当前位置:网站首页>This is enough for request & response

This is enough for request & response

2022-06-25 10:13:00 Grilled little fat sheep with charcoal...

Request and Response Overview

Request It's the object of the request ,Response It's a response object . These two objects are used by us Servlet I saw it when I was :
 Insert picture description here here , We need to think about a problem request and response What are the functions of these two parameters ?
 Insert picture description here

  • request: Get request data

    • The browser will send HTTP Request to the background server [Tomcat]
    • HTTP Your request will contain a lot of request data [ Request line + Request header + Request body ]
    • Background server [Tomcat] Would be right HTTP The data in the request is parsed and the parsing result is stored in an object
    • The stored object is request object , So we can request Object to get the relevant parameters of the request
    • After obtaining the data, you can continue the subsequent business , For example, obtaining the user name and password can realize the related business of login operation
  • response: Set response data

    • After business processing , The background needs to return the result of business processing, i.e. response data, to the front end
    • Encapsulate the response data into response In the object
    • Background server [Tomcat] Can parse response object , according to [ Response line + Response head + Response body ] Format splicing results
    • The browser finally parses the result , Display the content in the browser for users to browse

For the above mentioned content , Let's have a preliminary experience through a case request and response Use of objects

@WebServlet(urlPatterns = "/demo1")
public class ServletDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        // 1.  Use request object   Get request data 
        String username = req.getParameter("username");

        // 2.  Use response object   Set response data 
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("<h1>" + username +",  Welcome !</h1>");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        System.out.println("post...");
    }
}

 Insert picture description here

Request object

Request Inheritance system

I'm going to introduce Request and Reponse When the object , We found that :

  • When our Servlet Class implements Servlet Interface When ,service The parameter in the method is ServletRequest and ServletResponse
  • When our Servlet Class inherits HttpServlet class When ,doGet and doPost The parameter in the method becomes HttpServletRequest and HttpServletReponse

that ,

  • ServletRequest and HttpServletRequest What is the relationship of ?
  • request Who created the object ?
  • request What are provided API, these API Where to find out ?

First , So let's see Request Inheritance system :
 Insert picture description here

As can be seen from the above figure ,ServletRequest and HttpServletRequest All are Java Provided , So we can open JavaEE Provided API file , You can see :

 Insert picture description here  Insert picture description here therefore ServletRequest and HttpServletRequest It's inheritance , And both are interfaces , Interface is unable to create object , At this time, the following problem arises :
 Insert picture description here This is the time , We need to use Request In the inheritance system RequestFacade:

  • This class implements HttpServletRequest Interface , It also indirectly realizes ServletRequest Interface .
  • Servlet Class service Method 、doGet Method or doPost The method is ultimately determined by Web The server [Tomcat] To invoke the , therefore Tomcat The specific implementation class of method parameter interface is provided , And completed the creation of the object .
  • If you want to know RequestFacade What methods are provided in , We can look directly at JavaEE Of API About in the document ServletRequest and HttpServletRequest Interface documentation , because RequestFacade To implement its interface, you need to rewrite the methods in the interface

For the above conclusion , To verify , You can write a Servlet, Put... In the method request Print the object , You can see whether the final object is RequestFacade, The code is as follows :

@WebServlet(urlPatterns = "/demo2")
public class ServletDemo2 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        System.out.println(request);  // [email protected]
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}

 Insert picture description here
Summary

  1. Request Our inheritance system is ServletRequest–>HttpServletRequest–>RequestFacade;

  2. Tomcat The request data needs to be parsed , Encapsulated in the request object , And create request Object passed to service Method ;

  3. Use request object , You can refer to JavaEE API Document HttpServletRequest Method description in the interface .

Request Get request data

HTTP The request data is divided into three parts , Namely Request line 、 Request header 、 Request body , For the data of these three parts , How to get , First, let's learn how to obtain the request line data ?
Want to know more about HTTP Information can be found in the links :https://blog.csdn.net/qq_43751200/article/details/125219277

Get request line data

GET The request line contains three pieces , Namely Request mode Request resource path Request parameter information HTTP Agreement and version , Corresponding POST The request method does not contain the request parameter information , The request parameter information is in the request body .
 Insert picture description here For these four parts ,request Objects provide corresponding API Method to get , As follows :

  • Get request method : GET
    String getMethod()
    
  • Get virtual directory ( Project access path ): /request-demo
    String getContextPath()
    
  • obtain URL( Uniform resource locator ): http://localhost:8080/request-demo/req1
    StringBuffer getRequestURL()
    
  • obtain URI( Uniform resource identifiers ): /request-demo/req1
    String getRequestURI()
    
  • Get request parameters (GET The way ): username=lushimeng&password=123
    String getQueryString()
    

