Servlet Part 4 [common methods and applications of request object]

What is HttpServletRequest

The HttpServletRequest object represents the client's request. When the client accesses the server through the HTTP protocol, all the information in the HTTP request header is encapsulated in this object. Developers can obtain the client's information through the method of this object.

Simply put, to get the browser information, look for the HttpServletRequest object

HttpServletRequest common methods

Get the client browser information

  • The getRequestURL method returns the full URL when the client makes a request.
  • The getRequestURI method returns the resource name part of the request line.
  • The getQueryString method returns the parameter part of the request line.
  • The getPathInfo method returns additional path information in the request URL. The additional path information is the content in the request URL after the path of the Servlet and before the query parameters, which starts with "/".
  • The getRemoteAddr method returns the IP address of the requesting client
  • The getRemoteHost method returns the full hostname of the requesting client
  • The getRemotePort method returns the network port number used by the client
  • The getLocalAddr method returns the IP address of the WEB server.
  • The getLocalName method returns the hostname of the WEB server

Get client request header

  • getHeader method
  • getHeaders method
  • getHeaderNames method

Get client request parameters (data submitted by the client)

  • getParameter method
  • getParameterValues (String name) method
  • getParameterNames method
  • getParameterMap method

HttpServletRequest application

Anti theft chain

What is an anti-theft chain? For example, I now have the latest resources of the pirate king. Those who want to see the pirate king should read it on my website. Now people on other websites see that I have pirate king's resources and want to paste my resources on his own website. So my exclusive resources are robbed by CTRL+C and CTRL+V? The anti theft chain can not be controlled by their CRTL+C and CRTL+V

Let me simulate the scene. Now there is a hyperlink on my home page, pointing to the latest resources of the pirate king

When I click in, I can see the latest resources of the pirate king

Others can copy and paste my address and put it on their web pages

So I'm not worth it. If you want to see my resources, you must click in through my home page.

To achieve this effect, you need to get the Referer header and judge whether the Referer comes from my home page. If it's not from my home page, jump back to my home page.

        //Get where the web page comes from
        String referer = request.getHeader("Referer");

        //If it's not from my home page or directly from the address bar,
        if ( referer == null || !referer.contains("localhost:8080/zhongfucheng/index.jsp") ) {

            //Go back to the home page
            response.sendRedirect("/zhongfucheng/index.jsp");
            return;
        }

        //If you can execute the following statement, it means that you click in from my home page. That's no problem. It will be displayed as usual
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("Luffy did it XXXXxxxxxxxxxxxxxxxx");

First, as expected, others click on my resources from the home page to access the latest resources of my pirate king

Successful access to resources

If I directly enter the address in the browser [the Referer is null at this time], let's have a look

Jump back to the home page. You can't access the pirate king resource

Try again. If someone pastes my resource url and hangs a web address on its web page.

When you click on someone else's web page

Jump back to my home page again.

Form submission data [submit data by post]

<form action="/zhongfucheng/Servlet111" method="post">
    <table>
        <tr>
            <td>user name</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>password</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>Gender</td>
            <td>
                <input type="radio" name="gender" value="male">male
                <input type="radio" name="gender" value="female">female
            </td>
        </tr>
        <tr>
            <td>hobby</td>
            <td>
                <input type="checkbox" name="hobbies" value="Swimming">Swimming
                <input type="checkbox" name="hobbies" value="run">run
                <input type="checkbox" name="hobbies" value="flight">flight
            </td>
        </tr>
        <input type="hidden" name="aaa" value="my name is zhongfucheng">
        <tr>
            <td>Where did your come from</td>
            <td>
                <select name="address">
                    <option value="Guangzhou">Guangzhou</option>
                    <option value="Shenzhen">Shenzhen</option>
                    <option value="Beijing">Beijing</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>detailed description:</td>
            <td>
                <textarea cols="30" rows="2" name="textarea"></textarea>
            </td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit"></td>
            <td><input type="reset" value="Reset"></td>
        </tr>
    </table>

Get the submitted data in Servlet111. The code is as follows

        //Format the request character encoding
        request.setCharacterEncoding("UTF-8");

        //Get the value through the name attribute of html
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String gender = request.getParameter("gender");

        //Check boxes and drop-down boxes have multiple values, and multiple values are obtained
        String[] hobbies = request.getParameterValues("hobbies");
        String[] address = request.getParameterValues("address");

        //Gets the value of the text field
        String description = request.getParameter("textarea");

        //Get the value of the hidden field
        String hiddenValue = request.getParameter("aaa");

        ....various System.out.println().......

Enter data into the form

Servlet 111 gets the data brought from the form, and the last data is brought from the hidden field.

Submit data as hyperlink

Common get methods to submit data include: using hyperlinks and sendRedirect()

The format is as follows:

    sendRedirect("servlet Address of?Parameter name="+Parameter value &"Parameter name="+Parameter value);

