三、Web服务器——HTTP协议 Response对象 ServletContext对象 学习笔记
生活随笔
收集整理的這篇文章主要介紹了
三、Web服务器——HTTP协议 Response对象 ServletContext对象 学习笔记
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今日內容
1. HTTP協議:響應消息 2. Response對象 3. ServletContext對象HTTP協議:
1. 請求消息:客戶端發送給服務器端的數據* 數據格式:1. 請求行2. 請求頭3. 請求空行4. 請求體 2. 響應消息:服務器端發送給客戶端的數據* 數據格式:1. 響應行1. 組成:協議/版本 響應狀態碼 狀態碼描述2. 響應狀態碼:服務器告訴客戶端瀏覽器本次請求和響應的一個狀態。1. 狀態碼都是3位數字 2. 分類:1. 1xx:服務器就收客戶端消息,但沒有接受完成,等待一段時間后,發送1xx多狀態碼2. 2xx:成功。代表:2003. 3xx:重定向。代表:302(重定向),304(訪問緩存)4. 4xx:客戶端錯誤。* 代表:* 404(請求路徑沒有對應的資源) * 405:請求方式沒有對應的doXxx方法5. 5xx:服務器端錯誤。代表:500(服務器內部出現異常)2. 響應頭:1. 格式:頭名稱: 值2. 常見的響應頭:1. Content-Type:服務器告訴客戶端本次響應體數據格式以及編碼格式2. Content-disposition:服務器告訴客戶端以什么格式打開響應體數據* 值:* in-line:默認值,在當前頁面內打開* attachment;filename=xxx:以附件形式打開響應體。文件下載3. 響應空行4. 響應體:傳輸的數據* 響應字符串格式HTTP/1.1 200 OKContent-Type: text/html;charset=UTF-8Content-Length: 101Date: Wed, 06 Jun 2018 07:08:42 GMT<html><head><title>$Title$</title></head><body>hello , response</body></html>Response對象
* 功能:設置響應消息1. 設置響應行1. 格式:HTTP/1.1 200 ok2. 設置狀態碼:setStatus(int sc) 2. 設置響應頭:setHeader(String name, String value) 3. 設置響應體:* 使用步驟:1. 獲取輸出流* 字符輸出流:PrintWriter getWriter()* 字節輸出流:ServletOutputStream getOutputStream()2. 使用輸出流,將數據輸出到客戶端瀏覽器* 案例:1. 完成重定向* 重定向:資源跳轉的方式* 代碼實現://1. 設置狀態碼為302response.setStatus(302);//2.設置響應頭locationresponse.setHeader("location","/day15/responseDemo2");//簡單的重定向方法response.sendRedirect("/day15/responseDemo2");* 重定向的特點:redirect1. 地址欄發生變化2. 重定向可以訪問其他站點(服務器)的資源3. 重定向是兩次請求。不能使用request對象來共享數據* 轉發的特點:forward1. 轉發地址欄路徑不變2. 轉發只能訪問當前服務器下的資源3. 轉發是一次請求,可以使用request對象來共享數據* forward 和 redirect 區別* 路徑寫法:1. 路徑分類1. 相對路徑:通過相對路徑不可以確定唯一資源* 如:./index.html* 不以/開頭,以.開頭路徑* 規則:找到當前資源和目標資源之間的相對位置關系* ./:當前目錄* ../:后退一級目錄2. 絕對路徑:通過絕對路徑可以確定唯一資源* 如:http://localhost/day15/responseDemo2 /day15/responseDemo2* 以/開頭的路徑* 規則:判斷定義的路徑是給誰用的?判斷請求將來從哪兒發出* 給客戶端瀏覽器使用:需要加虛擬目錄(項目的訪問路徑)* 建議虛擬目錄動態獲取:request.getContextPath()* <a> , <form> 重定向...* 給服務器使用:不需要加虛擬目錄* 轉發路徑2. 服務器輸出字符數據到瀏覽器* 步驟:1. 獲取字符輸出流2. 輸出數據* 注意:* 亂碼問題:1. PrintWriter pw = response.getWriter();獲取的流的默認編碼是ISO-8859-12. 設置該流的默認編碼3. 告訴瀏覽器響應體使用的編碼//簡單的形式,設置編碼,是在獲取流之前設置response.setContentType("text/html;charset=utf-8");3. 服務器輸出字節數據到瀏覽器* 步驟:1. 獲取字節輸出流2. 輸出數據4. 驗證碼1. 本質:圖片2. 目的:防止惡意表單注冊隨機生成驗證碼圖片輸出到瀏覽器頁面上的案例:
package cn.web.servlet;import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random;/*** 重定向*/ @WebServlet("/checkCodeServlet") public class CheckCodeServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {int width = 100;int height = 50;// 1.創建一個對象,在內存中畫圖(驗證碼圖片對象)BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);// 2.美化圖片// 2.1 填充背景色Graphics g = image.getGraphics();// 畫筆對象g.setColor(Color.pink); // 設置畫筆顏色g.fillRect(0,0,width,height); // 填充一個矩形// 2.2 畫邊框g.setColor(Color.blue);g.drawRect(0,0,width-1,height-1);String str = "ABCDEFGHIJKLMNOPQRETUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";// 生成隨機下標Random random = new Random();for (int i = 1; i <= 4; i++) {int index = random.nextInt(str.length());// 獲取字符char c = str.charAt(index); // 根據下標取出隨機字符// 2.3 寫驗證碼g.drawString(c+"",width/5*i,height/2);}// 2.4 畫干擾線g.setColor(Color.green);// 隨機生成坐標點for (int i = 0; i < 10; i++) {int x1 = random.nextInt(width);int x2 = random.nextInt(width);int y1 = random.nextInt(height);int y2 = random.nextInt(height);g.drawLine(x1,y1,x2,y2);}// 3.將圖片輸出到頁面展示ImageIO.write(image,"jpg",response.getOutputStream());}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request,response);} } <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>register</title><script>/*分析:點擊超鏈接或者圖片,需要換一張圖片1. 給超鏈接和圖片綁定點擊事件2. 重新設置圖片的src屬性值*/window.onload = function () {// 1.獲取圖片對象var img = document.getElementById("checkCode");var a = document.getElementById("change");// 2.綁定單擊事件img.onclick = function () {// 加時間戳, 因為瀏覽器會自動緩存同一個路徑請求的圖片,通過改變請求路徑,給路徑后面加上參數來實現var date = new Date().getTime();img.src = "/day15/checkCodeServlet?" + date}a.onclick = function () {// 加時間戳, 因為瀏覽器會自動緩存同一個路徑請求的圖片,通過改變請求路徑,給路徑后面加上參數來實現var date = new Date().getTime();img.src = "/day15/checkCodeServlet?" + date}}</script> </head> <body><img src="/day15/checkCodeServlet" id="checkCode"/><a href="#" id="change">看不清,換一張</a></body> </html>ServletContext對象:
1. 概念:代表整個web應用,可以和程序的容器(服務器)來通信 2. 獲取:1. 通過request對象獲取request.getServletContext();2. 通過HttpServlet獲取this.getServletContext(); 3. 功能:1. 獲取MIME類型:* MIME類型:在互聯網通信過程中定義的一種文件數據類型* 格式: 大類型/小類型 text/html image/jpeg* 獲取:String getMimeType(String file) 2. 域對象:共享數據1. setAttribute(String name,Object value)2. getAttribute(String name)3. removeAttribute(String name)* ServletContext對象范圍:所有用戶所有請求的數據3. 獲取文件的真實(服務器)路徑1. 方法:String getRealPath(String path) String b = context.getRealPath("/b.txt");//web目錄下資源訪問System.out.println(b);String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目錄下的資源訪問System.out.println(c);String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目錄下的資源訪問System.out.println(a);案例:
* 文件下載需求:1. 頁面顯示超鏈接2. 點擊超鏈接后彈出下載提示框3. 完成圖片文件下載* 分析:1. 超鏈接指向的資源如果能夠被瀏覽器解析,則在瀏覽器中展示,如果不能解析,則彈出下載提示框。不滿足需求2. 任何資源都必須彈出下載提示框3. 使用響應頭設置資源的打開方式:* content-disposition:attachment;filename=xxx* 步驟:1. 定義頁面,編輯超鏈接href屬性,指向Servlet,傳遞資源名稱filename2. 定義Servlet1. 獲取文件名稱2. 使用字節輸入流加載文件進內存3. 指定response的響應頭: content-disposition:attachment;filename=xxx4. 將數據寫出到response輸出流文件目錄結構:
download.html文件:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>download</title> </head> <body><a href="./img/1.jpg">圖片1</a><a href="./img/3.avi">視頻</a><hr><a href="/day15/downloadServlet?filename=1.jpg">圖片1</a><a href="/day15/downloadServlet?filename=3.avi">視頻</a></body> </html>DownloadServlet.java文件:
package cn.web.download;import cn.web.utils.DownLoadUtils;import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException;@WebServlet("/downloadServlet") public class DownloadServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1.獲取請求參數,文件名稱String filename = request.getParameter("filename");// 2.使用字節輸入流加載文件進內存// 2.1 找到文件服務器路徑ServletContext servletContext = this.getServletContext();String realPath = servletContext.getRealPath("/img/" + filename);// 2.2 用字節流關聯FileInputStream fileInputStream = new FileInputStream(realPath);// 3.設置response的響應頭// 3.1 設置響應頭類型 content-typeString mimeType = servletContext.getMimeType(filename);response.setHeader("content-type",mimeType);// 解決中文文件名問題// 1. 獲取user-agent請求頭String agent = request.getHeader("user-agent");// 2. 使用工具類方法編碼文件名即可filename = DownLoadUtils.getFileName(agent, filename);// 3.2 設置響應頭打開方式 content-dispositionresponse.setHeader("content-disposition","attachment;filename="+filename);// 4.將輸入流的數據寫出到輸出流中ServletOutputStream outputStream = response.getOutputStream();byte[] buff = new byte[1024*8];int len=0;while ((len = fileInputStream.read(buff)) != -1){outputStream.write(buff,0,len);}fileInputStream.close();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request,response);} }工具類 DownLoadUtils.java文件:
package cn.web.utils;import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException; import java.net.URLEncoder;public class DownLoadUtils {public static String getFileName(String agent, String filename) throws UnsupportedEncodingException {if (agent.contains("MSIE")) {// IE瀏覽器filename = URLEncoder.encode(filename, "utf-8");filename = filename.replace("+", " ");} else if (agent.contains("Firefox")) {// 火狐瀏覽器BASE64Encoder base64Encoder = new BASE64Encoder();filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";} else {// 其它瀏覽器filename = URLEncoder.encode(filename, "utf-8");}return filename;} } * 問題:* 中文文件問題* 解決思路:1. 獲取客戶端使用的瀏覽器版本信息2. 根據不同的版本信息,設置filename的編碼方式不 // 解決中文文件名問題// 1. 獲取user-agent請求頭String agent = request.getHeader("user-agent");// 2. 使用工具類方法編碼文件名即可filename = DownLoadUtils.getFileName(agent, filename);
總結
以上是生活随笔為你收集整理的三、Web服务器——HTTP协议 Response对象 ServletContext对象 学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: react 网易云音乐实战项目笔记
- 下一篇: logisim实验——通过2个半加器实现