After introducing the above methods , Let's use all the above methods through code :

@WebServlet(urlPatterns = "/req1")
public class RequestDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        //  Get request line mode 
        // 1.  Get request method 
        String method = req.getMethod();
        System.out.println(method);  // GET

        // 2.  Get virtual directory ( Project access path ):
        String contextPath = req.getContextPath();
        System.out.println(contextPath);  // /request-demo

        // 3.  obtain URL( Uniform resource locator )
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL.toString());  // http://localhost:8080http://localhost:8080/request-demo/req1

        // 4.  obtain URI( Uniform resource identifiers )
        String requestURI = req.getRequestURI();
        System.out.println(requestURI);  // /request-demo/req1

        // 5.  Get request parameters (GET The way )
        String param = req.getQueryString();
        System.out.println(param);  // username=lushimeng&password=123
    }

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

Start the server , visit http://localhost:8080/request-demo/req1?username=zhangsan&passwrod=123, The results obtained are as follows :
 Insert picture description here

Get request header data

For the data of the request header , The format is key: value as follows :

 Insert picture description here
Therefore, the method to obtain the corresponding value according to the request header name by :

String getHeader(String name)

Next , In the code, if you want to get the version information of the client browser , You can use

@WebServlet(urlPatterns = "/req1")
public class RequestDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        //  How to get the request header : key - value form ,  You can press... In the browser F12 To view the 
                //  How to get the request header : key - value form ,  You can press... In the browser F12 To view the 
        String agent = req.getHeader("User-Agent");
        System.out.println("User-Agent : " + agent);  // User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36
        String connection = req.getHeader("Connection");
        System.out.println("Connection : " + connection);  // Connection : keep-alive
        String host = req.getHeader("Host");
        System.out.println("Host : " + host);  // Host : localhost:8080
        String platform = req.getHeader("sec-ch-ua-platform");
        System.out.println("sec-ch-ua-platform : " + platform);  // sec-ch-ua-platform : "Windows"
    }

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


After restarting the server ,http://localhost:8080/request-demo/req1?username=lushimeng&passwrod=123456, The results obtained are as follows :

 Insert picture description here

Get request body data

Browser sending GET There is no request body when requesting , So we need to change the request mode to POST, The data format in the request body is as follows :
For the data in the request body ,Request Object provides the following two ways to get the data , Namely :

  • Get byte input stream , If the front end sends byte data , For example, file data is transmitted , Use this method
ServletInputStream getInputStream():  This method can get bytes 
  • Get character input stream , If the front end sends plain text data , Use this method
BufferedReader getReader()

Next , You need to think , How to get the content of the request body ?

The specific implementation steps are as follows :

  1. Prepare a page , Add... To the page form Forms , To send post request
  2. stay Servlet Of doPost Method to get the request body data
  3. stay doPost Method used in request Of getReader() perhaps getInputStream() To get
  4. Access test

Test cases

  1. In the project webapp Add a html page , The name is :req.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!-- action:form Request address for form submission  method: Request mode , Designated as post -->
<form action="/request-demo/req1" method="post">
    <input type="text" name="username"><br>
    <input type="text" name="password"><br>
    <input type="checkbox" name="hobby" value="1"> swimming 
    <input type="checkbox" name="hobby" value="2"> Climbing the mountain  <br>
    <input type="submit">

</form>

</body>
</html>

 Insert picture description here

  1. call getReader() perhaps getInputStream() Method , Because at present, the front-end transmits plain text data , So we use getReader() Method to get
@WebServlet(urlPatterns = "/req1")
public class RequestDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
      
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        // 1.  obtain post Request body parameters 
        BufferedReader reader = req.getReader();
        // 2.  Reading data 
        String param = reader.readLine();
        System.out.println(param);   // username=lushimeng&password=123456
    }
}

Be careful
BufferedReader Flow is through request Object to get , When the request is complete request The object will be destroyed ,request After the object is destroyed ,BufferedReader The flow will automatically close , So there is no need to manually close the flow here .

  1. Start the server , Access... Through a browser http://localhost:8080/request-demo/req.html
    4.

Summary

