45.Cookie、Session、ServletContext数据共享
請求轉發
特點:只發一次請求,url不變。
優點:可以實現不同servlet之間的數據共享。
缺點:
1、由于請求URL不變,當網絡卡頓時,有可能由于用戶誤操作而導致表單重復提交。
2、請求轉發只能在當前項目內部進行,不能轉發到外部資源。
案例:
AServlet
@WebServlet("/a") public class AServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username="張三";//向請求對象中保存數據req.setAttribute("name",username);//調用API完成請求轉發//getRequestDispatcher(轉發的路徑) 設置轉發路徑//forward(req,resp) 執行轉發操作req.getRequestDispatcher("/b").forward(req,resp);//req.getRequestDispatcher("http://www.baidu.com").forward(req,resp); 測試能否轉發到外部項目} }BServlet
@WebServlet("/b") public class BServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//設置請求字符編碼格式req.setCharacterEncoding("utf-8");//設置響應字符編碼格式resp.setContentType("text/html;charset=utf-8");resp.setCharacterEncoding("utf-8");//從請求對象中獲取保存的數據String name = (String) req.getAttribute("name");System.out.println(name);resp.getWriter().write(name);} }重定向
優點:重定向可以解決請求轉發帶來的表單重復提交和不能訪問外部資源的問題。
缺點:不能通過請求對象來完成不同servlet之間的數據共享。
AServlet
@WebServlet("/a") public class AServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username="張三";//向請求對象中保存數據req.setAttribute("name",username);//通過響應對象來完成重定向操作。resp.sendRedirect("/b");} }BServlet
@WebServlet("/b") public class BServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");resp.setCharacterEncoding("utf-8");System.out.println("訪問了BServlet");} }[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cid4Jjqr-1631707496949)(C:\Users\王元元\AppData\Roaming\Typora\typora-user-images\image-20210912230631821.png)]
會話跟蹤
什么是會話?
當用戶訪問了某個web項目后,只要沒有主動退出或關閉瀏覽器,在此期間向該項目發送的所有請求都存在于一個會話中。
HTTP協議是一個無狀態的協議,發送的不同HTTP請求之間沒有狀態保存,因此數據無法共享。
什么是會話跟蹤?
保證同一個會話中的不同請求之間的數據共享的技術,就是會話跟蹤。
會話跟蹤之cookie
cookie是一門瀏覽器端的數據存儲技術。
當某次請求在服務器中創建cookie對象后,使用響應對象將其返回給瀏覽器,瀏覽器在后續的發送的請求后,會自動將cookie信息附帶在請求頭中發送到后臺。
CookieServlet
/*** 用于創建cookie*/ @WebServlet("/cookie") public class CookieServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//創建了cookie對象,并通過構造方法保存了數據Cookie cookie = new Cookie("a","1");//只有訪問指定的路徑時,才會附帶cookie信息cookie.setPath("/tcs");//指定cookie的有效時間,可以使用該api來完成七天免登錄之類的操作//如果調用了setMaxAge(),則cookie會以序列化生成一個文件,存放在硬盤中cookie.setMaxAge(7*24*60*60);//通過響應對象,將cookie返回給瀏覽器resp.addCookie(cookie);} }TestCookieServlet
/*** 測試cookie*/ @WebServlet("/tcs") public class TestCookieServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通過請求對象對獲取所有的cookie信息Cookie[] cookies = req.getCookies();for (Cookie cookie : cookies) {if (cookie.getName().equals("username")) {System.out.println(cookie.getValue());}}} }會話跟蹤之session
session是服務器端的數據存儲技術。
session要依賴的cookie做實現。服務器中獲取session是基于cookie中附帶的JSESSIONID來進行session匹配的。
session的創建:
SessionServlet
@WebServlet("/session") public class SessionServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//獲取或創建session//獲取:請求頭中通過cookie附帶了JSESSIONID時,//創建:請求頭中沒有通過cookie附帶JSESSIONID時,HttpSession session = req.getSession();//設置session的最大活動時間session.setMaxInactiveInterval(2*60*60);//向session中保存數據session.setAttribute("username","jack");//主動銷毀session,如果主動銷毀了session,之后在項目中無法通過session對象去獲取數據//session.invalidate();} }TestSessionServlet
@WebServlet("/tss") public class TestSessionServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession();Object username = session.getAttribute("username");System.out.println(username);} }session的有效期:瀏覽器的一次打開和關閉。
session和cookie的選擇:
cookie實現會話跟蹤時,所有保存的數據都會通過cookie對象在請求頭中附帶到后臺服務器,一旦請求被攔截器,數據的安全性得不到保障,因此會使用session來進行會話跟蹤。
cookie和session區別
session是服務器端的數據存儲技術。
cookie是一門瀏覽器端的數據存儲技術。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PhDCjtWA-1631707496950)(C:\Users\王元元\AppData\Roaming\Typora\typora-user-images\image-20210910125821053.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-j3vHVLbw-1631707496951)(C:\Users\王元元\AppData\Roaming\Typora\typora-user-images\image-20210910125845431.png)]
servletContext
web應用的上下文對象,每一個部署在服務器中的web項目,當服務器啟動時都會自動創建一個servletContext對象,當前項目內的所有servlet共享同一個servletContext對象,所以,可以使用該對象來完成不同用戶的數據共享。
TestServletContext
@WebServlet("/tsc") public class TestServletContext extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//第一種獲取方式:直接使用servlet對象獲取ServletContext context1 = this.getServletContext();//第二種獲取方式:使用servletConfig獲取ServletContext context2 = this.getServletConfig().getServletContext();//第三種獲取方式:使用session獲取ServletContext context3 = req.getSession().getServletContext();System.out.println(context1==context2);System.out.println(context1==context3);//獲取servletContext對象的初始化參數String username = context1.getInitParameter("username");System.out.println(username);//獲取web應用上下文的路徑System.out.println(context1.getContextPath());Student student = new Student();student.setName("李四");//向servletContext中保存數據context1.setAttribute("student",student);} }AServlet
@WebServlet("/a") public class AServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ServletContext context = this.getServletContext();//根據key從servletContext對象中獲取數據。Student student = (Student) context.getAttribute("student");System.out.println(student.getName());} }案例:統計網站訪問量
在servletContext中保存一個用于記錄網站訪問量的變量,每當servlet接收一次用戶請求,將該變量的值加1即可。
@WebServlet("/count") public class CountVisitServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");resp.setCharacterEncoding("utf-8");ServletContext context = this.getServletContext();Integer count = (Integer) context.getAttribute("count");System.out.println(count);if (null == count) {count=1;}else{count++;}context.setAttribute("count",count);resp.getWriter().write("<h1>當前網站訪問人數為:"+count+"</h1>");} }封裝工具類:BaseServlet
BaseServlet
package com.woniuxy.servlet;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;/*** 工具類:*/ public class BaseServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//獲取的就是用戶傳遞的method參數,就是用戶要去調用的方法名稱String methodName = req.getParameter("method");//如果用戶發起請求時,未傳遞method,或傳遞得不完整(method=)if ("".equals(methodName)||null==methodName) {throw new RuntimeException("當前請求中未傳遞method參數,無法準確調用對應的方法來處理請求!!");}Method method = null;try {method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);} catch (NoSuchMethodException e) {e.printStackTrace();}if (null != method) {//判斷方法對象不為空try {Object returnValue = method.invoke(this,req,resp);if (null == returnValue) {//為空時,表示請求由ajax發起,無需跳轉,也就無需對返回值進行處理return ;}else{//不為空時,表示要進行跳轉,需要對返回值進行相應的處理String value = (String) returnValue;// 1、f:/a(:之前的是跳轉方式,:之后的就是跳轉的路徑) 2、/a(默認的跳轉方式)if (value.contains(":")) {//包含了:則進行對應的處理(基于:進行字符串拆分)String[] split = value.split(":");String option = split[0];//返回的是跳轉方式String path = split[1];//返回的是跳轉路徑if (option.equals("r")) {//重定向操作resp.sendRedirect(path);} else if (option.equals("f")) {//請求轉發req.getRequestDispatcher(path).forward(req,resp);}else{throw new RuntimeException("當前系統尚不支持此種類型的操作,請待系統升級后再使用!!");}}else{//如果不包含:,默認使用重定向來處理resp.sendRedirect(value);}}} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}else{throw new RuntimeException("請求的方法不存在!!");}} }UserServlet
package com.woniuxy.servlet;import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 用于處理用戶類型資源的servlet* http://localhost:8080/user?method=findById*/ @WebServlet("/user") public class UserServlet extends BaseServlet {/*** 方法返回值只能是string 或 void* String:表示要去做請求轉發或重定向操作 值其實就是轉發或重定向的路徑* void: 表示請求是由ajax方式發出,無法實現跳轉功能* @param request* @param response* @return*/public String findAll(HttpServletRequest request, HttpServletResponse response){System.out.println("執行了findAll");return "/a";}public String updateById(HttpServletRequest request, HttpServletResponse response){System.out.println("執行了updateById");return "r:/b";}public String deleteById(HttpServletRequest request, HttpServletResponse response){System.out.println("執行了deleteById");return "f:/a";}public String addUser(HttpServletRequest request, HttpServletResponse response){System.out.println("執行了addUser");return "d:/b";} }使用BaseServlet要點:
1、向后臺發送請求時,必須帶method參數,參數的值取servlet的方法名稱
2、servlet的方法返回值,只是能String或void。返回值為String時,接收的請求應該是普通請求,返回值為void時,接收的請求是ajax請求。
3、servlet的方法返回值格式:r|f:/path
r:重定向
f:請求轉發
/path:表示要跳轉的路徑
AJAX:
實現客戶端的異步請求操作
Jsp:
是一種動態網頁開發技術。它使用JSP標簽在HTML網頁中插入Java代碼。標簽通常以<%開頭以%>結束。
一.ajax的優點:
1.開發過程中前端與后端脫離,交互通過JSON傳輸來實現2.跨平臺能力更強,依托于瀏覽器的支持3.使后臺數據接口能夠得到復用二.ajax的缺點:
1.開發難度大,考慮瀏覽器的兼容性2.頁面請求過多3.屬于后加載,無法被爬蟲爬到4.接口代碼需要新增很多5.無法直接顯示java實體類對象,需要轉換為json格式三.jsp的優點:
1.可被爬蟲爬到2.減少請求次數3.不用考慮瀏覽器的兼容性四.jsp的缺點:
1.增大了服務器的壓力2.前端與后端未脫離,拖慢開發進度3.過于依賴java運行環境4.復用較低操作
Jsp:
是一種動態網頁開發技術。它使用JSP標簽在HTML網頁中插入Java代碼。標簽通常以<%開頭以%>結束。
一.ajax的優點:
1.開發過程中前端與后端脫離,交互通過JSON傳輸來實現2.跨平臺能力更強,依托于瀏覽器的支持3.使后臺數據接口能夠得到復用二.ajax的缺點:
1.開發難度大,考慮瀏覽器的兼容性2.頁面請求過多3.屬于后加載,無法被爬蟲爬到4.接口代碼需要新增很多5.無法直接顯示java實體類對象,需要轉換為json格式三.jsp的優點:
1.可被爬蟲爬到2.減少請求次數3.不用考慮瀏覽器的兼容性四.jsp的缺點:
1.增大了服務器的壓力2.前端與后端未脫離,拖慢開發進度3.過于依賴java運行環境4.復用較低總結
以上是生活随笔為你收集整理的45.Cookie、Session、ServletContext数据共享的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 8.0人脸识别,华为终于
- 下一篇: linux操作系统各版本直接的区别?