Response and Request objects

Tomcat receives an HTTP request from the client and creates a Request object and a Response object respectively for each request

Since the Request object represents an HTTP request, we get the data submitted by the browser and go to the Request object. The response object represents the HTTP response, so we send data to the browser and look for the response object.

What is an HttpServletResponse object?

The HTTP response consists of a status line, entity content, a message header, and an empty line. The HttpServletResponse object encapsulates the information of the HTTP response.

The application of HttpServletResponse

Call the getOutputStream() method to output data to the browser

  • The getOutputStream() method is called to output data to the browser. The getOutputStream() method can use print() or write(). What’s the difference? Let’s try it out. The following code

        // Get the OutputStream
        ServletOutputStream servletOutputStream = response.getOutputStream();

        // Output data to the browser
        servletOutputStream.print("aaaa");
Copy the code
  • Successful output, seems to have no problem.

  • Let’s try exporting Chinese

        // Get the OutputStream
        ServletOutputStream servletOutputStream = response.getOutputStream();

        // Output data to the browser
        servletOutputStream.print("China!);
Copy the code
  • Something is wrong!!

  • Why is there an exception? Print () takes a string. Print () changes “China” to binary. Tomcat uses IOS 8859-1 encoding to convert it. ISO 8859-1 encoding is not supported in China. So there’s an anomaly
  • Let’s look at the write() method, which first prints English data to the browser

		response.getOutputStream().write("aaa".getBytes());

Copy the code
  • There is no problem

  • Try output Chinese data again

	 response.getOutputStream().write("Hello, I am China".getBytes());


Copy the code
  • It doesn’t seem to be a problem.

  • Why does the write() method normally output Chinese to the browser?"Hello, I am China.".getbytes ()This code is inGb2312 is used by default when converted to byte[]And **” hello ah I am China “support GB2312 code **, so it can be displayed normally.
  • However, for generality, the program should use utF-8 encoding. Let’s specify utF-8 encoding when converting a string to a byte array and see what happens.

 	response.getOutputStream().write("Hello, I am China".getBytes("UTF-8"));

Copy the code
  • Ok, successfully scrambled it!!

  • Why does it become garbled? The reason is like this: I am in the server output Chinese is UTF-8 encoding, and the browser uses GBK, GBK want to display UTF-8 Chinese data, not garbled it is strange!

  • In that case, I’ll try changing the browser encoding to UTF-8.

  • The garbled code problem is solved again. But do I have to change the encoding format on the web every time I write a UTF-8 program? That’s obviously impossible.
  • Since the HTTP response has a header that tells the browser what type of data to send back, the HttpServletResponse object should have a corresponding method that tells the browser what the encoding format of the data to send back is
  • So I went to the Servlet API and found a way to set the header

        // Set the header to tell the browser that the encoding I am sending back is UTF-8
        response.setHeader("Content-Type"."text/html; charset=UTF-8");
        
        response.getOutputStream().write("Hello, I am China".getBytes("UTF-8"));



Copy the code
  • The browser automatically replaced the page encoding to UTF-8 when displaying the data, and the garbled characters were resolved

  • Also, in addition to using the HttpServletResponse object to set the header method, I can simulate an HTTP header using HTML tags

  • Here’s the code:


        // Get the servletOutputStream object
        ServletOutputStream servletOutputStream = response.getOutputStream();


        // Use meta tags to simulate HTTP headers that tell the browser the encoding and format of the data to be sent back
        servletOutputStream.write("
      ".getBytes());

        servletOutputStream.write("I am China".getBytes("UTF-8"));


Copy the code
  • The garbled code problem can also be solved

Call the getWriter() method to output data to the browser

  • The getWriter() method, which is a subclass of Writer, can only output character data to the browser, not binary data
  • Use getWriter() to output Chinese data as follows:

        // Get the printWriter object
        PrintWriter printWriter = response.getWriter();
        printWriter.write("Like the blog after reading it!");


Copy the code
  • Happy to hear the visible again, I have a garbled again.

  • Why is it garbled? Since Tomcat is written by foreigners, the default code of Tomcat is ISO 8859-1. When we output Chinese data, Tomcat will encode our data according to ISO 8859-1 code table. Chinese does not support this code table, so there are garbled characters
  • In this case, I set the code, the code is as follows:
		

        // The encoding of ISO 8859-1 was set to UTF-8
        response.setCharacterEncoding("UTF-8");

        // Get the printWriter object
        PrintWriter printWriter = response.getWriter();
        printWriter.write("Like the blog after reading it!");



Copy the code
  • I revisited it. Oh, my God! It looks even messier!

  • Why hasn’t the garble problem been solved? Careful friends will notice that I only set the code table to UTF-8 when converting Chinese, but the browser does not necessarily use UTF-8 code table to display data
  • Ok, let’s look at the browser encoding format, sure enough, the browser uses GB2312 display UTF-8 data, not garbled

  • We have solved this problem in two ways above (using tags to simulate headers and setting headers), and the Servlet provides another method for us

        // Set the browser to use UTF-8 encoding to display data
        response.setContentType("text/html; charset=UTF-8");

Copy the code
  • Ok, let’s go back to the interview

  • Since servlets have so many ways to solve the garble problem, is there one that is easiest? That’s right! SetContentType (“text/ HTML; “) response.setContentType(“text/ HTML; charset=UTF-8″); The response. SetCharacterEncoding (” utf-8 “) things done!

  • Using getWriter() to display Chinese data, you only need one method!


        // Set the browser to use UTF-8 encoding to display data.
        response.setContentType("text/html; charset=UTF-8");

        // Get the printWriter object
        PrintWriter printWriter = response.getWriter();
        printWriter.write("Like the blog after reading it!");


Copy the code


Implementing file download

Downloading resources is also very common in our daily life. How does it work? To be able to download for others, the server should have this resource

  • Now I have an image under my Web site!

  • Since browsers send all requests to servlets, I’ll write a Servlet so that when people visit my Servlet, they can download my image!

  • Java file upload and download are done through THE IO stream, since to download the image, the first must be able to read it


        // The path to the resource
        String path = this.getServletContext().getRealPath("/download/1.png");

        // Read the resource
        FileInputStream fileInputStream = new FileInputStream(path);

        // Get the file name, the path saved on the computer is in \\ form.
        String fileName = path.substring(path.lastIndexOf("\ \") + 1);

Copy the code
  • Tell the browser, I want to download this file

	    // Set the message header to tell the browser I want to download the 1.png image
        response.setHeader("Content-Disposition"."attachment; filename="+fileName);

Copy the code
  • Send the read back to the browser

        // Write the read resource to the browser
        int len = 0;
        byte[] bytes = new byte[1024];
        ServletOutputStream servletOutputStream = response.getOutputStream();

        while ((len = fileInputStream.read(bytes)) > 0) {
            servletOutputStream.write(bytes, 0, len);
        }

        // Close the resource
        servletOutputStream.close();
        fileInputStream.close();
Copy the code
  • When I visit, the browser prompts me to download.

  • It can also be opened successfully!

  • Now the question is, what if the name of my file is Chinese?

  • Let’s access it again and find the name is garbled.

  • In order to solve the filename garbled, we need to carry out URL encoding, the code is as follows:

        response.setHeader("Content-Disposition"."attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));

Copy the code
  • When revisited, the filename garble problem is resolved!


Automatic refresh

Refresh the page at a set time to update resources

  • Let the browser automatically refresh, which is definitely changing the header again.

        // Automatically refresh the page every 3 seconds
        response.setHeader("Refresh"."3");

Copy the code
  • For a better look, let’s add a time value

	response.getWriter().write("time is :" + System.currentTimeMillis());
	
Copy the code
  • The time value changes every three seconds

  • Finish to learn above, seem to have no what to use, oneself get online when who see such thing. Automatic refresh, can realize the page skipping 】
  • We login website, a lot of times will see [login success, 3 seconds after the automatic jump….] In fact, this is done with Refresh.

	  	response.setContentType("text/html; charset=UTF-8");
        response.getWriter().write("Jump to the page after 3 seconds.....");

        // After 3 seconds, I go to the index.jsp page. I set the mapping path of the Web application to /, and the URL does not write the application name
        response.setHeader("Refresh"."3; url='/index.jsp'");


Copy the code
  • Look at the effect


Set the cache

Caching is inherent in browsers

  • When I first accessed index.jsp, the browser made two requests to the server (one for web pages and one for images)

  • When I accessed index.jsp the second time, the browser cached the image! The image is not reloaded, it is taken from the cache.

  • A stock type web page cannot fetch cached data, which is constantly updated. I’m going to disable caching

        // The browser has three headers set to cache, for compatibility! All three headers are set
        response.setDateHeader("Expires", -1);
        response.setHeader("Cache-Control"."no-cache");
        response.setHeader("Pragma"."no-cache");


		// Here for effect
        PrintWriter printWriter = response.getWriter();
        printWriter.print("Hello?" + new Date().toString());


Copy the code
  • Of course, if some data on a page is not up to date, you can improve the performance of your server by caching it

Implementing data compression

There’s a lot of information on a web page, and if you don’t compress the data and send it back to the browser, it’s a traffic hog

  • Now I have an article to output to the browser
        response.setContentType("text/html; charset=UTF-8");

        String ss = "fsdfhsdfhuisdhfusdhfuids" +
                "fsdfdsfsdfsdfdsfdafdsfhsdjfhsdjkfhkjds" +
                "fdsfjdslkfjsldkfjsdlkfjsdkfsdjkff" +
                "fsjdfjdsklfjdsklfjkldsfjlksdjflksdjflkds" +
                "dsjfklsdjflsdjfkldsfkjsdkfjsldkfjsdlfk" +
                "fdsjlkfjdslkfjsdlkfjlkasjflk";
        response.getWriter().write("The original length was:"+ss.getBytes().length+"</br>");

        // Output to the browser
        response.getWriter().write(ss);


Copy the code
  • If you look at it, you can see that the original length is 201

  • What is the principle of compression? We know that getOutputStream() and getWriter() both output data directly to the browser. Now what I’m going to do is instead of sending the data directly to the browser, let me compress it and then send it to the browser. Java provides us with GZIP compression classes
  • Let’s use the GZIP class to compress the data

        The GZIP constructor requires an OutputStream subclass object. To see which object is appropriate, let's take a look at the write() method
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream();

        Write () receives bytes [].
        gzipOutputStream.write();

Copy the code
  • So I’m just passing it a ByteArrayOutputStream on the constructor


        // Since it is byte[], I will give it a ByteArrayOutputStream
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new ByteArrayOutputStream());

Copy the code
  • When you write data to a GZIPOutputStream, you write it to a ByteArrayOutputStream, and then you have to pull it out and write it to the browser, so you can’t give it to GZIPOutputStream as an anonymous inner class, I have to define ByteArrayOutputStream,

        // Create a GZIPOutputStream object and give it ByteArrayOutputStream
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);

        //GZIP compresses data. Data written by GZIP is stored on a byteArrayOutputStream
        gzipOutputStream.write(ss.getBytes());

        //gzipOutputStream has buffering, clean up the buffering, and close the stream
        gzipOutputStream.close();


Copy the code
  • Take the compressed data and write it to the browser
  		// Get the compressed data out
        byte[] bytes = byteArrayOutputStream.toByteArray();

        // Write compressed data to the browser
        response.getOutputStream().write(bytes);

Copy the code
  • Let’s compare the size before compression to the size after compression

  • Yes, the data is compressed, however, why the garbled ah? It’s very simple, since you’re compressing the data, you’re writing to the browser, the browser doesn’t know that you’re compressing the data, it opens the data in the normal way. Of course this makes garbled code! Now I’m going to tell the browser that I’m compressing the data

        // Tell the browser that this is gzip compressed data
        response.setHeader("Content-Encoding"."gzip");

        // Write the compressed data to the browser
        response.getOutputStream().write(bytes);

Copy the code
  • Visit again


Generate random images

Generating random images is very common. We often write captcha when we log in, and that captcha is an image written to the browser via HttpServletResponse.


  • To generate an image, Java provides the BufferedImage class for us to use


        // Create an image in memory with width 80, height 20 and type RGB
        BufferedImage bufferedImage = new BufferedImage(80.20, BufferedImage.TYPE_INT_RGB);

        // Get this image
        Graphics graphics = bufferedImage.getGraphics();

        // Set the color and font for the image
        graphics.setColor(Color.BLUE);
        graphics.setFont(new Font(null, Font.BOLD, 20));

        // Write "12345" on the image. The abscissa is 0 and the ordinate is 20.
        graphics.drawString("12345".0.20);


Copy the code
  • Ok, so now we’ve created an image in memory and said 12345. Next, we’ll write the image to the browser. Write the image to the browser, and Java provides the image stream for us to use

        // To write an image to the browser, tell the browser to send back an image
        response.setHeader("ContentType"."jpeg");
        
        // Java provides an image stream for us to use, which is a utility class
        // Upload the image as JPG and write it to the browser
        ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

Copy the code
  • Let’s take a look and see what it looks like

  • This is ugly. Let’s change the background to white

        // Fill the entire image with white
        graphics.setColor(Color.white);
        graphics.fillRect(0.0.80.20);

Copy the code
  • And if you look at the effect, this is obviously much better

  • Ok, our picture numbers may not be written manually, the numbers should be randomly generated! ** This is easy. Now I’m going to generate a random 7 bit number, and I’m going to do that as follows


    private String makeNum(a) {

        Random random = new Random();

        // This generates a random number between 0 and 7 bits. What if there are less than 7 bits? If we don't have seven bits, we just add seven bits
        int anInt = random.nextInt(9999999);

        // Convert a number to a string
        String num = String.valueOf(anInt);

        // Count the number of digits
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < 7 - num.length(); i++) {
            stringBuffer.append("0");
        }

        return stringBuffer.append(num).toString();
        
    }

Copy the code
  • If you want to generate Chinese, just look for the Chinese mapping table.

Redirect redirect

What is a redirect? Clicking a hyperlink that tells the browser to go to another page is called a redirect. ** notifies the browser to jump, which is important. ** There are two ways to jump from page to page: redirect and forward. I’ll explain when to redirect and what to forward when I finish with the HttpServletRequest object.

  • Let’s use the following redirection of the HttpServletResponse object

        // Redirect to the index.jsp page
        response.sendRedirect("/zhongfucheng/index.jsp");

Copy the code
  • Access Servlet222 in the address bar of your browser

  • Jump to the index.jsp page, and the address bar has changed

  • So what happens with HTTP

  • From the diagram, we see two status codes, one is 302. One is 200. The 302 status code represents a temporary redirect in THE HTTP protocol. For example: I went to the disciplinary committee and said: Give me a leave form, I want to go home. The disciplinary committee told me: I don’t have a leave form here, you go to the counselor. Look back to when I visited Sevlet222: I looked for Servlet222, which told the browser: I don’t have the resource you want, the resource you want is in the index.jsp page, go find it yourself.
  • It’s easy to see that the redirection is done with a 302 status code and a jump address. As a result, we set the HTTP header to redirect

        // Set status code to 302
        response.setStatus(302);

        //HttpServletResponse encapsulates a commonly used status code as a static constant, so SC_MOVED_TEMPORARILY represents 302
        response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);

        // Jump to the index.jsp page
        response.setHeader("Location"."/zhongfucheng/index.jsp");

Copy the code
  • The sendRedirect() method encapsulates setStatus() and setHeader(). This is how setStatus() and setHeader() work

GetWriter and getOutputStream details

  1. GetWriter () and getOutputStream() cannot be called at the same time. An exception occurs if both calls are made
  2. The Servlet program writes data to a ServletOutputStream or PrintWriter object that is retrieved from the response by the Servlet engine, which treats the data as the body of the response message. It is then combined with the response status line and each response header and output to the client.
  3. When the serice() method of the Servlet ends, the Servlet engine checks to see if the output stream object returned by getWriter or getOutputStream has already called the close method. If not, The Servlet engine will call the close method to close the output stream object.

If the article has the wrong place welcome to correct, everybody exchanges with each other. Students who are used to reading technical articles on wechat can follow the wechat public account :Java3y