HTTP The request data contains Request line Request header and Request body , For these three parts ,Request Objects provide corresponding API Method to get the corresponding value :

  • Request line
    • getMethod(): Get request method
    • getContextPath(): Get project access path ( Virtual directory )
    • getRequestURL(): Get request URL( Uniform resource locator )
    • getRequestURI(): Get request URI( Uniform resource identifiers )
    • getQueryString(): obtain GET Request parameters for request mode
  • Request header
    • getHeader(String name): Get the corresponding value according to the request header name
  • Request body
    • Be careful : browser-sent POST A request has a request body
    • If it's plain text data :getReader()
    • If it is byte data, such as file data :getInputStream()

General way to get request parameters

Before learning the following , Let's start with two questions :

  • What are request parameters ?
  • What is the relationship between request parameters and request data ?

1. What are request parameters ?

In order to better answer the above two questions , Let's take the example of user login to illustrate

1.1 Want to log in to the website , You need to enter the login page

1.2 Enter your user name and password on the login page

1.3 Submit the user name and password to the background

1.4 Check whether the user name and password are correct in the background

1.5 If correct , Then log in normally , If not , The user name or password is wrong

In the above example , User name and password are actually what we call request parameters .

2. What is request data ?

The request data contains the request line 、 All data of the request header and request body

3. What is the relationship between request parameters and request data ?

3.1 Request parameters are part of the request data

3.2 If it is GET request , The request parameter is on the request line

3.3 If it is POST request , Request parameters are generally in the request body

For the acquisition of request parameters , There are two commonly used :

  • GET The way :
String getQueryString()
  • POST The way :
BufferedReader getReader();

With the above knowledge reserve , Let's implement a requirement :

(1) Send a GET Request and carry the user name , Print to the console after receiving in the background

(2) Send a POST Request and carry the user name , Print to the console after receiving in the background

What you need to pay attention to here is GET Request and POST The way of requesting and receiving parameters is different , The specific implementation code is as follows :

@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    

        String result = req.getQueryString();
        System.out.println(result);

    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        BufferedReader br = req.getReader();
        String result = br.readLine();
        System.out.println(result);
    }
}
  • For the above code , What's the problem ?
     Insert picture description here
  • How to solve the above problem ?
     Insert picture description here Of course , It can also be in doGet Call in doPost, stay doPost Complete the acquisition and printing of parameters in , Another thing to note ,doGet and doPost Methods must exist , You cannot delete any .

GET Request and POST The request gets the request parameters in different ways , How to get the request parameters ?

If you want to achieve , We just need reflection :

GET Request mode and POST The main difference between request methods lies in the different ways of obtaining request parameters , Can you provide a Unified How to get the request parameters , thus Unified doGet and doPost The code inside the method ?

Solution 1 :

@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        // Get request method 
        String method = req.getMethod();
        // Get request parameters 
        String params = "";
        if("GET".equals(method)){
    
            params = req.getQueryString();
        }else if("POST".equals(method)){
    
            BufferedReader reader = req.getReader();
            params = reader.readLine();
        }
        // Print the request parameters to the console 
        System.out.println(params);
      
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        this.doGet(req,resp);
    }
}

Use request Of getMethod() To get the request method , Obtain the request parameter values according to different request methods , In this way, the above problems can be solved , But then everyone Servlet You need to write code like this , It's more difficult to realize , This scheme is not recommended .

Solution 2 :

request Object has encapsulated the above method of obtaining request parameters , also request The method provided is more powerful , In the future, just call request The method provided can , stay request What operations are implemented in the methods of ?

(1) Obtain request parameters according to different request methods , The contents obtained are as follows :
 Insert picture description here (2) Divide the obtained content , The contents are as follows :
 Insert picture description here (3) Split the back-end data , Deposit into a Map Collection :
 Insert picture description here Be careful : Because the value of the parameter may be a , There could be multiple , therefore Map The value of is of type String Array .

Based on the above theory ,request Object provides us with the following methods :

  • Get all parameters Map aggregate
Map<String,String[]> getParameterMap()
  • Get the parameter value according to the name ( Array )
String[] getParameterValues(String name)
  • Get the parameter value according to the name ( Single value )
String getParameter(String name)

Next , We use cases to demonstrate the above three methods :

  1. modify req.html page , Add hobby options , You can choose multiple hobbies at the same time
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/request-demo/req3" method="get">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1">  swimming 
    <input type="checkbox" name="hobby" value="2">  Climbing the mountain  <br>
    <input type="submit">

</form>
</body>
</html>

 Insert picture description here

  1. stay Servlet Get page delivery in code GET/POST Requested parameter value
