Request&Response

貝貝子發表於2022-01-24

HttpServletResponse

web伺服器接收到客戶端的http請求,針對這個請求,分別建立一個代表請求的HttpServletRequest物件,代表響應的一個HttpServletResponse;

  • 如果要獲取客戶端請求過來的引數:找HttpServletRequest
  • 如果要給客戶端響應一些資訊:找HttpServletResponse

簡單分類

負責向瀏覽器傳送資料的方法

ServletoutputStream getoutputStream() throws IOException;
PrintWriter getWriter() throws IOException;(中文最好用這個)

負責向瀏覽器傳送響應頭的方法

void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String name, long date);
void addDateHeader(String name, long date);
void setHeader(String name, String value);
void addHeader(String name, String value);
void setIntHeader(String name, int value);
void addIntHeader(String name, int value);

常見應用

1.向瀏覽器輸出訊息

2.下載檔案

​ 1.要獲取下載檔案的路徑

​ 2.下載的檔名是啥?

​ 3.設定想辦法讓瀏覽器能夠支援下載我們需要的東西

​ 4.獲取下載檔案的輸入流

​ 5.建立緩衝區

​ 6.獲取OutputStream物件

​ 7.將FileOutputStream流寫入到buffer緩衝區

​ 8.使用OutputStream將緩衝區的資料輸出到客戶端

通過response.getOutputStream的方式下載檔案,為檔案設定檔名:

//1.設定檔案ContentType型別,這樣設定,會自動判斷下載檔案型別  
response.setContentType("multipart/form-data");  
//2.設定檔案頭:最後一個引數是設定下載檔名(假如我們叫a.pdf)  
response.setHeader("Content-Disposition", "attachment;fileName="+"a.pdf");  
public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.要獲取下載檔案的路徑
        String realPath = "D:\\java_work\\javaweb-test\\response\\src\\main\\resources\\貝貝子.png";
        System.out.println("下載檔案的路徑"+realPath);
        // 2.下載的檔名是啥?
        String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
        //3.設定想辦法讓瀏覽器能夠支援(Content-Disposition)下載我們需要的東西(中文檔名需要使用:URLEncoder.encode(filename,"UTF-8"),否則可能亂碼或出現編碼問題)
        resp.setHeader("Content-Disposition", "attachment;fileName="+ URLEncoder.encode(filename,"UTF-8"));
        // 4.獲取下校檔案的輸入流
        FileInputStream in = new FileInputStream(realPath);
        // 5.建立緩衝區
        int len=0;
        byte[] buffer = new byte[1024];
        // 6.獲取Outputstream物件
        ServletOutputStream out = resp.getOutputStream();
        //7.將FiLeoutputstream流寫入到buffer緩衝區,使用outputStream將緩衝區中的數擦輸出到客戶端!
        while((in.read(buffer))>0){
            out.write(buffer,0,len);
        }
      in.close();
      out.close();
    }
	@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3、驗證碼功能

驗證怎麼來的?

  • 前端實現
  • 後端實現,需要用到Java的圖片類,生成一個圖片
package com.bbz.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
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;

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //如何讓瀏覽器5秒自動重新整理一次
        resp.setHeader("refresh","3");
        //在記憶體中建立一個圖片
        BufferedImage bufferedImage = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到圖片
        Graphics2D g=(Graphics2D) bufferedImage.getGraphics();
        //設定圖片背景顏色
        g.setColor(Color.yellow);
        g.fillRect(0,0,80,20);
        //給圖片寫資料
        g.setColor(Color.BLUE);
        g.setFont(new Font(null,1,20));
        g.drawString(makeNum(),0,20);
        //告訴瀏覽器,這個請求用圖片的方式開啟
        resp.setContentType("image/png");
        //網站存在快取,不讓瀏覽器快取
        resp.setDateHeader("expires",-1);
        resp.setHeader("Cache-Control","no-cache");
        resp.setHeader("Pragma","no-cache");

        //把圖片寫給瀏覽器
        boolean write = ImageIO.write(bufferedImage,"png", resp.getOutputStream());

    }
    //生成隨機數
    private String makeNum(){
        Random random=new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<7- num.length();i++){
            sb.append("0");
        }	//保證驗證碼一定是7位數
        num = sb.toString() + num;
        return num;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

4.重定向

一個web資源B收到客戶端A請求後,通知客戶端A訪問另一個web資源C,該過程叫重定向。
常見場景:使用者登入;

	public void sendRedirect(String location) throws IOException;

重定向:

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*重定向原理
        resp.setHeader("Location","/resp/img");
        resp.setStatus(302);
         */
        resp.sendRedirect("/resp/img");//重定向
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

重定向與轉發的異同點:

  • 相同:
    • 頁面都會跳轉
  • 不同:
    • 請求轉發的時候,URL不會產生變化 307
    • 重定向的時候,URL位址列會發生變化 302

登入重定向的小demo:
建立處理登入重定向的Servlet:

public class RequestTes extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //處理請求
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println(username+":"+password);

        //重定向的時候一定要注意路徑問題
        resp.sendRedirect("/resp/success.jsp");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

在index.jsp中新增登入提交:

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8" %>
<html>
<body>
<h2>Hello World!</h2>

    <%-- 這裡提交的路徑,需要尋找到專案的路徑 --%>
    <%-- ${pageContext.request.contextPath}代表當前專案 --%>
    <form action="${pageContext.request.contextPath}/request" method="get">
        使用者名稱: <input type="text" name="username" /> <br/>
        密  碼: <input type="password" name="password" /> <br/>
        <input type="submit">
    </form>

</body>
</html>

注:在jsp中指定編碼格式可以防止中文亂碼。

HttpServletRequest

HttpServletRequest代表客戶端的請求,使用者通過Http協議訪問伺服器,HTTP請求中的所有資訊會被封裝到HttpServletRequest,通過這個HttpServletRequest的方法,可以獲取請求的資訊

  • getContextPath() 獲取當前路徑
  • getHeader() 獲取頭資訊
  • getHttpServletMapping() 獲取請求的路徑
  • getRequestURL() 獲取請求的URL

獲取前端傳遞的引數及請求轉發:

	request.getParameter(String s) //取單個值
	request.getParameterValues(String s) //取多個值

接受登入資訊的servlet檔案:

package com.bbz.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.util.Arrays;


public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 解決後臺接受中文亂碼問題
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");

        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));

        // 重定向
        // resp.sendRedirect("/resuest-01/success.jsp");
        // 通過請求轉發, 此處的 / 就是當前web應用,不需要在多寫了。
        req.getRequestDispatcher("/success.jsp").forward(req, resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

登入的jsp頁面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Login</title>
</head>
<body>

    <h1>登入</h1>
    <div style="text-align: center">
<%-- 這裡表單表示的意思:以post方式提交表單,提交到我們的login請求       --%>
        <form action="${pageContext.request.contextPath}/login" method="post">
            使用者名稱:<input type="text" name="username"> <br/>
            密碼:<input type="password" name="password"> <br/>
            愛好:
            <input type="checkbox" name="hobbys" value="女孩">女孩
            <input type="checkbox" name="hobbys" value="程式碼">程式碼
            <input type="checkbox" name="hobbys" value="唱歌">唱歌
            <input type="checkbox" name="hobbys" value="電影">電影

            <br/>
            <input type="submit">
        </form>
    </div>
</body>
</html>