請求重定向
一個 web 資源收到客戶端請求后,通知客戶端去訪問另外一個 web 資源,這稱之為請求重定向。
使用response對象提供的sendRedirect()方法,可以將網頁重定向到另一個頁面。SendRedirect()方法的語法格式:
response.sendRedirect("aa.jsp");//重定向
// 參數path指的是目標的路徑,這個路徑可以是相對的,也可以是不同主機的其他URL地址。
該方法把響應連同狀態碼和新的網頁位置發送回瀏覽器。您也可以通過把 setStatus() 和 setHeader() 方法一起使用來達到同樣的效果:
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
//設置302狀態碼,等同于response.setStatus(302);resp.setHeader("Location", “path");
請求轉發
一個 web 資源收到客戶端請求后,通知服務器去調用另外一個 web 資源進行處理,這稱之為請求轉發。
在 Servlet 中實現請求轉發的兩種方式:
1、通過ServletContext實現請求轉發。
this.getServletContext().getRequestDispatcher("/xxx.jsp").forward(request, response);
2、通過request實現請求轉發:
request.getRequestDispatcher("/xxx.jsp").forward(request, response);
request對象同時也是一個域對象(Map容器),開發人員通過request對象在實現轉發時,把數據通過request對象帶給其它web資源處理。
請求重定向與轉發區別
求重定向與轉發的區別主要從以下5點進行了闡述:
1、轉發使用的是getRequestDispatcher()方法,重定向使用的是sendRedirect();
2、轉發:瀏覽器URL的地址欄不變,重定向:瀏覽器URL的地址欄改變;
3、轉發是服務器行為,重定向是客戶端行為;
4、轉發是瀏覽器只做了一次訪問請求,重定向是瀏覽器做了至少兩次的訪問請求;
5、轉發2次跳轉之間傳輸的信息不會丟失,重定向2次跳轉之間傳輸的信息會丟失 (request范圍)。
Cookie原理及應用
Cookie在HTTP中通常是用來辨別用戶身份,進行會話跟蹤而儲存在用戶本地終端上的數據,一般會加密處理,由用戶客戶端計算機暫時或永久保存的信息。其結構就是一個鍵和一個值構成的。隨著服務器端的響應發送給客戶端瀏覽器。然后客戶端瀏覽器會把Cookie保存起來,當下一次再訪問服務器時把Cookie再發送給服務器。
Cookie是由服務器創建,然后通過響應發送給客戶端的鍵值對。客戶端會保存Cookie,并會標注出Cookie的來源。當客戶端向服務器發出請求時會把Cookie包含在請求中發送給服務器,這樣服務器就可以識別客戶端。
Cookie機制:
Cookie機制采用的在客戶端保持HTTP狀態信息的方案。
Cookie會在瀏覽器訪問web服務器某個資源時,web服務器在http響應過程中,消息頭中附帶傳送給瀏覽器的一個文本文件。一旦web瀏覽器保存了某個cookie,那么它在以后每次訪問web服務器時,都會在HTTP請求中將這個cookie回傳給web服務器。
一個cookie只能標識一種信息,它至少有一個標識該信息的名稱(NAME)和設置值(VALUE)。
一個web站點可以給一個web瀏覽器發送多個cookie,一個web瀏覽器也可存儲多個web站點提供的cookie。
cookie 大小上限為4kb。
一個服務器最多在客戶端瀏覽器上保存20個cookie;一個瀏覽器最多保存3000個cookie。
注意:不同瀏覽器間是不共享cookie
cookie使用示例
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();Cookie[] cookies = request.getCookies(); // 獲取瀏覽器訪問訪問服務器時傳遞過來的cookie數組// 如果用戶是第一次訪問,那么得到的cookies將是nullif (cookies != null) {out.write("您上次訪問的時間是:");for (int i = 0; i < cookies.length; i++) {Cookie cookie = cookies[i];if (cookie.getName().equals("lastAccessTime")) {Long lastAccessTime = Long.parseLong(cookie.getValue());Date date = new Date(lastAccessTime);out.write(date.toLocaleString());}}} else {out.write("這是您第一次訪問本站!");} // 用戶訪問過之后重新設置用戶的訪問時間,存儲到cookie中,然后發送到客戶端瀏覽器Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis() + "");// 將cookie對象添加到response對象中,這樣服務器在輸出response對象中的內容時就會把cookie也輸出到客戶端瀏覽器response.addCookie(cookie);}
在上面的例子中,在程序代碼中并沒有使用setMaxAge方法設置cookie的有效期,所以當關閉瀏覽器之后,cookie就失效了,要想在關閉了瀏覽器之后,cookie依然有效,那么在創建cookie時,就要為cookie設置一個有效期。如下所示:
cookie.setMaxAge(24*60*60); //以秒為單位
Cookie 的生命
Cookie 的生命就是Cookie在客戶端的有效時間,可以通過setMaxAge(int)來設置Cookie的有效時間。以秒為單位,不設置則默認為關閉窗口時Cookie結束。
cookie. setMaxAge(-1):cookie的maxAge屬性的默認值就是-1,表示只在瀏覽器內存中存活。一旦關閉瀏覽器窗口,那么cookie就會消失。
cookie.setMaxAge(60*60):表示cookie對象可存活1小時。當生命大于0時,瀏覽器會把Cookie保存到硬盤上,就算關閉瀏覽器,就算重啟客戶端電腦,cookie也會存活1小時;
cookie.setMaxAge(0):cookie生命等于0是一個特殊的值,它表示cookie被作廢!也就是說,如果原來瀏覽器已經保存了這個Cookie,那么可以通過Cookie的setMaxAge(0)來刪除這個Cookie。無論是在瀏覽器內存中,還是在客戶端硬盤上都會刪除這個Cookie。
刪除Cookie
設置cookie.setMaxAge(0),生命等于0是一個特殊的值,它表示cookie被作廢。
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {if (cookie.getName().equals("author")) {cookie.setMaxAge(0);response.addCookie(cookie);}}}
Cookie中存取中文
Cookie 不允許存儲中文,如果要在 Cookie 中存儲中文,那么必須使用 URLEncoder 類里面的 encode(String s, String enc) 方法進行中文轉碼,例如:
Cookie cookie = new Cookie("userName", URLEncoder.encode("軟通動力", "UTF-8"));
response.addCookie(cookie);
獲取 Cookie 中的中文數據時,再使用URLDecoder類里面的decode(String s, String enc) 進行解碼,例如:
URLDecoder.decode(cookies[i].getValue(), "UTF-8");
Session原理及應用
會話管理,當用戶在應用程序的Web頁之間跳轉時,存儲在Session對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。
Servlet中可以把一個會話內需要共享的數據保存到HttSession對象中。四大域對象:PageContext、ServletRequest、HttpSession、ServletContext。
Session保存在服務器端。為了獲得更高的存取速度,服務器一般把Session放在內存里。每個用戶都會有一個獨立的Session。
如果Session內容過于復雜,當大量客戶訪問服務器時可能會導致內存溢出。因此,Session里的信息應該盡量精簡。
首次使用session時,服務器端要創建session,session是保存在服務器端,數據是保存在session中,sessionId通過Cookie發送給客戶端,且只在瀏覽器本次會話中存在,也就是說如果用戶關閉了瀏覽器,那么這個Cookie就丟失。
客戶端再次訪問服務器時,在請求中會帶上sessionId,服務器會通過sessionId找到對應的session,而無需再創建新的session。
Session生成后,只要用戶繼續訪問,服務器就會更新Session的最后訪問時間,并維護該Session。用戶每訪問服務器一次,無論是否讀寫Session,服務器都認為該用戶的Session“活躍(active)”了一次。
由于會有越來越多的用戶訪問服務器,因此Session也會越來越多。為防止內存溢出,服務器會把長時間內沒有活躍的Session從內存刪除。這個時間就是Session的超時時間。如果超過了超時時間沒訪問過服務器,Session就自動失效了。
Session的超時時間為maxInactiveInterval屬性,可以通過對應的getMaxInactiveInterval()獲取,通過setMaxInactiveInterval(longinterval)修改。
Session的超時時間也可以在web.xml中修改。另外,通過調用Session的invalidate()方法可以使Session失效。
session使用實例
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");// 使用request對象的getSession()獲取session,如果session不存在則創建一個HttpSession session = request.getSession();// 將數據存儲到session中session.setAttribute("data", "isoftstone");// 獲取session的IdString sessionId = session.getId();// 判斷session是不是新創建的if (session.isNew()) {response.getWriter().print("session創建成功,session的id是:" + sessionId);} else {response.getWriter().print("服務器已經存在該session了,session的id是:" + sessionId);}}
刪除session
刪除Session的原理,其實就是讓Session在服務器端失效,我們設置Session 失效的時間,是為了確保在用戶長時間不與服務器交互的情況下,可以自動退出登錄。這里將介紹三種設置 Session 失效的方法:
1、通過java代碼設置
session.setMaxInactiveInterval(30*60);//以秒為單位
2、通過項目的web.xml設置
<session-config><session-timeout>10</session-timeout>
</session-config>
3、通過web容器設置 (Tomcat)
在apache-tomcat-10.1.34\conf\web.xml 中配置session-config信息
注意:如果上述三個地方如果都設置了,有個優先級的問題,從高到低:(1)>(2)>(3)
session和Cookie的區別
1、cookie數據存放在客戶的瀏覽器硬盤上,session數據放在服務器內存上。
2、cookie不是很安全,別人可以分析存放在本地的cookie并進行cookie欺騙,考慮到安全應當使用session。
3、session會在一定時間內保存在服務器上。當訪問增多,會比較占用你服務器的性能,考慮到減輕服務器性能方面,應當使用cookie。
4、Session一旦瀏覽器關閉,session就失效,cookie設置有效期后,瀏覽器關閉,不會失效。
5、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
文件上傳下載
文件上傳實例
jsp頁面
<%--file.jsp--%>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head><title>文件上傳</title>
</head>
<body>
<form action="fileServlet" enctype="multipart/form-data" method="post"><p>上傳文件1:<input type="file" name="file1"></p><p>上傳文件2:<input type="file" name="file2"></p><button>ok</button>
</form>
</body>
</html>
成功跳轉頁面
<%--success.jsp,上傳成功跳轉頁面--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head><title>success</title>
</head>
<body>
<body>
<%=request.getAttribute("message") %>
</body>
</body>
</html>
基于 @MultipartConfig 注解實現文件上傳
從 Servlet 3.0 開始已經提供了基于 @MultipartConfig 注解實現文件上傳,而且使用也非常簡單。為此,HttpServletRequest 提供了兩個方法用于從請求中解析出上傳的文件:
Part getPart(String name) // 單文件
Collection getParts() // 多文件
前者用于獲取請求中給定 name 的文件,后者用于獲取所有的文件。
每一個文件用一個javax.servlet.http.Part 對象來表示。該接口提供了處理文件的簡易方法,比如 write()、delete() 等。至此,結合 HttpServletRequest 和 Part 來保存上傳的文件變得非常簡單,如下所示:
@WebServlet(name ="fileServlet" ,urlPatterns = "/fileServlet")
@MultipartConfig
public class FileServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {try{request.setCharacterEncoding("utf-8");Collection<Part> parts = request.getParts();for (Part part : parts) {String filename = part.getSubmittedFileName();String path = request.getServletContext().getRealPath("/file/") + filename;part.write(path);}request.setAttribute("message", "文件上傳成功!");}catch (Exception e){request.setAttribute("message", "上傳失敗,原因:"+e.getMessage());}// 跳轉到 message.jspgetServletContext().getRequestDispatcher("/success.jsp").forward(request, response);}
}
1、需要檢測文件的上傳格式為:enctype="multipart/form-data“
2、需要判斷path路徑是否存在
文件下載實例
jsp頁面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件下載</title>
</head>
<body><a href="downLoadServlet?fileName=filename.png">下載 文件:filename.png</a>
</body></html>
servlet內容
@WebServlet("/downLoadServlet")
public class DownLoadServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{// 1.獲取要下載的文件的絕對路徑String realPath = this.getServletContext().getRealPath("/file/");// 2.獲取要下載的文件名String fileName = request.getParameter("fileName");// 3.設置content-disposition響應頭控制瀏覽器以下載的形式打開文件response.setHeader("content-disposition", "attachment;filename=" + fileName);//response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); // 處理文件名中文亂碼// 4.獲取要下載的文件輸入流InputStream in = new FileInputStream(realPath + fileName);int len = 0;// 5.創建數據緩沖區byte[] buffer = new byte[1024];// 6.通過response對象獲取OutputStream流OutputStream out = response.getOutputStream();// 7.將FileInputStream流寫入到buffer緩沖區while ((len = in.read(buffer)) > 0) {// 8.使用OutputStream將緩沖區的數據輸出到客戶端瀏覽器out.write(buffer, 0, len);}in.close();}
}