/** * request  Get request parameters in a common way  */
@WebServlet(urlPatterns = "/req3")
public class RequestDemo3 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        // 1.  Get... For all parameters Map aggregate 
        Map<String, String[]> map = req.getParameterMap();
        Set<String> keys = map.keySet();  //  Get the set of keys 
        for(String key : keys){
    
            System.out.print(key + " : ");
            String[] stringValues = map.get(key);  //  according to key Get the corresponding value
            for(String str : stringValues){
    
                System.out.print(str + " ");
            }
            System.out.println();
        }

        System.out.println("--------------------");
        // 2.  Get the parameter value according to the name ( Array )
        String[] hobbies = req.getParameterValues("hobby");
        for(String hobby : hobbies){
    
            System.out.println(hobby);  // 1, 2
        }

        System.out.println("--------------------");
        // 3.  Get the parameter value according to the name 
        String username = req.getParameter("username");
        System.out.println("username : " + username);  // username : lushimeng
        String password = req.getParameter("password");
        System.out.println("password : " + password);  // password : 123456

    }

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

 Insert picture description here

IDEA Quick creation Servlet

After obtaining the request parameters in a general way , Shielded GET and POST Different request methods and codes , The code can be defined in the following format :

 Insert picture description here

Because of the fixed format , So we can use it IDEA Provide a template to make a Servlet The template of , In this way, we will create it later Servlet It will be more efficient when , How to realize :

(1) According to your own needs , modify Servlet Create template content
 Insert picture description here

(2) Use servlet Template creation Servlet class

 Insert picture description here

The request parameters are garbled in Chinese

Question presentation :

(1) take req.html The request mode of the page is modified to get

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/request-demo/req2" method="get">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1">  swimming 
    <input type="checkbox" name="hobby" value="2">  Climbing the mountain  <br>
    <input type="submit">

</form>
</body>
</html>

(2) stay Servlet Method , And print

/** *  Chinese garbled problem solution  */
@WebServlet("/req2")
public class RequestDemo4 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
       //1.  obtain username
       String username = request.getParameter("username");
       System.out.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}


(3) Start the server , Enter Chinese parameters on the page


 Insert picture description here
(4) View console print content

 Insert picture description here

(5) hold req.html Change the request mode of the page to post, Send the request and Chinese parameters again

 Insert picture description here

(6) View console print content , Still garbled

 Insert picture description here

Through the above case , Will find , Whether it's GET still POST request , If there is Chinese in the sent request parameters , When receiving in the background , There will be the problem of Chinese garbled code . How to solve it ?

POST Request solution

  • Analyze the causes of Chinese garbled code :
    • POST The request parameter is through request Of getReader() To get the data in the stream
    • TOMCAT The encoding used when obtaining the stream is ISO-8859-1
    • ISO-8859-1 The code does not support Chinese , So it's going to be messy
  • Solution
    • The coding format of page setup is UTF-8
    • hold TOMCAT The encoding before obtaining the stream data is set to UTF-8( That is the Tomcat Server default ISO-8859-1 Code to UTF- Encoding set )
    • adopt request.setCharacterEncoding(“UTF-8”) Set encoding ( there UTF-8 It can also be lowercase )

The revised code is :

@WebServlet(urlPatterns = "/req2")
public class RequestDemo2 extends HttpServlet {
    

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        //  Solve the mess : POST getReader()
        // 1.  Set the encoding of the character input stream , The set character set should be consistent with the page 
        req.setCharacterEncoding("UTF-8");
        // 2.  obtain username
        String username = req.getParameter("username");
        System.out.println(username);
    }

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

To resend POST request , You will see the Chinese results displayed normally on the console .
 Insert picture description here

GET Request solution

A question just mentioned is POST Why the requested Chinese garbled code solution is not applicable GET request ?

  • GET The way to get the request parameters is request.getQueryString()
  • POST The way to get the request parameters is request.getReader()
  • request.setCharacterEncoding(“utf-8”) It's settings request Encoding of processing stream
  • getQueryString Method does not get data through stream

therefore GET The request cannot solve the problem of Chinese garbled code by setting the code , That's the question again , How to solve GET The Chinese garbled code of the request ?

  1. First, we need to analyze GET The reason why the request is garbled :
     Insert picture description here

(1) Browser pass HTTP The protocol sends requests and data to the background server (Tomcat)

(2) Browser sending HTTP Chinese data will be processed in the process of URL code

