一、請求的方式
1.地址欄輸入
在瀏覽器地址欄直接輸入要訪問的地址,此種方式可以看做是訪問服務器的起始操作。
http://ip:port/path
2.超鏈接
使用超鏈接也可以向服務器發出請求
<a href=”http:/ www.baidu.com”>百度
3.表單form
當需要向服務器發送請求,並且傳輸一些用戶輸入的數據時,我們優先選擇 form 表單的方式發起請求。
4.異步請求Ajax
通過 ajax 發起的請求,屬於異步請求,能實現局部刷新的效果,是一種比較常用的請求方式。
通過 jQuery 中的 ajax(),get(),post(),getJSON()等方法都能發送請求
5.請求轉發
通過服務器內部將請求進行一次轉發,可以請求到其他資源
6.重定向
服務器通過給定一個新資源的地址,響應會客戶端後,客戶端自動再次發送一個請求到新資源的地址處。
二、HttpServletRequest對象
1.理解
HttpServletRequest 對象:主要作用是用來接收客戶端發送過來的請求信息
HttpServletRequest 是 ServletRequest 的子接口,ServletRequest
只有一個子接口,就是 HttpServletRequest。
2.常用方法
//重要記得: getRequestURI 獲取請求時的部分路徑 // getMethod() 獲取請求類型 // getParameter() 通過參數名獲取到具體參數值 /* 常用方法 */ // 獲取請求時的完整路徑 (從http開始,到"?"前面結束) System.out.println("獲取請求時的完整路徑:" + request.getRequestURL()); // 獲取請求時的部分路徑 (從站點名開始,到"?"前面結束) System.out.println("獲取請求時的部分路徑:" + request.getRequestURI()); // 獲取請求時的參數字符串 (從"?"開始到最後) System.out.println("獲取請求時的參數字符串:" + request.getQueryString()); // 獲取請求類型 (GET|POST) System.out.println("獲取請求類型:" + request.getMethod()); // 獲取請求協議版本 (HTTP/1.1) System.out.println("獲取請求協議版本: " +request.getProtocol()); // 獲取站點名 (webapp的名稱) System.out.println("獲取站點名: " +request.getContextPath()); System.out.println("==========================================="); /* 獲取請求頭 */ // 通過具體的請求頭名稱獲取對應的值 (請求頭的名稱不區別大小寫) String host = request.getHeader("host"); System.out.println("Host:" + host); // 獲取所有的請求頭名稱,返回枚舉集合 Enumeration<String> enumeration = request.getHeaderNames(); // 遍歷枚舉集合 while(enumeration.hasMoreElements()) { System.out.println("請求頭名稱:" + enumeration.nextElement()); } System.out.println("==========================================="); /* 獲取客戶端請求的參數 */ // 通過參數名獲取到具體參數值 ,返回字符串 String uname = request.getParameter("uname"); System.out.println("用戶名:" + uname); // 獲取指定參數名的所有參數值 String[] hobbys = request.getParameterValues("hobby"); // 判斷非空 if (hobbys != null && hobbys.length > 0) { // 遍歷數組 for (int i = 0; i < hobbys.length; i++) { System.out.println("愛好: " + hobbys[i]); } } // 獲取請求時的所有參數 Enumeration<String> enumeration2 = request.getParameterNames(); // 遍歷枚舉集合 while(enumeration2.hasMoreElements()) { System.out.println("請求參數名稱:" + enumeration2.nextElement()); } // 獲取請求時所有的參數及對應的參數值,返回map Map<String, String[]> map = request.getParameterMap(); // 遍歷map for (String key : map.keySet()) { System.out.println("參數名:" + key + ",參數值:" + map.get(key)); }
3.請求亂碼解決
請求亂碼解決
亂碼的原因:
request在解析數據時使用的編碼格式是ISO-8859-1,該編碼本身就不支持中文。
解決方案:
1、設置request的解析編碼(只針對於POST請求有效)
request.setCharacterEncoding(“UTF-8”);
2、通過new String()將ISO-8859-1的編碼轉換爲UTF-8
new String(request.getParamter(name).getBytes(“ISO-8859-1”),“UTF-8”);
POST請求 GET請求
Tomcat8 亂碼 不亂碼
request.setCharacterEncoding(“UTF-8”); 不處理
Tomcat7 亂碼 亂碼
request.setCharacterEncoding(“UTF-8”); new String(request.getParamter(name).getBytes(“ISO-8859-1”),“UTF-8”);
4.請求轉發
請求轉發跳轉
簡介:
請求轉發是一種服務端的跳轉方式,是服務端行爲
格式:
request.getRequestDispatcher(“地址”).forward(request, response);
特點:
1、服務端行爲,服務端跳轉
2、瀏覽器的地址不發生改變
3、從始至終只有一個請求
4、請求轉發時,數據可以共享(request對象共享)
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub System.out.println("Servlet03....."); //接收參數 String name=req.getParameter("uname"); String pwd=req.getParameter("upwd"); System.out.println("Servlet03 name:"+name); //判斷爲空 if(name!=null&& !"".equals(name.trim())){ //請求轉發跳轉到index頁面 req.getRequestDispatcher("index.html").forward(req, resp); } //req.getRequestDispatcher("index.html").forward(req, resp); }
5.request作爲域對象
request作用域
設置request域對象
request.setAttribute(“限域變量名”,“域變量的值”);
獲取指定域對象的值
request.getAttribute(“限域變量名”);
移除指定域對象的值
request.removeAttribute(“限域變量名”);
設置在request作用域中的數據可以實現數據共享,但只在一次請求中有效,即只在請求轉發跳轉有效。
System.out.println("Servlet04......"); List<String> list=new ArrayList<>(); list.add("hhhh"); list.add("ssss"); //設置request域對象 req.setAttribute("mylist", list); req.setAttribute("name", "lisi"); //移除指定域對象的值 req.removeAttribute("name"); //請求轉發 req.getRequestDispatcher("ser05").forward(req, resp); System.out.println("Servlet05......"); //獲取指定域對象的值 List<String> list=(List<String>) req.getAttribute("mylist"); System.out.println(list.get(0)); String name=(String) req.getAttribute("name"); System.out.println("名字"+name);
三、HttpServletResponse對象
1.理解
HttpServletResponse 的主要功能用於服務器對客戶端的請求進行響應,將 Web 服務器處理後的結果返回給客戶端
2.常用方法和刷新頁面自動跳轉
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ggplakkK-1582382624589)(C:\Users\Hello Word\AppData\Roaming\Typora\typora-user-images\1582381399524.png)]
System.out.println("Servlet01....."); //添加響應頭 resp.addHeader("userName", "zhangsan"); //判斷響應頭是否被設置 System.out.println(resp.containsHeader("userName")); System.out.println(resp.containsHeader("userPwd")); //設置錯誤狀態碼 //resp.sendError(404); //resp.sendError(404,"需要顏值高的,才能訪問"); //設置自動刷新 //resp.setHeader("refresh","3");//每3秒刷新 //設置固定時間後跳轉到某頁面 resp.setHeader("refresh", "3;URL=http://www.baidu.com");
3.數據響應
響應數據:
1.輸出字符流
PrintWriter writer=response.getWriter();
輸出字符串
2.輸出字節流
ServletOutputStream out=response.getOutputStream();
輸出任意
注:字符流和字節流不能同時使用
java.lang.IllegalStateException getWriter() has already been called for this response
響應類型:
response.setContentType(“響應類型MIME-TYpe”);
text文本格式:text/plain
html格式:text/html
System.out.println("Servlet02......"); //設置響應類型 resp.setContentType("text/html;charset=utf-8"); //輸出字符流 /*PrintWriter writer=resp.getWriter(); writer.write("<h2>你好</h2>"); writer.close();*/ //輸出字節流 /*ServletOutputStream out=resp.getOutputStream(); out.write("<h2>歡迎你哦!!!!</h2>".getBytes()); out.close();*/ // 輸出頁面 String table = "<table><tr><th>UserName</th><th>UserPwd</th></tr><tr><td>zhangsan</td><td>123456</td></tr></table>"; resp.getWriter().write(table); resp.getWriter().close(); }
4.響應亂碼問題
響應亂碼解決
getWriter()的字符亂碼
對於 getWriter()獲取到的字符流,響應中文必定出亂碼。
由於服務器端在進行編碼時默認會使用 ISO-8859-1 格式的編碼,該編碼方式並不支持中文。
getOutputStream()字節亂碼
對於 getOutputStream()方式獲取到的字節流,響應中文時,由於本身就是傳輸的字節, 所以此時可能出現亂碼,也可能正確顯示。
當服務器端給的字節恰好和客戶端使用的編碼方式一致時則文本正確顯示,否則出現亂碼。解決方案:
第一步:設置服務端的響應編碼格式
response.setCharacterEncoding(“UTF-8”);
第二步:設置客戶端的編碼的格式
response.setHeader(“content-type”,“text/html;charset=UTF-8”);
總結:
保證發送端和接收端的編碼一致;設置客戶端和服務端的編碼保持一致,且都支持中文。
同時設置客戶端和服務端的編碼
response.setContentType(“text/html;charset=utf-8”);System.out.println("ServletR03....."); //設置服務器的響應編碼格式 //resp.setCharacterEncoding("UTF-8"); //設置客戶端的編碼的格式 //resp.setHeader("content-type", "text/html;charset=UTF-8"); //同時設置客戶端和服務端的編碼 resp.setContentType("text/html;charset=utf-8"); /** * 字符流亂碼 getWriter() * */ /*resp.getWriter().write("<h2>哈哈哈哈</h2>"); resp.getWriter().close(); */ /** * 字節流亂碼:getOutputStream() * */ resp.getOutputStream().write("<h2>嘿嘿嘿嘿嘿</h2>".getBytes()); resp.getOutputStream().close();
5.響應圖片
System.out.println("ServletR04......"); //設置響應類型 resp.setContentType("image/jpeg"); //getRealPath():得到項目存放在服務器中位置 String realPath=req.getServletContext().getRealPath("/"); System.out.println(realPath); //得到圖片存放的路徑 String filePath=realPath+"/WEB-INF/1.jpg"; File file=new File(filePath); //得到輸出流 ServletOutputStream out=resp.getOutputStream(); //得到文件的輸入流 InputStream in=new FileInputStream(file); //輸出數據 byte[] bytes=new byte[1024]; int len=0; while((len=in.read(bytes))!=-1){ out.write(bytes,0,len); } //刷新流 out.flush(); //關閉 in.close(); out.close(); }
6.重定向
重定向:
一種跳轉方式,是服務器指導,客戶端的跳轉行爲
流程:
當有請求到達服務器時,服務器接收請求,響應給客戶端時會向客戶端響應一個新的地址,客戶端接收到響應後,會立刻馬上重新發起一次請求到新的地址,服務器再接收並接收。
特點:
1.客戶端跳轉
2.存在二次請求
3.地址欄會發生改變
4.數據不共享(request對象不共享)
5.地址可以任意地址
//接收請求的參數 String uname=request.getParameter("uname"); System.out.println(uname); //設置域對象 request.setAttribute("upwd", "123456"); //重定向 //response.sendRedirect("s06"); //請求轉發時地址只能定位到當前資源下(不能跨域),重定向可以跨域 //request.getRequestDispatcher("http://www.baidu.com").forward(request, response); response.sendRedirect("http://www.baidu.com");
7.請求轉發和重定向區別
請求轉發和重定向區別:
- 1.請求轉發是服務端跳轉,重定向是客戶端跳轉
- 2.請求轉發時地址欄不發生改變,重定向時地址欄會發生改變
- 3.請求轉發只請求一次,重定向存在兩次請求
- 4.請求轉發數據可以共享(request對象和域對象),重定向數據不共享
- 5.請求轉發時地址只能定位到當前站點下(不能跨域),重定向地址可以任意地址
四、請求路徑問題
相對路徑:
相對於當前資源所在的路徑
絕對路徑:
1.http://開頭的路徑,已經跨域,可以定位到任意地址
2.以/開頭
如果是服務端跳轉,"/"代表的含義是 http://IP:端口/站點名/
如果是客戶端跳轉,"/"代表的含義是 http://IP:端口/
//服務器跳轉:請求轉發跳轉 //相對路徑 http://localhost:8080/myday03/ +img.html //request.getRequestDispatcher("img.html").forward(request, response); //絕對路徑 http://localhost:8080/myday03/ +img.html //request.getRequestDispatcher("/img.html").forward(request, response); //相對路徑 http://localhost:8080/myday03/ +myday03/img.html //request.getRequestDispatcher("myday03/img.html").forward(request, response);//404 //絕對路徑 http://localhost:8080/myday03/ +/myday03/img.html //request.getRequestDispatcher("/myday03/img.html").forward(request, response);//404 // 絕對路徑 請求轉發不支持跨域 // request.getRequestDispatcher("http://www.baidu.com").forward(request, response); /* 客戶端跳轉:重定向跳轉 (表單提交、超鏈接、地址欄輸入等) */ //相對路徑 http://localhost:8080/myday03/ +img.html //response.sendRedirect("img.html"); //絕對路徑 http://localhost:8080/myday03/ +/img.html //response.sendRedirect("/img.html");//404 //相對路徑 http://localhost:8080/myday03/ +myday03/img.html //response.sendRedirect("myday03/img.html");//404 //絕對對路徑 http://localhost:8080/myday03/ +/myday03/img.html //response.sendRedirect("/myday03/img.html");//ok // 絕對路徑 重定向支持跨域 response.sendRedirect("http://www.baidu.com"); // OK
五、Cookie對象
1.cookie的創建和發送
cookie:客戶端的緩存技術,瀏覽器技術
作用:提高網頁效率,減輕服務器負載
Cookie的創建:
Cookie cookie=new Cookie(“名稱”,“值”);
Cookie的發送:
response.addCookie(cookie);
//創建Cookie的創建 Cookie cookie=new Cookie("uname","hhh"); //Cookie的發送 response.addCookie(cookie); //創建Cookie的創建 Cookie cookie2=new Cookie("upwd","123456"); //Cookie的發送 response.addCookie(cookie2);
2.cookie獲取
System.out.println("Cookie02....."); //獲取cookie數組 Cookie[] cookies=req.getCookies(); //判斷非空 if(cookies!=null&&cookies.length>0){ //遍歷cookie數組 for(Cookie cookie:cookies){ System.out.println("名稱:"+cookie.getName()+",值"+cookie.getValue()); //獲取uname的名稱 if("uname".equals(cookie.getName())){ System.out.println("name的值爲:"+cookie.getValue()); } } }
3.cookie到期時間的設定
Cookie到時間的設定
到期時間,到期時間用來指定該cookie何時失效。 默認爲當前瀏覽器關閉就失效
通過setMaxAge(int time);方法設定cookie的最大有效時間,以秒爲單位
大於0的整數
表示cookie存活指定秒數
在瀏覽器中存活指定秒數,在時間未到之前,cookie會一直存在,無論是關閉瀏覽器還是關閉電腦,都不影響,但是不跨瀏覽器和電腦
小於0的整數
表示不存儲,默認關閉瀏覽器失效
0
表示刪除
//創建Cookie的創建 Cookie cookie=new Cookie("uname2","SSS"); //Cookie的發送 response.addCookie(cookie); //創建Cookie的創建 Cookie cookie2=new Cookie("uname3","QQQ"); //設置到期時間 cookie2.setMaxAge(3*24*60*60);//在瀏覽器中存活指定秒數,在時間未定之前,cookie會一直存在,無論是關閉瀏覽器還是關閉電腦,都不影響,但是不跨瀏覽器和電腦 //Cookie的發送 response.addCookie(cookie2); Cookie cookie03 = new Cookie("uname4","wangwu"); cookie03.setMaxAge(0); // 刪除cookie response.addCookie(cookie03); // 刪除已存在的cookie Cookie cook = new Cookie("uname",null); cook.setMaxAge(0); response.addCookie(cook);