sp中四種傳遞參數的方法,我覺得總結一下,挺好的,以備后用!
1、form表單
2、request.setAttribute();和request.getAttribute();
3、超鏈接:<a herf="index.jsp"?a=a&b=b&c=c>name</a>
1、form表單
form.jsp:
<%@page contentType="text/html; charset=GB2312"%> <html> <head> <title> form.jsp file </title> </head> <body style="background-color:lightblue"> <h2 style="font-family:arial;color:red;font-size:25px;text-align:center">登錄頁面</h2> <form action="result.jsp" method="get" align="center"> 姓名:<input type="text" name="name" size="20" value="" maxlength="20"><br/> 密碼:<input type="password" name="password" size="20" value="" maxlength="20"><br/> <!--在愛好前空一個空格,是為了排版好看些--> 愛好:<input type="checkbox" name="hobby" value="唱歌">唱歌 <input type="checkbox" name="hobby" value="足球">足球 <input type="checkbox" name="hobby" value="籃球">籃球<br/><br/> <input type="submit" name="submit" value="登錄"> <input type="reset" name="reset" value="重置"><br/> </form> </body> </html>
result.jsp:
1 <%@page language="java" import="java.util.*" pageEncoding="GB2312"%> 2 <html> 3 <head> 4 <title> 5 result.jsp file 6 </title> 7 </head> 8 9 <body bgcolor="ffffff"> 10 <% 11 request.setCharacterEncoding("GB2312"); 12 13 String name=request.getParameter("name"); 14 name=new String(name.getBytes("iso-8859-1"),"GB2312"); 15 16 String pwd=request.getParameter("password"); 17 String[] hobby=request.getParameterValues("hobby");//注意這里的函數是getParameterValues()接受一個數組的數據 18 19 %> 20 21 <% 22 if(!name.equals("") && !pwd.equals("")) 23 { 24 %> 25 26 您好!登錄成功!<br/> 27 姓名:<%=name%><br/> 28 密碼:<%=pwd%><br/> 29 愛好:<% 30 for(String ho: hobby) 31 { 32 ho=new String(ho.getBytes("iso-8859-1"),"GB2312"); 33 out.print(ho+" "); 34 } 35 %> 36 <% 37 } 38 else 39 { 40 %> 41 請輸入姓名或密碼! 42 <% 43 } 44 %> 45 </body> 46 </html>
注意:form表單的提交方式為get,在參數傳遞時會遇到中文亂碼的問題,一個簡單的解決方法是,將接受到的字符串先轉換成一個byte數組,再用String構造一個新的編碼格式的String,如:
1 String name=request.getParameter("name"); 2 name=new String(name.getBytes("iso-8859-1"),"GB2312");
如果form表單的提交方式為post,解決亂碼問題的簡單辦法是,使用 request.setCharacterEncoding("GB2312");設置request的編碼方式。
為什么會出現中文亂碼問題呢?因為Tomcat服務器默認的系統編碼方式為iso- 8859-1,你傳遞參數給服務器時,使用的是默認的iso-8859-1的編碼方式,但是服務器向你返回信息時,是按page指令中設置的編碼方式, 如:<%@page language="java" import="java.util.*" pageEncoding="GB2312"%>,這樣就混合了兩種編碼方式,所以會出現亂碼,所以解決之道就是統一傳遞和接收的編碼方式。
2、request.setAttribute()和request.getAttribute()
set.jsp:
<%@page contentType="text/html; charset=GB2312"%> <html> <head> <title> set.jsp file </title> </head> <body style="background-color:lightblue"> <% request.setAttribute("name","心雨"); %> <jsp:forward page="get.jsp"/> </body> </html>
get.jsp:
<%@page contentType="text/html; charset=GB2312"%> <html> <head> <title> get.jsp file </title> </head> <body style="background-color:lightblue"> <% out.println("傳遞過來的參數是:"+request.getAttribute("name")); %> </body> </html>
request.setAttribute()和request.getAttribute()是配合<jsp:forward>或是include指令來實現的。
3、超鏈接:<a herf="index.jsp?a=a&b=b&c=c">name</a>
href.jsp:
<%@page contentType="text/html; charset=GB2312"%> <html> <head> <title> href.jsp file </title> </head> <body style="background-color:lightblue"> <a href="getHerf.jsp?name=心雨&password=123">傳遞參數</a> </body> </html>
getHref.jsp:
<%@page contentType="text/html; charset=GB2312"%> <html> <head> <title> getHref.jsp file </title> </head> <body style="background-color:lightblue"> <% String name=request.getParameter("name"); name=new String(name.getBytes("iso-8859-1"),"gb2312"); out.print("name:"+name); %> <br/> <% out.print("password:"+request.getParameter("password")); %> </body> </html>
這種傳遞參數的方法和form表單的get方式類似,是通過地址欄傳遞的參數,其亂碼解決方法也和form 的get方式一樣。
4、<jsp:param>
param.jsp:
<%@page contentType="text/html; charset=GB2312"%> <html> <head> <title> param.jsp file </title> </head> <body style="background-color:lightblue"> <%request.setCharacterEncoding("GB2312");%> <jsp:forward page="getParam.jsp"> <jsp:param name="name" value="心雨"/> <jsp:param name="password" value="123"/> </jsp:forward> </body> </html>
getParam.jsp:
<%@page contentType="text/html; charset=GB2312"%> <html> <head> <title> getParam.jsp file </title> </head> <body style="background-color:lightblue"> <% String name=request.getParameter("name"); out.print("name:"+name); %> <br/> <% out.print("password:"+request.getParameter("password")); %> </body> </html>
這里發現了一個奇怪的問題,還是在中文亂碼的問題上,在form表單的例子中,如果傳遞方式為post,則只需要在接收參數的頁面設置request的編 碼方式就可以了,即request.setCharacterEncoding("GB2312");,注意是在接收參數的頁面,如果將該句放到form 表單里,那么不起作用,仍然是亂碼。而在本例中,為了使傳遞的參數不出現亂碼,卻是將 request.setCharacterEncoding("GB2312");放在發送參數的頁面中,才會正常顯示中文,放在接收參數的頁面中,不起 作用。也許這就是<jsp:param>和form表單傳遞參數不同的地方。為什么會有這個不同呢?可能是因為form表單中的參數是由客戶 端傳送到服務端上的,需要經過一個request的打包過程,但是<jsp:param>傳遞的參數本身就是在服務器端的,不需要經歷由客戶 端到服務端這么一個過程,但是服務器里的參數傳遞是這么回事呢?這個問題,我不知道了!真是知識是一個擴大的圓圈,你知道的越多,那么不知道的就越多!努 力吧!
SP的工作模式是請求/響應模式,客戶端首先發出HTTP請求,JSP程序收到請求后將進行處理并返回處理結果。在一個JSP文件第一次被請求的時候,JSP引擎(容器)把該JSP文件轉換成一個Servlet,而這個引擎本身也是一個Servlet。JSP的運行原理如圖11-4所示。
圖11-4 JSP的運行原理
JSP的運行過程具體如下。
(1)客戶端發出請求,請求訪問JSP文件。
(2)JSP容器先將JSP文件轉換成一個Java源文件(Java Servlet源程序),在轉換過程中,如果發現JSP文件中存在任何語法錯誤,則中斷轉換過程,并向服務端和客戶端返回出錯信息。
(3)如果轉換成功,則JSP容器會將生成的Java源文件編譯成相應的字節碼文件*.class。該class文件就是一個Servlet,Servlet容器會像處理其他Servlet一樣處理它。
(4)由Servlet容器加載轉換后的Servlet類(class文件)創建一個該Servlet(JSP頁面的轉換結果)的實例,并執行Servlet的jspInit()方法。jsInit()方法在Servlet的整個生命周期中只會執行一次。
(5)執行jspService()方法處理客戶端的請求。對于每一個請求,JSP容器都會創建一個新的線程處理它。如果多個客戶端同時請求該JSP文件,則JSP容器會創建多個線程,使每一個客戶端請求都對應一個線程。
(6)如果JSP文件被修改了,則服務器將根據設置決定是否對該文件重新進行編譯,如果需要重新編譯,則使用重新編譯后的結果取代內存中的Servlet,并繼續上述處理過程。需要注意的是,雖然JSP效率很高,但在第一次調用時往往由于需要轉換和編譯,所以會產生一些輕微的延遲。
(7)如果系統出現資源不足等問題,JSP容器可能會以某種不確定的方式將Servlet從內存中移除,發生這種情況的時候,首先會調用jspDestroy()方法,然后Servlet實例會被作為“垃圾”進行處理。
(8)當請求處理完成后,響應對象由JSP容器接收,并將HTML格式的響應信息發送回客戶端。
. 增強HttpServletResponse對象
1. 實現一個增強的HttpServletResponse類,需要繼承javax.servlet.http.HttpServletRequestWrapper類,通過重寫自己需要增強的方法來實現(這種模式就叫做裝飾者模式),使用該增強類在加上過濾器就可以實現無編碼轉換處理代碼。
public class MyRequest extends HttpServletRequestWrapper{ private HttpServletRequest req; public MyRequest(HttpServletRequest request) { super(request); req=request; } @Override public String getParameter(String name) { //解決編碼問題,無論是post還是get請求,都不需要在業務代碼中對編碼再處理 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(); } } //絕對不能刪除此行代碼,因為此行代碼返回的就是編碼之后的數據 return super.getParameter(name); } }
在過濾器中應用
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 { //生成增強的HttpServletRequest對象 HttpServletRequest req=(HttpServletRequest) request; MyRequest myReq=new MyRequest(req); //將增強的HttpServletRequest對象傳入過濾器執行鏈中,在后面傳入的request對象都會是增強的HttpServletRequest對象 chain.doFilter(myReq, response); } @Override public void destroy() {} }
2. 文件上傳原理過程
1. JavaWeb中實現文件上傳:
<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>
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. 創建磁盤文件項工廠類 DiskFileItemFactory * 2. 創建核心解析Request類 ServletFileUpload * 3. 開始解析Request對象中的數據,并返回一個List集合 * 4. List中包含表單中提交的內容 * 5. 遍歷集合,獲取內容 */ DiskFileItemFactory fac=new DiskFileItemFactory(); ServletFileUpload upload=new ServletFileUpload(fac); upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼 try { List<FileItem> fileItems = upload.parseRequest(req); for(FileItem item:fileItems){ //有可能是普通文本項,比如<input type="text">標簽提交上來的字符串 //也有可能是<input type="submit" value="上傳">上傳的文件 //文件項與普通項有不同的API來處理 //首先判斷是普通文本項還是文件項, if(item.isFormField()){ //true表示普通文本項 //獲取文本項的name屬性值 String name=item.getFieldName(); //獲取對應的文本 String value=item.getString("utf-8");//防止中文亂碼 System.out.println(name+":"+value); }else{ //false表示文件項 //先獲取文件名稱 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(); } } }
注意:在文件上傳時,會將form表單的屬性enctype屬性值為"multipart/form-data",當提交到服務端后,無法使用 req.getParameter(name) 方法來獲取到內容,只有通過上面的方法來獲取文本項。
2. 文件上傳相關核心類:
//改進上面的文件上傳代碼,添加一個臨時文件 public class UploadServlet extends HttpServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { DiskFileItemFactory fac=new DiskFileItemFactory(); fac.setSizeThreshold(1024*1024);//設置緩沖區為1mb //設置臨時文件的本地磁盤存儲路徑 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(); } } }
3. 實現多文件上傳(需要js技術):主要是更改jsp頁面,通過js代碼來添加多個文件進行上傳,服務器代碼無需更改
<%@ 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. 關于文件上傳的一些問題:
3. 文件下載
1. 傳統文件下載方式有超鏈接下載或者后臺程序下載兩種方式。通過超鏈接下載時,如果瀏覽器可以解析,那么就會直接打開,如果不能解析,就會彈出下載框;而后臺程序下載就必須通過兩個響應頭和一個文件的輸入流。
2. 后臺程序下載:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。