(3) It's going on URL When coding, the page will be used <meta> The label specifies UTF-8 The way to code , Zhang San The result of coding is %E5%BC%A0%E4%B8%89

(4) Background server (Tomcat) Received %E5%BC%A0%E4%B8%89 It will default to ISO-8859-1 Conduct URL decode

(5) Because the format of pre and post coding and decoding is different , It will cause the data obtained in the background to be garbled .

reflection : If you put req.html Page <meta> Labeled charset Attribute change ISO-8859-1, No operation in the background , Can you solve the problem of Chinese garbled code ?

The answer is No , because ISO-8859-1 It does not support Chinese display , So I changed the label charset After attribute , It will cause the Chinese content on the page to be unable to display normally .

After analyzing the above problems , We will find that , Two things we are not familiar with are URL code and URL decode , What is? URL code , What is URL Decoding ?

URL code

We only need to understand this knowledge , The specific coding process is divided into two steps , Namely :

(1) Convert the string to binary by encoding

(2) Each byte is converted to 2 individual 16 Hexadecimal number and add %

Zhang San according to UTF-8 The result of binary conversion is :

1110 0101 1011 1100 1010 0000 1110 0100 1011 1000 1000 1001

In the hexadecimal result of the calculation , Add one... Before every two %, I can get it %E5%BC%A0%E4%B8%89.

stay Java Has provided us with encoding and decoding API Tool classes allow us to encode and decode faster :

code :

java.net.URLEncoder.encode(" What needs to be encoded "," Character set (UTF-8)")

decode :

java.net.URLDecoder.decode(" Content to be decoded "," Character set (UTF-8)")

Next, let's talk about Zhang San To encode and decode

/** * @Author Mr.Lu * @Date 2022/6/18 21:09 * @ClassName URLDemo * @Version 1.0 */
public class URLDemo {
    
    public static void main(String[] args) throws UnsupportedEncodingException {
    
        String name = " Zhang San ";

        // 1. URL code 
        String encode = URLEncoder.encode(name, "UTF-8");  //  It can't be replaced by ISO-8859-1 code , Because the code does not support Chinese characters , So use Unicode Code table coding ( Unified code 、 Wanguo horse yard )
        System.out.println(encode);  // %E5%BC%A0%E4%B8%89

        // 2. URL decode 
        String decode = URLDecoder.decode(encode, "UTF-8");
        System.out.println(decode);  //  Zhang San 

        // 3.  Convert to byte data ,  code 
        byte[] bytes = decode.getBytes();
        for( byte bt : bytes){
    
            System.out.print(bt + " ");  // -27 -68 -96 -28 -72 -119
        }

        // 4.  decode 
        String s = new String(bytes, "UTF-8");
        System.out.println(s);  //  Zhang San 
    }
}

Here we are , We can analyze GET The reason why the Chinese parameters are garbled ,

  • The browser sets the Chinese parameters according to UTF-8 Conduct URL code
  • Tomcat The obtained contents are ISO-8859-1 Of URL decode
  • On the console will appear on the class å¼ ä¸‰ The mess of , The last digit is a space
  1. Clear the reason for the garbled code , Next, we need to find a way to solve \
     The specific implementation steps are :
    
    1. according to ISO-8859-1 Code to get garbled code `å¼ ä¸‰` Corresponding byte array 
    
    2. according to UTF-8 Get the string corresponding to the byte array by encoding 
    
    The implementation code is as follows :
@WebServlet(urlPatterns = "/req2")
public class RequestDemo2 extends HttpServlet {
    

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        // 1.  obtain username
        String username = req.getParameter("username");
        System.out.println(" Before solving the garbled code  : " + username);


        //  The reason for the disorder :tomcat Conduct URL decode , Default character set ISO-8859-1
        // 2.  First encode the garbled data : Convert to byte array 
        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        //  Byte array decoding 
        String targetUserName = new String(bytes, "UTF-8");
// String targetUserName = new String(username.getBytes(StandardCharsets.ISO_8859_1), "UTF-8"); //  The above two sentences can be combined into one sentence 
        System.out.println(" After solving the garbled code  : " + targetUserName);
    }

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


 Insert picture description here Be careful

  • hold request.setCharacterEncoding("UTF-8") After the code is commented out , Will find GET The request parameter garbled solution can also POST The problem of garbled request parameters is also solved
  • Just for POST Generally, there are many request parameters , It's troublesome to solve garbled code in this way , So for POST The request is still recommended to use the method of setting coding .

In addition, it should be noted that Tomcat8.0 after , The GET Ask for trouble shooting , Set the default decoding method as UTF-8