Let's use it to bring data to the browser through hyperlinks

     <a href="/zhongfucheng/Servlet111?username=xxx">Use hyperlinks to bring data to the browser</a>

Receive data at servlet 111

        //Receive the value with username as the parameter name
        String username = request.getParameter("username");
        System.out.println(username);

Pay attention to the lower left corner of the browser

The server successfully received the data sent by the browser

In addition, the transmission data plaintext appears on the address bar of the browser

sendRedirect() is similar to hyperlinks and will not be repeated here

Solve the problem of Chinese garbled code

Careful friends will find that when I get the form data, I have this code request.setCharacterEncoding("UTF-8");, What would happen without this code? Let's see.

Fill in the data again

Check the submitted data on the server. All Chinese data are garbled

Here, let's analyze the causes of garbled code. I have introduced in the previous blog that the default code of Tomcat server is ISO 8859-1, while the browser uses UTF-8 code. The Chinese data of the browser is submitted to the server. Tomcat encodes the Chinese data in ISO 8859-1. When I read the data in the Servlet, of course, I get the garbled code. I set the request code to UTF-8, and the random code is solved.

Next, use the get method to transfer Chinese data, and change the form method to get

When we visited, there was garbled code again!


So I try to set the request object to UTF-8 in the above way

        request.setCharacterEncoding("UTF-8");
        String name = request.getParameter("name");

The result is still garbled. Why? I have clearly set the code to UTF-8. According to the post mode, the problem of garbled code has been solved!. Let's take a look at the difference between get and post? Why does the post method set the request code to solve the problem of garbled code, but the get method can't.

First, let's take a look at how the post method passes parameters. When we click the submit button, the data is encapsulated in the Form Data, and the entity body is brought in the http request [the transmitted data is called the entity body]. Since the request object encapsulates the http request, the request object can parse the sent data, so we can solve the problem of garbled code by setting the code to UTF-8.

The get method is different. Its data is brought from the message line and is not encapsulated in the request object, so it is invalid to use request to set the encoding.

It is not difficult to solve the problem of garbled code in get mode. Since we know that the default code of Tomcat is ISO 8859-1, the get mode must be coded with ISO 8859-1 when it is brought to the browser from the message body.

        //At this time, the data obtained is a string encoded by ISO 8859-1, which is garbled
        String name = request.getParameter("username");

        //The original data is obtained by reverse checking ISO 8859-1
        byte[] bytes = name.getBytes("ISO8859-1");

        //Through the original data, set the correct code table and construct the string
        String value = new String(bytes, "UTF-8");

The above code is difficult to understand. Let me draw a picture to illustrate:

After our manual conversion, let's visit it again

OK, the problem of garbled code has been solved successfully.

In addition to manual conversion, the get method can also change the configuration of Tomcat server to solve garbled code, but it is not recommended, which is not flexible. “

We all know that the default encoding of Tomcat is ISO 8859-1. If the encoding is changed to UTF-8 under the configuration of Tomcat server, the problem of garbled code caused by the server when parsing data can be solved

Add URIEncoding = "UTF-8" to the Connector of port 8080, and set the code of Tomcat when accessing the port to UTF-8, so as to solve the problem of garbled code. This modification is based on UTF-8 coding

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="utf-8"/>

After the code is set, no manual conversion is performed, and the data is successfully obtained


Of course, there is another way to change the server code. Set the code when Tomcat accesses the port to the page code, which changes with the page code

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" useBodyEncodingForURI="true" />

Set the encoding to UTF-8

        request.setCharacterEncoding("UTF-8");
        String name = request.getParameter("name");

Visit again

Handwritten hyperlinks with Chinese parameters need URL rewriting, which will be mentioned in the JSP blog

Summary:

  • The post method directly changes the code of the request object
  • The get method requires manual code conversion
  • The get method can also modify the code of the Tomcat server. It is not recommended because it depends too much on the server!
  • Use post if you can submit data

Realize forwarding

As mentioned earlier, sendRedirect() of response can realize redirection. The function is page Jump. The function of forwarding is page Jump by using getRequestDispatcher.forward(request,response) of request. The function is also page Jump. What's the difference between them? Let me talk about Forwarding first

The code is shown below

        //Get the requestDispatcher object and jump to index.jsp
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.jsp");

        //Call forward() of the requestDispatcher object to forward and pass in the request and response methods
        requestDispatcher.forward(request, response);

Accessing Servlet111

As mentioned above, you can add parameters at the end of the resource to submit data to the server through sendRedirect(). Can forwarding submit data to the server?

The answer is obviously yes, and this method is used very frequently

When talking about ServletContext, I once said that ServletContext can be used to realize communication between servlets, and ServletContext can also be called domain object. Request can also be called domain object, but the domain of ServletContext is the whole web application, and the domain of request only represents one http request

