整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          JavaWeb實(shí)現(xiàn)文件上傳與下載

          . 增強(qiáng)HttpServletResponse對象

          1. 實(shí)現(xiàn)一個(gè)增強(qiáng)的HttpServletResponse類,需要繼承javax.servlet.http.HttpServletRequestWrapper類,通過重寫自己需要增強(qiáng)的方法來實(shí)現(xiàn)(這種模式就叫做裝飾者模式),使用該增強(qiáng)類在加上過濾器就可以實(shí)現(xiàn)無編碼轉(zhuǎn)換處理代碼。

          public class MyRequest extends HttpServletRequestWrapper{
          	private HttpServletRequest req;
          	public MyRequest(HttpServletRequest request) {
          		super(request);
          		req=request;
          	}
          	@Override
          	public String getParameter(String name) {
          		//解決編碼問題,無論是post還是get請求,都不需要在業(yè)務(wù)代碼中對編碼再處理
          		String method=req.getMethod();
          		if("get".equalsIgnoreCase(method)){
          			try {
          				String str=req.getParameter(name);
          				byte[] b=str.getBytes("iso8859-1");
          				String newStr=new String(b, "utf-8");
          				return newStr;
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}else if("post".equalsIgnoreCase(method)){
          			try {
          				req.setCharacterEncoding("utf-8");
          			} catch (UnsupportedEncodingException e) {
          				// TODO Auto-generated catch block
          				e.printStackTrace();
          			}
          		}
          		//絕對不能刪除此行代碼,因?yàn)榇诵写a返回的就是編碼之后的數(shù)據(jù)
          		return super.getParameter(name);
          	}
          }
          

          在過濾器中應(yīng)用

          public class FilterTest4 implements Filter {
          	@Override
          	public void init(FilterConfig filterConfig) throws ServletException {}
          	@Override
          	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          			throws IOException, ServletException {
          		//生成增強(qiáng)的HttpServletRequest對象
          		HttpServletRequest req=(HttpServletRequest) request;
          		MyRequest myReq=new MyRequest(req);
          		//將增強(qiáng)的HttpServletRequest對象傳入過濾器執(zhí)行鏈中,在后面?zhèn)魅氲膔equest對象都會是增強(qiáng)的HttpServletRequest對象
          		chain.doFilter(myReq, response);
          		
          	}
          	@Override
          	public void destroy() {}
          }
          

          2. 文件上傳原理過程

          1. JavaWeb中實(shí)現(xiàn)文件上傳:

          • 客戶端:HTML頁面需要一個(gè)<form>表單,且必須設(shè)置表單的enctype屬性值為"multipart/form-data",以及method屬性值為"post"(因?yàn)間et方式不支持大量數(shù)據(jù)提交);表單里有一個(gè)<input type="file" name="">的標(biāo)簽,且name屬性值必須指定。
          <html>
           <head>
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <form action="" method="post" enctype="multipart/form-data">
           <input type="text" name="name">
           	請選擇文件:<input type="file" name="upload">
           	<input type="submit" value="上傳">
           </form>
           </body>
          </html>
          
          • 服務(wù)端:主要進(jìn)行IO讀寫操作。必須導(dǎo)入commons-fileupload和commons-io兩個(gè)jar包,可以通過請求request對象的getInputStream獲得一個(gè)流來讀取請求中的文件數(shù)據(jù),但是如果客戶端上傳多個(gè)文件時(shí),就會很麻煩,所以提供了commons-fileupload和commons-io兩個(gè)jar包來更方便的實(shí)現(xiàn)文件上傳。
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.util.List;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import org.apache.commons.fileupload.FileItem;
          import org.apache.commons.fileupload.FileUploadException;
          import org.apache.commons.fileupload.disk.DiskFileItemFactory;
          import org.apache.commons.fileupload.servlet.ServletFileUpload;
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		/**
          		 * 1. 創(chuàng)建磁盤文件項(xiàng)工廠類 DiskFileItemFactory
          		 * 2. 創(chuàng)建核心解析Request類 ServletFileUpload
          		 * 3. 開始解析Request對象中的數(shù)據(jù),并返回一個(gè)List集合
          		 * 4. List中包含表單中提交的內(nèi)容
          		 * 5. 遍歷集合,獲取內(nèi)容
          		 */
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems = upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				//有可能是普通文本項(xiàng),比如<input type="text">標(biāo)簽提交上來的字符串
          				//也有可能是<input type="submit" value="上傳">上傳的文件
          				//文件項(xiàng)與普通項(xiàng)有不同的API來處理
          				//首先判斷是普通文本項(xiàng)還是文件項(xiàng),
          				if(item.isFormField()){
          					//true表示普通文本項(xiàng)
          					//獲取文本項(xiàng)的name屬性值
          					String name=item.getFieldName();
          					//獲取對應(yīng)的文本
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					//false表示文件項(xiàng)
          					//先獲取文件名稱
          					String name=item.getName();
          					//獲取文件項(xiàng)的輸入流
          					InputStream in=item.getInputStream();
          					//獲取服務(wù)器端文件存儲的目標(biāo)磁盤路徑
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					//獲取輸出流,輸出到本地文件中
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					//寫入數(shù)據(jù)
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          

          注意:在文件上傳時(shí),會將form表單的屬性enctype屬性值為"multipart/form-data",當(dāng)提交到服務(wù)端后,無法使用 req.getParameter(name) 方法來獲取到內(nèi)容,只有通過上面的方法來獲取文本項(xiàng)。

          2. 文件上傳相關(guān)核心類:

          • DiskFileItemFactory:相關(guān)API如下
          • public DiskFileItemFactory():無參構(gòu)造器
          • public DiskFileItemFactory(int sizeThreshold, File repository):構(gòu)造器,sizeThreshold設(shè)置緩沖區(qū)大小,默認(rèn)10240 byte;repository表示如果過緩沖區(qū)空間小于上傳文件空間,那么會生成臨時(shí)文件,repository就是指定該臨時(shí)文件的保存路徑,如果過未上傳完成就中斷,繼續(xù)上傳時(shí)就可以通過這個(gè)臨時(shí)文件來繼續(xù)上傳。
          • public void setSizeThreshold(int sizeThreshold):設(shè)置緩沖區(qū)大小
          • public void setRepository(File repository):指定該臨時(shí)文件的保存路徑
          //改進(jìn)上面的文件上傳代碼,添加一個(gè)臨時(shí)文件
          public class UploadServlet extends HttpServlet{
          	@Override
          	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          		DiskFileItemFactory fac=new DiskFileItemFactory();
          		fac.setSizeThreshold(1024*1024);//設(shè)置緩沖區(qū)為1mb
          		//設(shè)置臨時(shí)文件的本地磁盤存儲路徑
          		File repository=new File(getServletContext().getRealPath("/temp"));
          		fac.setRepository(repository);
          		ServletFileUpload upload=new ServletFileUpload(fac);
          		upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼
          		try {
          			List<FileItem> fileItems = upload.parseRequest(req);
          			for(FileItem item:fileItems){
          				if(item.isFormField()){
          					String name=item.getFieldName();
          					String value=item.getString();
          					String value=item.getString("utf-8");//防止中文亂碼
          					System.out.println(name+":"+value);
          				}else{
          					String name=item.getName();
          					InputStream in=item.getInputStream();
          					String path=getServletContext().getRealPath("/upload");
          					System.out.println(path);
          					OutputStream out=new FileOutputStream(path+"/"+name);
          					int len=0;
          					byte[] b=new byte[1024];
          					while((len=in.read(b))!=-1){
          						out.write(b,0,len);
          					}
          					in.close();
          					out.close();
          					
          				}
          			}
          		} catch (FileUploadException e) {
          			// TODO Auto-generated catch block
          			e.printStackTrace();
          		}
          	}
          }
          
          • ServletFileUpload:相關(guān)API如下
          • public static final boolean isMultipartContent( HttpServletRequest request) :判斷表單提交上來的數(shù)據(jù)內(nèi)容是否是multipart類型的數(shù)據(jù),即 form表單的 enctype="multipart/form-data",是則返回true,否則返回false
          • public List /* FileItem */ parseRequest(HttpServletRequest request):解析request對象,返回一個(gè)泛型為FileItem 的List集合
          • public void setFileSizeMax(long fileSizeMax):設(shè)置單個(gè)文件的空間大小的最大值
          • public void setSizeMax(long sizeMax):設(shè)置所有文件空間大小之和的最大值
          • public void setHeaderEncoding(String encoding):解決上傳文件名的亂碼問題
          • public void setProgressListener(ProgressListener pListener):上傳時(shí)的進(jìn)度條。
          • FileItem:封裝表單中提交的數(shù)據(jù)
          • boolean isFormField():判斷當(dāng)前FileItem對象是表單中提交的文本數(shù)據(jù)項(xiàng),還是文件數(shù)據(jù)項(xiàng)
          • String getFieldName():獲取文本項(xiàng)類型FileItem對象的name屬性值,即相當(dāng)于表單中的 <input type="text" name="name">
          • String getString( String encoding ):獲取文本項(xiàng)類型FileItem對象的value值,可以指定編碼格式,也可以省略encoding不寫
          • String getName():應(yīng)用于文件項(xiàng)類型的FileItem對象,用于獲取文件的名稱,包括后綴名
          • InputStream getInputStream():獲取輸入流
          • void delete():刪除臨時(shí)緩存文件(在輸入以及輸出流關(guān)閉后執(zhí)行)

          3. 實(shí)現(xiàn)多文件上傳(需要js技術(shù)):主要是更改jsp頁面,通過js代碼來添加多個(gè)文件進(jìn)行上傳,服務(wù)器代碼無需更改

          <%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"%>
          <%
          String path = request.getContextPath();
          String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
          %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
           <head>
           <base href="<%=basePath%>">
           <title>My JSP 'upload.jsp' starting page</title>
          	<meta http-equiv="pragma" content="no-cache">
          	<meta http-equiv="cache-control" content="no-cache">
          	<meta http-equiv="expires" content="0"> 
          	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
          	<meta http-equiv="description" content="This is my page">
           </head>
           
           <body>
           <script type="text/javascript">
           	function run(){
           		var div=document.getElementById("divId");
           		 div.innerHTML+=
           		 "<div><input type='file' name='upload'><input type='button' value='刪除' onclick='del(this)'></div>"
           	}
           	function del(presentNode){
           		var div=document.getElementById("divId");
           		div.removeChild(presentNode.parentNode);
           	}
           </script>
           <div>
           	多文件上傳<br/>
           <form action="/Servlet/upload" method="post" enctype="multipart/form-data">
           	<input type="button" value="添加" onclick="run()"><br/>
           	<div id="divId">
           	
           	</div>
           	
           	<input type="submit" value="上傳">
           </form>
           </div>
           </body>
          </html>
          

          4. 關(guān)于文件上傳的一些問題:

          • 文件重名可能會產(chǎn)生覆蓋效果,可以在處理文件名時(shí)生成一個(gè)唯一的文件名
          • 如果所有的文件都儲存在一個(gè)文件夾中,會導(dǎo)致文件夾下文件過多,可以一個(gè)用戶一個(gè)文件夾,或者利用算法目錄分離等方法。

          3. 文件下載

          1. 傳統(tǒng)文件下載方式有超鏈接下載或者后臺程序下載兩種方式。通過超鏈接下載時(shí),如果瀏覽器可以解析,那么就會直接打開,如果不能解析,就會彈出下載框;而后臺程序下載就必須通過兩個(gè)響應(yīng)頭和一個(gè)文件的輸入流。

          2. 后臺程序下載:

          • 兩個(gè)響應(yīng)頭:
          • Content-Type:其值有比如 text/html;charset=utf-8
          • Content-Disposition:其值為 attachment;filename=文件名 以附件形式打開
          • 流:需要獲取文件的輸入流,然后通過response對象的輸出流輸出到客戶端。

          JSP指令用來設(shè)置整個(gè)JSP頁面相關(guān)的屬性,如網(wǎng)頁的編碼方式和腳本語言。

          語法格式如下:

          <%@ directive attribute="value" %>

          指令可以有很多個(gè)屬性,它們以鍵值對的形式存在,并用逗號隔開。

          JSP中的三種指令標(biāo)簽:

          指令描述
          <%@ page ... %>定義網(wǎng)頁依賴屬性,比如腳本語言、error頁面、緩存需求等等
          <%@ include ... %>包含其他文件
          <%@ taglib ... %>引入標(biāo)簽庫的定義

          Page指令

          Page指令為容器提供當(dāng)前頁面的使用說明。一個(gè)JSP頁面可以包含多個(gè)page指令。

          Page指令的語法格式:

          <%@ page attribute="value" %>

          等價(jià)的XML格式:

          <jsp:directive.page attribute="value" />

          屬性

          下表列出與Page指令相關(guān)的屬性:

          屬性描述
          buffer指定out對象使用緩沖區(qū)的大小
          autoFlush控制out對象的 緩存區(qū)
          contentType指定當(dāng)前JSP頁面的MIME類型和字符編碼
          errorPage指定當(dāng)JSP頁面發(fā)生異常時(shí)需要轉(zhuǎn)向的錯(cuò)誤處理頁面
          isErrorPage指定當(dāng)前頁面是否可以作為另一個(gè)JSP頁面的錯(cuò)誤處理頁面
          extends指定servlet從哪一個(gè)類繼承
          import導(dǎo)入要使用的Java類
          info定義JSP頁面的描述信息
          isThreadSafe指定對JSP頁面的訪問是否為線程安全
          language定義JSP頁面所用的腳本語言,默認(rèn)是Java
          session指定JSP頁面是否使用session
          isELIgnored指定是否執(zhí)行EL表達(dá)式
          isScriptingEnabled確定腳本元素能否被使用

          Include指令

          JSP可以通過include指令來包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是該JSP文件的一部分,會被同時(shí)編譯執(zhí)行。

          Include指令的語法格式如下:

          <%@ include file="文件相對 url 地址" %>

          include 指令中的文件名實(shí)際上是一個(gè)相對的 URL 地址。

          如果您沒有給文件關(guān)聯(lián)一個(gè)路徑,JSP編譯器默認(rèn)在當(dāng)前路徑下尋找。

          等價(jià)的XML語法:

          <jsp:directive.include file="文件相對 url 地址" />

          Taglib指令

          JSP API允許用戶自定義標(biāo)簽,一個(gè)自定義標(biāo)簽庫就是自定義標(biāo)簽的集合。

          Taglib指令引入一個(gè)自定義標(biāo)簽集合的定義,包括庫路徑、自定義標(biāo)簽。

          Taglib指令的語法:

          <%@ taglib uri="uri" prefix="prefixOfTag" %>

          uri屬性確定標(biāo)簽庫的位置,prefix屬性指定標(biāo)簽庫的前綴。

          等價(jià)的XML語法:

          <jsp:directive.taglib uri="uri" prefix="prefixOfTag" />

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!

          言:在CGI(通用網(wǎng)關(guān)接口)編程風(fēng)行的日子,人們紛紛尋思簡化并讓其更加靈活的新方法和新技術(shù),包括PHP、JSP、ASP。1997年SUN公司推出了servlet,1999年初,SUN公司推出了JSP,實(shí)際上在servlet基礎(chǔ)上修改而成。JSP即Java服務(wù)器頁面(Java Server Page),將HTML和JAVA代碼使用某種方式結(jié)合起來,完成前后端的有效交互。本文通過JSP歷史回顧和應(yīng)用總結(jié)來審視過去和開拓未來。

          1.從實(shí)例項(xiàng)目入手

          其實(shí),從現(xiàn)在看來JSP依然極具魅力,據(jù)了解很多JSP老項(xiàng)目還在維護(hù)。下面使用STS作為IDE構(gòu)建一個(gè)實(shí)例項(xiàng)目,先體驗(yàn)其效果。

          1.1 動態(tài)web項(xiàng)目模板

          如下圖,使用new dynamic web project創(chuàng)建項(xiàng)目:

          1.2修改文件編碼

          進(jìn)入preferences修改JSP文件的編碼:

          1.3 編寫簡單的JSP文件

          新增一個(gè)JSP文件到WebContent目錄,如下

          然后檢查并修改編碼,應(yīng)該都是UTF-8,如下圖:

          如果不是,就修改。

          1.4運(yùn)行和測試

          選中項(xiàng)目名稱,點(diǎn)郵件菜單的Run as ...-->Run on server

          之后出現(xiàn)如下界面:

          若沒有現(xiàn)存的tomcat server,就自己加一個(gè)。點(diǎn)Finish。然后自動調(diào)用chrome,界面如下:

          自動調(diào)用瀏覽器設(shè)置的地方是windows-->Web browser菜單:

          1.5增加功能:顯示IP地址

          (1)顯示ip地址:getRemoteAddr

          (2)變量聲明<%! %>

          (3)表達(dá)式<%=%>

          2.JSP語言介紹

          2.1語法

          語法

          描述

          <%-- 注釋 --%>

          JSP注釋,注釋內(nèi)容不會被發(fā)送至瀏覽器甚至不會被編譯

          <!-- 注釋 -->

          HTML注釋,通過瀏覽器查看網(wǎng)頁源代碼時(shí)可以看見注釋內(nèi)容

          <\%

          代表靜態(tài) <%常量

          %\>

          代表靜態(tài) %> 常量

          \'

          在屬性中使用的單引號

          \"

          在屬性中使用的雙引號

          2.2指令

          指令

          描述

          <%@ page ... %>

          定義頁面的依賴屬性,比如腳本語言、error頁面、緩存需求等等

          <%@ include ... %>

          包含其他文件

          <%@ taglib ... %>

          引入標(biāo)簽庫的定義,可以是自定義標(biāo)簽

          2.3Page指令屬性

          屬性

          描述

          buffer

          指定out對象使用緩沖區(qū)的大小

          autoFlush

          控制out對象的 緩存區(qū)

          contentType

          指定當(dāng)前JSP頁面的MIME類型和字符編碼

          errorPage

          指定當(dāng)JSP頁面發(fā)生異常時(shí)需要轉(zhuǎn)向的錯(cuò)誤處理頁面

          isErrorPage

          指定當(dāng)前頁面是否可以作為另一個(gè)JSP頁面的錯(cuò)誤處理頁面

          extends

          指定servlet從哪一個(gè)類繼承

          import

          導(dǎo)入要使用的Java類

          info

          定義JSP頁面的描述信息

          isThreadSafe

          指定對JSP頁面的訪問是否為線程安全

          language

          定義JSP頁面所用的腳本語言,默認(rèn)是Java

          session

          指定JSP頁面是否使用session

          isELIgnored

          指定是否執(zhí)行EL表達(dá)式

          isScriptingEnabled

          確定腳本元素能否被使用

          2.4行為標(biāo)簽

          行為標(biāo)簽語法:<jsp:行為名稱 attribute="value" />

          語法

          描述

          jsp:include

          用于在當(dāng)前頁面中包含靜態(tài)或動態(tài)資源

          jsp:useBean

          尋找和初始化一個(gè)JavaBean組件

          jsp:setProperty

          設(shè)置 JavaBean組件的值

          jsp:getProperty

          將 JavaBean組件的值插入到 output中

          jsp:forward

          從一個(gè)JSP文件向另一個(gè)文件傳遞一個(gè)包含用戶請求的request對象

          jsp:plugin

          用于在生成的HTML頁面中包含Applet和JavaBean對象

          jsp:element

          動態(tài)創(chuàng)建一個(gè)XML元素

          jsp:attribute

          定義動態(tài)創(chuàng)建的XML元素的屬性

          jsp:body

          定義動態(tài)創(chuàng)建的XML元素的主體

          jsp:text

          用于封裝模板數(shù)據(jù)

          使用bean是最好用的行為標(biāo)簽,例如,我們創(chuàng)建一個(gè)java類:

          然后,在JSP中使用useBea/setProperty/getProperty三個(gè)行為標(biāo)簽:

          測試:

          2.5隱含對象(默認(rèn)創(chuàng)建的對象)

          對象

          描述

          request

          HttpServletRequest類的實(shí)例

          response

          HttpServletResponse類的實(shí)例

          out

          PrintWriter類的實(shí)例,用于把結(jié)果輸出至網(wǎng)頁上

          session

          HttpSession類的實(shí)例

          application

          ServletContext類的實(shí)例,與應(yīng)用上下文有關(guān)

          config

          ServletConfig類的實(shí)例

          pageContext

          PageContext類的實(shí)例,提供對JSP頁面所有對象以及命名空間的訪問

          page

          類似于Java類中的this關(guān)鍵字

          Exception

          Exception類的對象,代表發(fā)生錯(cuò)誤的JSP頁面中對應(yīng)的異常對象

          2.6判斷語句

          判斷語句包括兩種:if else和switch case

          示例如下:

          2.7循環(huán)語句

          循環(huán)語句包括兩種:for和while

          示例如下:

          2.8運(yùn)算符

          類別

          操作符

          結(jié)合性

          后綴

          () [] . (點(diǎn)運(yùn)算符)

          左到右

          一元

          ++ - - ! ~

          右到左

          可乘性

          * / %

          左到右

          可加性

          + -

          左到右

          移位

          >> >>> <<

          左到右

          關(guān)系

          > >= < <=

          左到右

          相等/不等

          == !=

          左到右

          位與

          &

          左到右

          位異或

          ^

          左到右

          位或

          |

          左到右

          邏輯與

          &&

          左到右

          邏輯或

          ||

          左到右

          條件判斷

          ?:

          右到左

          賦值

          = += -= *= /= %= >>= <<= &= ^= |=

          右到左

          逗號

          ,

          左到右

          2.9變量類型

          布爾值(boolean):true 和 false;

          整型(int):與 Java 中的一樣;

          浮點(diǎn)型(float):與 Java 中的一樣;

          字符串(string):以單引號或雙引號開始和結(jié)束;

          Null:null。

          2.10表單處理

          以下提供一個(gè)例子來說明:

          (1)創(chuàng)建FormProcess.jsp文件:

          其中提供了兩個(gè)input輸入框。

          (2)再創(chuàng)建FormProcessMain.jsp文件,如下:

          其中使用request對象的getParameter方法來獲取Get參數(shù)。

          2.11過濾器

          JSP過濾器實(shí)際上和Servlet過濾器一樣。

          以下通過示例來說明:

          (1)在web.xml中增加一個(gè)過濾器:

          (2)然后創(chuàng)建過濾器處理類com.hunting.LogFilter,如下:

          2.12JSTL(JSP標(biāo)準(zhǔn)標(biāo)簽庫)

          (1)核心標(biāo)簽:

          標(biāo)簽

          描述

          <c:out>

          用于在JSP中顯示數(shù)據(jù),就像<%= ... >

          <c:set>

          用于保存數(shù)據(jù)

          <c:remove>

          用于刪除數(shù)據(jù)

          <c:catch>

          用來處理產(chǎn)生錯(cuò)誤的異常狀況,并且將錯(cuò)誤信息儲存起來

          <c:if>

          與我們在一般程序中用的if一樣

          <c:choose>

          本身只當(dāng)做<c:when>和<c:otherwise>的父標(biāo)簽

          <c:when>

          <c:choose>的子標(biāo)簽,用來判斷條件是否成立

          <c:otherwise>

          <c:choose>的子標(biāo)簽,接在<c:when>標(biāo)簽后,當(dāng)<c:when>標(biāo)簽判斷為false時(shí)被執(zhí)行

          <c:import>

          檢索一個(gè)絕對或相對 URL,然后將其內(nèi)容暴露給頁面

          <c:forEach>

          基礎(chǔ)迭代標(biāo)簽,接受多種集合類型

          <c:forTokens>

          根據(jù)指定的分隔符來分隔內(nèi)容并迭代輸出

          <c:param>

          用來給包含或重定向的頁面?zhèn)鬟f參數(shù)

          <c:redirect>

          重定向至一個(gè)新的URL.

          <c:url>

          使用可選的查詢參數(shù)來創(chuàng)造一個(gè)URL

          (2)格式化標(biāo)簽:

          標(biāo)簽

          描述

          <fmt:formatNumber>

          使用指定的格式或精度格式化數(shù)字

          <fmt:parseNumber>

          解析一個(gè)代表著數(shù)字,貨幣或百分比的字符串

          <fmt:formatDate>

          使用指定的風(fēng)格或模式格式化日期和時(shí)間

          <fmt:parseDate>

          解析一個(gè)代表著日期或時(shí)間的字符串

          <fmt:bundle>

          綁定資源

          <fmt:setLocale>

          指定地區(qū)

          <fmt:setBundle>

          綁定資源

          <fmt:timeZone>

          指定時(shí)區(qū)

          <fmt:setTimeZone>

          指定時(shí)區(qū)

          <fmt:message>

          顯示資源配置文件信息

          <fmt:requestEncoding>

          設(shè)置request的字符編碼

          (3)SQL標(biāo)簽:

          標(biāo)簽

          描述

          <sql:setDataSource>

          指定數(shù)據(jù)源

          <sql:query>

          運(yùn)行SQL查詢語句

          <sql:update>

          運(yùn)行SQL更新語句

          <sql:param>

          將SQL語句中的參數(shù)設(shè)為指定值

          <sql:dateParam>

          將SQL語句中的日期參數(shù)設(shè)為指定的java.util.Date 對象值

          <sql:transaction>

          在共享數(shù)據(jù)庫連接中提供嵌套的數(shù)據(jù)庫行為元素,將所有語句以一個(gè)事務(wù)的形式來運(yùn)行

          (4)XML標(biāo)簽:

          標(biāo)簽

          描述

          <x:out>

          與<%= ... >,類似,不過只用于XPath表達(dá)式

          <x:parse>

          解析 XML 數(shù)據(jù)

          <x:set>

          設(shè)置XPath表達(dá)式

          <x:if>

          判斷XPath表達(dá)式,若為真,則執(zhí)行本體中的內(nèi)容,否則跳過本體

          <x:forEach>

          迭代XML文檔中的節(jié)點(diǎn)

          <x:choose>

          <x:when>和<x:otherwise>的父標(biāo)簽

          <x:when>

          <x:choose>的子標(biāo)簽,用來進(jìn)行條件判斷

          <x:otherwise>

          <x:choose>的子標(biāo)簽,當(dāng)<x:when>判斷為false時(shí)被執(zhí)行

          <x:transform>

          將XSL轉(zhuǎn)換應(yīng)用在XML文檔中

          <x:param>

          與<x:transform>共同使用,用于設(shè)置XSL樣式表

          3.JSP歷史

          下面從前后端分離角度展現(xiàn)JSP的產(chǎn)生和發(fā)展脈絡(luò)。

          3.1互聯(lián)網(wǎng)的產(chǎn)生

          1957年美國國防部(DoD)組建了高級研究計(jì)劃局(ARPA)。1961年7月,MIT工程師Leonard Kleinrock發(fā)表Information Flow in Large Communication Nets論文。1962年8月, MIT工程師J.C.R. Licklider和W. Clark發(fā)表On-Line Man Computer Communication論文。1967 2月,在ARPA IPTO PI會議上,Larry Roberts組織了有關(guān)ARPANET設(shè)計(jì)方案的討論?;ヂ?lián)網(wǎng)雛形ARPANET由此產(chǎn)生。

          互聯(lián)網(wǎng)最初的目的是訪問和復(fù)制文件從一臺計(jì)算機(jī)到另一臺遠(yuǎn)程計(jì)算機(jī),兩臺計(jì)算機(jī)之間有網(wǎng)絡(luò),但速度慢,而且經(jīng)常專用于大學(xué)或者研究機(jī)構(gòu)是昂貴的,不支持大規(guī)模用戶。1970年,ARPANET主機(jī)開始使用網(wǎng)絡(luò)控制協(xié)議(NCP),這就是后來的傳輸控制協(xié)議(TCP)的雛形。

          人們基于TCP/IP構(gòu)建了更快的網(wǎng)絡(luò),其中應(yīng)用層文件傳輸協(xié)議(FTP)規(guī)范提供了交換這些文件的標(biāo)準(zhǔn)方法。1973年,文件傳輸協(xié)議(FTP)推出,用于在異構(gòu)系統(tǒng)之間交換文件。FTP傳輸?shù)奈募⒉荒苡行Р榭矗虼税l(fā)明了超文本標(biāo)記語言(HTML),使我們能夠在互聯(lián)網(wǎng)上看到文檔。

          3.2萬維網(wǎng)的產(chǎn)生

          1989年蒂姆伯納斯-李寫了一份關(guān)于建立一個(gè)通過網(wǎng)絡(luò)傳輸超文本系統(tǒng)的報(bào)告,其中創(chuàng)建了單行 HTTP 協(xié)議,這個(gè)協(xié)議在1991年被命名為HTTP/0.9,萬維網(wǎng)由此產(chǎn)生,1996年超文本傳送協(xié)議HTTP 1.0發(fā)布。

          盡管FTP可以傳輸HTML文件,但是并沒有提供有效小文件傳輸機(jī)制和無狀態(tài)管理能力,超文本傳輸協(xié)議(HTTP)才被發(fā)明出來專門用于傳輸HTML文檔,HTTP是一種無連接/無狀態(tài)協(xié)議,這使得許多短連接更加有效,而且可以不使用密碼就可以獲取HTML文檔,這讓萬維網(wǎng)真正到來,真正體現(xiàn)了互聯(lián)網(wǎng)的快捷、免費(fèi)思維。

          3.3通用網(wǎng)關(guān)接口的產(chǎn)生

          上面提到了TCP/IP,HTTP,F(xiàn)TP都是通信管道,后來大家把注意力轉(zhuǎn)向內(nèi)容。我們感興趣的文件隨著IT技術(shù)的發(fā)展而快速爆發(fā),例如數(shù)據(jù)庫快速發(fā)展導(dǎo)致各種應(yīng)用系統(tǒng)快速發(fā)展。同時(shí),數(shù)據(jù)的更新頻度更加快速,這種即時(shí)信息推動了互聯(lián)網(wǎng)流量快速增長。通過基于HTTP的HTML,最終用戶可以瀏覽位于遠(yuǎn)程服務(wù)器上的文件。

          當(dāng)時(shí),遠(yuǎn)程服務(wù)器屬于局域網(wǎng),局域網(wǎng)連接到互聯(lián)網(wǎng)需要專用設(shè)備,可惜的是這種專用設(shè)備并不好用(直到后來路由器和交換機(jī)被思科發(fā)明出來),因此通用網(wǎng)關(guān)接口(CGI)規(guī)范被制定出來,它允許Web服務(wù)器超越文件服務(wù)器并從內(nèi)部數(shù)據(jù)庫中獲取數(shù)據(jù),并動態(tài)更改HTML。

          最初,CGI是在1993年由美國國家超級電腦應(yīng)用中心(NCSA)為NCSA HTTPd Web服務(wù)器開發(fā)的,當(dāng)年NCSA內(nèi)部有一份簡單的CGI規(guī)范說明,后來在1997年Ken Coar領(lǐng)導(dǎo)的團(tuán)隊(duì)制定了CGI1.1規(guī)范,并提交RFC。CGI規(guī)范是Web應(yīng)用程序開發(fā)中的一個(gè)重大突破,確保了相同的CGI程序在不同的Web服務(wù)器上工作。

          CGI成為傳遞動態(tài)內(nèi)容的最常用手段。只是互聯(lián)網(wǎng)發(fā)展太快了,CGI的性能無法跟上,每個(gè)對CGI腳本的請求都會產(chǎn)生一個(gè)單獨(dú)的進(jìn)程。這種設(shè)計(jì)讓CGI在高峰負(fù)載時(shí)也消耗大量資源。解決方案非常多,功能性和可伸縮性成為關(guān)鍵。

          許多CGI替代者都采用服務(wù)器端編程技術(shù)來實(shí)現(xiàn)業(yè)務(wù)邏輯,包括ASP、ColdFusion、PHP和Perl等等,其中至今仍然在大量使用的是PHP ,PHP 繼承自一個(gè)老的工程,名叫 PHP/FI,PHP/FI 在 1995 年由 Rasmus Lerdorf 創(chuàng)建,最初只是一套簡單的 Perl 腳本,用來跟蹤訪問他主頁的人。然后,即使是PHP,最終由于可移植性和面向?qū)ο蟮木幊淘O(shè)計(jì),Java超越了PHP和其他CGI平臺。

          3.4 JSP的產(chǎn)生

          Java自1991年誕生以來已經(jīng)走過了很長的一段路,當(dāng)時(shí)Sun公司推出了“綠色計(jì)劃”,試圖集成數(shù)字消費(fèi)設(shè)備,如電視機(jī)、CD播放機(jī)和計(jì)算機(jī)。OAK(名字來自高斯林窗外的一棵橡樹!)誕生了,但直到出現(xiàn)HotJava和小程序,才開始活躍起來。1995年,Sun發(fā)布了開源Java,向微軟發(fā)起了挑戰(zhàn),反響巨大。這促使Java深入到服務(wù)器端開發(fā)領(lǐng)域。

          Sun在Java中加入了Internet功能,并在1997年6月發(fā)布了servlet接口。servlet以CGI替代為目標(biāo)。與CGI為每個(gè)請求啟動一個(gè)進(jìn)程不同,servlet使用更細(xì)粒度的線程在單個(gè)進(jìn)程中運(yùn)行。servlet采用了更有效的體系架構(gòu),能夠應(yīng)對互聯(lián)網(wǎng)上的復(fù)雜情況。Java servlet為開發(fā)Java Web組件提供了基礎(chǔ)。servlet優(yōu)點(diǎn)是每個(gè)額外的并發(fā)請求帶來的額外開銷非常小。

          servlet技術(shù)需要真正的Java編程技能才能有效應(yīng)用,外觀和良好體驗(yàn)為web應(yīng)用帶來了巨大方便,但是圖像支持還不是那么良好。于是Sun公司在1998年發(fā)布了JavaServer Pages (JSP),這來自于微軟ASP的啟發(fā),也有些人說是復(fù)制的,它使得編寫動態(tài)HTML頁面變得容易。

          使用JSP的使用非常簡單,有些工具(例如Dreamweaver)能讓非程序員來構(gòu)建WWW網(wǎng)站前端頁面,當(dāng)然要servlet帶動后端服務(wù)器代碼(例如javabean)才能完成完整的WWW網(wǎng)站構(gòu)建工作,這樣構(gòu)建的WWW網(wǎng)站具有模塊化、可維護(hù)、可伸縮和可移植優(yōu)點(diǎn),從而完成簡單網(wǎng)站到復(fù)雜Web應(yīng)用程序的轉(zhuǎn)變,從而實(shí)現(xiàn)前后端分離。

          JSP官方版本1.0和1.1都出現(xiàn)在1999年,都很受歡迎,版本1.2出現(xiàn)于2001年,是目前最流行的實(shí)現(xiàn)。

          3.5 Node的產(chǎn)生

          JSP終究還是含有Java代碼,前后端沒有徹底分離,因此人們在2009年發(fā)明了node-js,這讓前端開發(fā)人員崛起,他們單純使用HTML+CSS+JavaScript前端語言就能完成前端頁面的開發(fā),而不需要使用含有各種后端交互印記的標(biāo)簽。

          于是,基于node-js的React、Angela、VUE框架成為潮流。


          主站蜘蛛池模板: av一区二区三区人妻少妇| 久久4k岛国高清一区二区| 久久精品免费一区二区喷潮| 国产一区二区精品在线观看| 国产精品一区二区四区| 日韩一区二区在线视频| 高清一区二区三区免费视频| 亚洲欧美国产国产一区二区三区 | 国产在线精品一区二区三区不卡| 久久精品成人一区二区三区| 精品国产亚洲一区二区三区在线观看| 日韩一区二区视频| 精品一区二区三区3d动漫| 国产suv精品一区二区33| 亚洲午夜精品一区二区麻豆| 国产一区二区三区在线观看影院| 人妻体内射精一区二区| 亚洲Av永久无码精品一区二区| 国产伦精品一区二区三区视频小说 | 久久久久人妻精品一区三寸| 久久无码人妻精品一区二区三区 | 国产伦精品一区二区三区免.费 | 在线视频一区二区三区三区不卡| 久久国产视频一区| www.亚洲一区| 国产精品成人国产乱一区| 中文字幕av日韩精品一区二区| 精品一区二区AV天堂| 国产精品揄拍一区二区久久| 国产精品日本一区二区不卡视频 | 无码人妻精品一区二区在线视频| 无码中文字幕乱码一区| 无码精品人妻一区二区三区漫画| 亚洲一区二区免费视频| 日本一区二区不卡在线| 亚洲成在人天堂一区二区| 色狠狠一区二区三区香蕉蜜桃| 一区二区三区免费视频观看| 国产在线一区观看| 一区二区三区在线免费| 中文字幕一区二区三区有限公司|