Summary

  1. The solution of Chinese scrambling
  • POST Request and GET If there is Chinese in the requested parameters , Chinese garbled code will appear when receiving data in the background

    GET Request in Tomcat8.0 Later versions will not appear

  • POST The requested solution is : Set the encoding of the input stream

    request.setCharacterEncoding("UTF-8");
     Be careful : The set character set should be consistent with the page 
    
  • General way (GET/POST): You need to decode , Recode

    new String(username.getBytes("ISO-8859-1"),"UTF-8");
    
  1. URL Coding implementation :
  • code :

    URLEncoder.encode(str,"UTF-8");
    
  • decode :

    URLDecoder.decode(s,"ISO-8859-1");
    

Request Request forwarding

  1. Request forwarding (forward): A way to jump resources inside the server .
     Insert picture description here
    (1) The browser sends a request to the server , The corresponding resource in the server A Received request

    (2) resources A After processing the request, send the request to the resource B

    (3) resources B After processing, respond the result to the browser

    (4) Request from resource A To resources B This process is called Request forwarding

  2. Implementation of request forwarding :

    req.getRequestDispatcher(" resources B route ").forward(req,resp);
    
  3. Request to forward shared data between resources : Use Request object , You need to use request Object provides three methods :

  • Store data to request Domain [ Range , Data is stored in request object ] in

    void setAttribute(String name,Object o);
    
  • according to key Get value

    Object getAttribute(String name);
    
  • according to key Delete the key-value pair

    void removeAttribute(String name);
    

For the above needs , The specific implementation steps are :

1. Create a RequestDemo6 class , receive /req6 Request , stay doGet Method to print demo6

2. Create a RequestDemo7 class , receive /req7 Request , stay doGet Method to print demo7

3. stay RequestDemo6 Method to store data , And use req.getRequestDispatcher(“/req7”).forward(req,resp) Forward request

4. Start the test

RequestDemo6 class :

@WebServlet(urlPatterns = "/req6")
public class RequestDemo6 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        System.out.println("demo6...");
        //  Store the data 
        req.setAttribute("msg", " Log information ");

        //  Redirect ,  Pay special attention to resource paths 
        req.getRequestDispatcher("/req7").forward(req, resp);
    }

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

RequestDemo7 class :

@WebServlet(urlPatterns = "/req7")
public class RequestDemo7 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        System.out.println("demo7...");
        //  get data 
        Object msg = req.getAttribute("msg");
        System.out.println(msg);
    }

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

Start the test , visit http://localhost:8080/request-demo/req6, You can see the following on the console :
 Insert picture description here


The characteristics of request forwarding ( To distinguish from redirection )

  • The browser address bar path does not change , Although the backstage from /req6 Forwarding to /req7, But the address of the browser has always been /req6, No change
  • It can only be forwarded to the internal resources of the current server , You cannot access another server by forwarding from one server
  • Only one request , Can be used between forwarding resources request Shared data , Although the backstage from /req6 Forwarding to /req7, But this Only one request

Response object

Request: Use request Object to obtain Request data

Response: Use response Object to Set up The response data
 Insert picture description here Reponse Inheritance system and Request Our inheritance system is also very similar :
 Insert picture description here

Response Introduction to setting response data function

HTTP The response data is divided into three parts , Namely Response line 、 Response head 、 Response body , For the data of these three parts ,respone What methods are provided by the object to set ?

Response line

 Insert picture description here


For response headers , More commonly used is to set the response status code :

void setStatus(int sc);

Response head

 Insert picture description here
Set the response header key value pair :

void setHeader(String name,String value);

Response body

 Insert picture description here


For responders , Is by character 、 Write to the browser in the way of byte output stream ,

Get character output stream :

PrintWriter getWriter();

Get byte output stream

ServletOutputStream getOutputStream();

Respones request redirections

  1. Response Redirect (redirect): A resource jump method .
     Insert picture description here

(1) The browser sends a request to the server , The corresponding resource in the server A Received request

(2) resources A The request cannot be processed at this time , Will give the browser a response 302 The status code + Location An access resource for B The path of

(3) The browser received a response with a status code of 302 Will resend the request to Location The corresponding access address to access resources B

About response status code , Let's first recognize three status codes , The rest will be mastered later :

  • 200 ok Client request successful
  • 404 Not Found The requested resource does not exist
  • 500 Internal Server Error Unexpected error occurred on the server