Next, let's use request to realize the communication between servlets, Servlet111 code

        //Save the zhongfucheng value with username as the keyword
        request.setAttribute("username", "zhongfucheng");

        //Get requestDispatcher object
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/Servlet222");

        //Call forward() of the requestDispatcher object to forward and pass in the request and response methods
        requestDispatcher.forward(request, response);

Servlet222 code

        //Gets the value stored in the request object
        String userName = (String) request.getAttribute("username");

        //Output the value in the browser
        response.getWriter().write("i am :"+userName);

Visit Servlet111 to see the effect

As shown in the figure above, servlet 222 successfully obtains the data stored in servlet 111 by the request object.

Now the problem comes again. We can use ServletContext and request to realize the communication between servlets, so which one do we use? General principle: if you can use request, use request as much as possible. Because ServletContext represents the whole web application, using ServletContext will consume a lot of resources, and the request object will end with the end of the request, and the resources will disappear The communication between servlets using the request domain is very frequent in development.

Forwarding sequence diagram

Details of request forwarding

If part of the content written in the Servlet program has been actually transmitted to the client before calling the forward method, the forward method will throw an IllegalStateException. That is, do not write data to the browser before forwarding

Let's see if there are really exceptions.

        OutputStream outputStream = response.getOutputStream();
        outputStream.write("--------------------------------------------".getBytes());

        //Turn off the flow and make sure the data is in the browser
        outputStream.close();
        
        //Jump
        request.getRequestDispatcher("/Foot").forward(request, response);

When accessing, you see that the browser can output data, and Tomcat throws an exception in the background


If content is written to the buffer of the Servlet engine before calling the forward method, the forward method can be executed normally as long as the content written to the buffer has not been actually output to the client, and the content originally written to the output buffer will be cleared. However, the response header field information written to the HttpServletResponse object remains valid.

The difference between forwarding and redirection

The actual location is different, and the address bar is different

Forwarding occurs on the server

  • Forwarding is performed by the server. Careful friends will find that the address bar of the browser does not change during forwarding. When I visit Servlet111, even if I jump to the page of Servlet222, the address of the browser is Servlet111. That is to say, the browser does not know the action of the jump, and forwarding is transparent to the browser. Through the above We can also find that forwarding is only an http request, and the request and response objects are the same in a forwarding. This also explains why request can be used as a domain object for communication between servlets.

Redirection occurs in the browser

  • Redirection is performed by the browser. When redirection is performed, the address of the browser will change. It was introduced that the principle of redirection is realized by the combination of response status code and Location header. This is a page Jump performed by the browser. Redirection will send two http requests. The request domain object is invalid because it is not the same A request object

Different usage

Many people don't know how to write the resource address when forwarding and redirection. Sometimes you need to write the application name, and sometimes you don't need to write the application name. It's easy to confuse people. Remember one principle: write the resource name directly for the server, and write the application name for the browser

  • request.getRequestDispatcher("/ resource name URI").forward(request,response)
    During forwarding, "/" represents the root directory of the application [zhongfucheng]
  • response.send("/web application / resource name URI");
    During redirection, "/" represents the webapps directory

The range of URL s that can go to is different

  • Forwarding is a server jump that can only go to the resources of the current web application
  • Redirection is a browser jump that can go to any resource

Different types of data are passed

  • The forwarded request object can transfer various types of data, including objects
  • Redirection can only pass strings

The jump time is different

  • When forwarding: it will jump immediately when the jump statement is executed
  • Redirection: jump only after the entire page is executed

Which is used for forwarding and redirection?

According to the above description, the difference between forwarding and redirection can also be easily summarized. Forwarding takes the parameters of the request before forwarding. Redirection is a new request.

Typical application scenarios:

  1. Forward: access the Servlet to process the business logic, and then forward to the jsp to display the processing results. The URL in the browser remains unchanged
  2. Redirect: submit the form and redirect to another jsp after successful processing to prevent repeated submission of the form and change of the URL in the browser

RequestDispatcher again

The RequestDispatcher object can call forward() to forward, as mentioned above. RequestDispatcher also has another method, include(), which can implement inclusion. What's the use of this method?

When we write a web page, the head and tail of the general web page do not need to be changed. If we use servlets to output headers and tails in multiple places, we need to rewrite the code. Using the include() method of RequestDispatcher can achieve the effect of including net header and net tail.

Let's operate it! Now I have a Servlet at the head and tail

Use Servlet111 to include the header and tail

        request.getRequestDispatcher("/Head").include(request, response);

        response.getWriter().write("--------------------------------------------");

        request.getRequestDispatcher("/Foot").include(request, response);

Visit Servlet111 and successfully include the header and tail

Keywords: servlet request

Added by jahstarr on Sat, 23 Oct 2021 11:38:07 +0300