Status code classification explain
1xx Response —— Temporary status code , The request has been accepted , Tell the client that it should continue the request or ignore it if it has completed
2xx success —— Indicates that the request has been successfully received , Processing completed
3xx Redirect —— Redirect to other places : It allows the client to make another request to complete the whole process .
4xx Client error —— Processing error , The responsibility lies with the client , Such as : The client requested a nonexistent resource , The client is not authorized , No access, etc
5xx Server-side error —— Processing error , The responsibility lies in the service side , Such as : The server threw an exception , Routing error ,HTTP Version does not support etc

Status code :https://cloud.tencent.com/developer/chapter/13553

Status code English description explain
200OK Client request successful , namely Handle a successful , This is the status code we most want to see
302Found Indicates that the requested resource has been moved to by Location Response header given URL, The browser will automatically revisit this page
304Not Modified Tell the client , The resources you requested have been available since the last time , The server has not changed , You can use your local cache directly . Implicit redirection
400Bad Request The client request has Grammar mistakes , Not understood by the server
403Forbidden The server receives the request , however Denial of service , such as : No permission to access related resources
404Not Found The requested resource does not exist , It's usually URL Incorrect input , Or the website resources have been deleted
428Precondition Required The server requires conditional requests , Tell the client to access the resource , Must carry a specific request header
429Too Many Requests Too many requests , You can limit the number of clients requesting a resource , coordination Retry-After( How long can I request ) Use with response headers
431 Request Header Fields Too Large The request head is too big , The server is not willing to process requests , Because its header field is too large . The request can be resubmitted after reducing the size of the request header field .
405Method Not Allowed The request method is wrong , For example, we should use GET Resources in request mode , It was used POST
500Internal Server Error An unexpected error occurred on the server . Something went wrong with the server , Hurry to read the log
503Service Unavailable The server is not ready to process the request , The server has just started , Not initialized yet
511Network Authentication Required The client needs to be authenticated to gain network access

(4) resources B After receiving the request, process it and finally respond to the browser , This whole process is called Redirect

  1. Implementation of redirection :
resp.setStatus(302);
resp.setHeader("location"," resources B Access path of ");

 Insert picture description here

How to use , Let's first look at the demand :

For the above needs , The specific implementation steps are :

1. Create a ResponseDemo1 class , receive /resp1 Request , stay doGet Method to print resp1....

2. Create a ResponseDemo2 class , receive /resp2 Request , stay doGet Method to print resp2....

3. stay ResponseDemo1 The method used in

​ response.setStatus(302);

​ response.setHeader(“Location”,“/request-demo/resp2”) The front end responds to the data

4. Start the test

establish ResponseDemo1 class

/** * @Author Mr.Lu * @Date 2022/6/19 10:00 * @ClassName ResponseDemo1 * @Version 1.0 */
@WebServlet(urlPatterns = "/resp1")
public class ResponseDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        System.out.println("resp1....");
        //  Redirect 
        // 1.  Set response status code 
        resp.setStatus(302);
        // 2.  Set the response header  Location
        String contextPath = req.getContextPath();  //  Get virtual directory ( Project access path ): `/request-demo`
        resp.setHeader("Location", contextPath + "/resp2");
    }

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

establish ResponseDemo2 class

/** * @Author Mr.Lu * @Date 2022/6/19 10:00 * @ClassName ResponseDemo2 * @Version 1.0 */
@WebServlet(urlPatterns = "/resp2")
public class ResponseDemo2 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        System.out.println("resp2...");
    }

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

Start the test visit http://localhost:8080/request-demo/resp1, You can see the following on the console :
 Insert picture description here Although the function has been realized , But from the two lines of code that set redirection , You will find that the address is different except for redirection , Everything else is as like as two peas. , therefore request Object provides us with a simplified way to write :

resposne.sendRedirect("/request-demo/resp2")

improvement ResponseDemo2 class

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        System.out.println("resp1....");
        // Redirect 
        resposne.sendRedirect("/request-demo/resp2");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}

Features of redirection

  • Browser address bar path sending change , When redirecting access , Because it is two requests sent by the browser , So the address will change
  • Resources that can be redirected to any location ( service content 、 The outside can ), Because the first response result contains the path that the browser will jump next time , So this path is a resource that can be located anywhere .
  • Two requests , Cannot be used in more than one resource request Shared data , Because the browser sent two requests , It's two different request object , Can't go through request Object to share data

contrast request redirections and Request forwarding
 Insert picture description here

routing problem

problem 1: The path is not added when forwarding /request-demo And redirection adds , So when exactly do I need to add , When don't you need to add ?

In fact, the basis of judgment is very simple , Just remember the following rules :

  • Browsers use : Need to add virtual directory ( Project access path )
  • Server use : No need to add virtual directory

For forwarding , Because it is carried out on the server side , So you don't need to add a virtual directory

For redirection , The path is ultimately sent by the browser , You need to add a virtual directory .

Here are some common paths :

  • <a href=' route '> // Need to add virtual directory
  • <form action=' route '> // Need to add virtual directory
  • req.getRequestDispatcher(" route ") // No need to add virtual directories
  • resp.sendRedirect(" route ") // Need to add virtual directory

problem 2: In the redirected code ,/request-demo It's fixed coding , If later passed Tomcat The plug-in configures the access path of the project , Then all the places that need to be redirected need to be modified , How to optimize ?
 Insert picture description here We can dynamically get the virtual directory accessed by the project in the code , adopt request Object getContextPath() Method to get the virtual directory , The modified code is as follows :

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        System.out.println("resp1....");

        // Complete redirection in a simplified way 
        // Get virtual directory dynamically 
        String contextPath = request.getContextPath();
        response.sendRedirect(contextPath+"/resp2");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}

Response Response character data

To write character data back to the browser , We need two steps :

  • adopt Response Object to get the character output stream : PrintWriter writer = resp.getWriter();
  • Write data through character output stream : writer.write("aaa");
  1. Returns a simple string aaa
package response;
/** * @Author Mr.Lu * @Date 2022/6/19 10:42 * @ClassName ${NAME} * @Version 1.0 */

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(urlPatterns = "/resp4")
public class ResponseDemo4 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        response.setContentType("text/html;charset=utf-8");  //  This line can be used for uniform settings content-type,  Set the code as utf-8 The way , because ISO-8859-1 The character set does not support Chinese 
        // 1.  Get character output stream 
        PrintWriter writer = response.getWriter();
        writer.write("aaaa");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}

 Insert picture description here

  1. Return to a string of html character string , And can be parsed by the browser
@WebServlet(urlPatterns = "/resp4")
public class ResponseDemo4 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        PrintWriter writer = response.getWriter();
        // content-type, Tell the browser what type of data to return HTML Type data , In this way, the browser will parse HTML label 
        response.setHeader("content-type", "text/html");  //  It will be set uniformly later response.setContentType("text/html;charset=utf-8"); that will do , In this way, the returned data type can be solved and the Chinese can be parsed 
        writer.write("<h1>aaaa</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}

 Insert picture description here == Be careful :== After a request response ,response The object will be destroyed , So don't close the flow manually .

  1. Returns a Chinese string Hello , It should be noted that the code of the response data is set to utf-8
package response;
/** * @Author Mr.Lu * @Date 2022/6/19 10:42 * @ClassName ${NAME} * @Version 1.0 */
@WebServlet(urlPatterns = "/resp4")
public class ResponseDemo4 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        // //  This line can be used for uniform settings content-type,  Set the code as utf-8 The way , because ISO-8859-1 The character set does not support Chinese 
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.write(" How do you do !!!");
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}

 Insert picture description here

Response Response byte data

To write byte data back to the browser , We need two steps :

  • adopt Response Object to get byte output stream :ServletOutputStream outputStream = resp.getOutputStream();

  • Write data through byte output stream : outputStream.write( Bytes of data );

Next , We implement the response character data to practical application through some cases :

  1. Returns a picture file to the browser
@WebServlet(urlPatterns = "/resp5")
public class ResponseDemo5 extends HttpServlet {
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        // 1.  Read the file 
        FileInputStream fis = new FileInputStream("D:\\javaAPI_picture\\5.jpg");

        // 2.  obtain response Byte output stream 
        ServletOutputStream os = response.getOutputStream();  //  The system automatically releases resources 

        // 3.  Completion flow copy
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = fis.read(buffer)) != -1){
    
            os.write(buffer, 0, len);
        }
        
        fis.close();  //  Closed flow 
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        this.doGet(request, response);
    }
}

 Insert picture description here In the above code , For flow copy The code is more complex , So we can use good methods provided by others to simplify code development , The specific steps are :

(1) pom.xml Add dependency

   <dependency><!--  Import IO Flow dependence  -->
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.6</version>
    </dependency>

(2) Call tool class method
 Insert picture description here  Insert picture description here

原网站

版权声明
本文为[Grilled little fat sheep with charcoal...]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/176/202206250922200221.html