20. Introduction to Servlet - introduction and use of response

20. Introduction to Servlet - introduction and use of response

Response overview

In the previous chapters, we have already known the relevant functions of the resquest request, so let's continue to understand the response response.

8cc53256cecf8aa3acb5ceb7fa54f619.png
image-20210108214841273

Overview of HttpServletResponse

In the Servlet API, a HttpServletResponse interface (parameters of doGet, doPost methods) is defined, which inherits from the ServletResponse interface and is specially used to encapsulate HTTP response messages. Since the HTTP response message is divided into three parts: response line, response header, and response body, the methods for sending response status code, response header, and response body to the client are defined in the HttpServletResponse interface

effect

  • The three parts of the operation response (response line, response header, response body)

summary

  1. Response represents the response object. The prototype is HttpServletResponse, created by the server, and there are doGet()/doPost() methods in the form of formal parameters

  2. The role of Response

  • The three parts of the operation response (line, header, body)

Response sets the response status code (operation response line)

When the Servlet returns the response information to the browser, you can set the response status code returned to the browser.

For example:

HTTP/1.1 200

You can use the setStatus(int sc) method to set the response status code:

d48e4c98e8a8d33a91d5324d4aab0584.png

img/

The commonly used status codes are:

200: success

302: Redirect

304: access cache

404: Client Error

500: Server Error

Let's write a Demo to demonstrate it.

1. Create a demo Servlet program and set the response status code 403

037a581640f5255ecb8c77bc8c4f6c0f.png

image-20210108220708037
@WebServlet("/ResponseDemo1")
public class ResponseDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("访问 ResponseDemo1 ....");
        //设置响应状态码: 403 forbidden
        response.setStatus(403);
    }
}

2. Test access on the browser

c77e04efcc7a56860f66d67e97fead67.png

image-20210108220811810

3. Summary

  1. Set API: response.setStatus(int code);

  2. Generally, no setting is required, maybe 302 redirection needs to be set

  3. Common Response Status Codes

  • 200 successful

  • 302 redirect

  • 304 read cache

  • 404 client error

  • 500 server error

Response sets the refresh response header to perform timing jump (operation response header)

We have learned how to use Response to set the response status code above, so let's operate the response header.

1. API introduction for manipulating response headers

Response header: is the server instructs the browser what to do

A key corresponds to a value

8676437153927e0387f2f10d4d853e2f.png

One key corresponds to multiple values

59563cd9797e0767ac92282991b5003c.png

The method of concern: setHeader(String name,String value);

Common response headers

Refresh: timing jump (eg: the server tells the browser to jump to Baidu after 5s)

Location: redirection address (eg: the server tells the browser to jump to xxx)

Content-Disposition: Tell the browser to download

Content-Type: Set the MIME type of the response content (the server tells the browser the type of content)

Let's demonstrate how Refresh performs timing jumps.

2. Create a demo Servlet program and set the response header to jump regularly

9a52a57a52684f6468d7f96de1446c2f.png

image-20210108223112151
@WebServlet("/ResponseDemo2")
public class ResponseDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //目标: 让浏览器在访问ResponseDemo2后三秒,跳转到百度首页
        System.out.println("ResponseDemo2收到了请求。。。");
        //通过"Refresh"响应头
        response.setHeader("Refresh","3;url=https://www.baidu.com");
    }
}

3. Test access on the browser

f88b2916ec54173a9ae99ed6d2c30c34.png

image-20210108224213961

After waiting for 3 seconds, it will automatically jump to Baidu, as follows:

203fd7ce9648ce308dd7fb71dd74da4e.png

image-20210108224233411

Response initiates a redirect (operation response header)

Above we have realized the timing jump by setting the response header, so let's look at the redirection next.

1. Response sets the Location response header for redirection (immediate jump)

First create a Servlet program to demonstrate redirection, as follows:

fe33a07eb40694be39f50499ea9f0e8b.png

image-20210108225507845
@WebServlet("/ResponseDemo3")
public class ResponseDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ResponseDemo3收到了一个请求...");
        //目标1:浏览器访问ResponseDemo3,会跳转到百度首页
        //重定向跳转的步骤:1. 设置响应状态码为302  2. 设置响应头Location的值为要跳转到的地址
        response.setStatus(302);
        response.setHeader("Location","https://www.baidu.com");
    }
}

2. Browser test access, found that the browser is successful and immediately jumps to Baidu

Visit http://localhost:8080/ResponseDemo3

43191cdb347ad81de0ee67baee7ad1f8.png

image-20210108225751120

In this test, we can make sure that redirects can be forwarded to resources outside the project. So let's forward it to the resources in the project to see.

3. Set redirection to resources in the project

3.1 Create an index.html under WEB-INF

b3f875418e4025b160b6d4cc5fc0edb8.png

image-20210108230052784

3.2 Set redirection to the index.html in the Servlet, as follows:

1745652f83355573c310bc103ecc1ea6.png

image-20210108231529080
@WebServlet("/ResponseDemo3")
public class ResponseDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ResponseDemo3收到了一个请求...");
        //目标1:浏览器访问ResponseDemo3,会跳转到百度首页
        //重定向跳转的步骤:1. 设置响应状态码为302  2. 设置响应头Location的值为要跳转到的地址
//        response.setStatus(302);
//        response.setHeader("Location","https://www.baidu.com");

        //目标2:浏览器访问ResponseDemo3,会跳转到本项目的index.html页面
        response.setStatus(302);
        response.setHeader("Location","/index.html"); // 路径设置: /项目部署路径/文件在webapp下的路径
    }
}

Use a browser to access http://localhost:8080/ResponseDemo3 as follows:

8c56021e6ce73b0a0cfdaf9cc847875e.png

image-20210108231635621

So can I access the resources in WEB-INF?

3.3 Attempt to redirect to resources in WEB-INF

1b80ee3c5b36eae2b745e31da1a410fd.png

image-20210108231939579

It can be seen that the browser cannot access the resources under WEB-INF, so it cannot be redirected to.

3.4 Shorthand redirection using sendRedirect

In the above, since we redirect to set the response code or set the request header, is there a shorthand method? Of course there is, see below.

81954971877d6e20a9aa6cf83e5f936f.png

image-20210108232209845
// 重定向的简写方法
response.sendRedirect("/index.html");

Test it in a browser, as follows:

b2598b19aa343ac9e67f0bcb5f3ce417.png

image-20210108232249318

It can be seen that the effect of redirection can be achieved, so we just need to remember this way of writing.

4. Summary

0b66dd8ca6ac1abaf40e690d8397b859.png

img/
  1. Redirects cause the browser to make two requests

  2. The redirected address bar path changes

  3. Write the absolute path for the redirected path (with domain name/ip address, if it is in the same project, the domain name/ip address can be omitted)

  4. The redirected path can be inside the project or outside the project (eg: Baidu)

  5. Redirects cannot redirect to resources under WEB-INF

  6. Store the data in the request, redirection is not available

//方式一: 重定向
//1.设置状态码
//response.setStatus(302);
//2.设置重定向的路径(绝对路径,带域名/ip地址的,如果是同一个项目里面的,域名/ip地址可以省略)
//response.setHeader("Location","https://www.baidu.com");
//response.setHeader("Location","/index.html");

//方式二:  直接调用sendRedirect方法, 内部封装了上面两行
response.sendRedirect("/index.html");
  • redirect

response.sendRedirect("重定向的路径");

Comparison of redirection and request forwarding

f4877fdc79e94a51d7b6bbf98e62e7bc.png

1. Features of redirection:

  1. The redirection jump is initiated by the browser, and the browser will initiate two requests during this process

  2. Redirection jumps can jump to resources of any server, but cannot jump to resources in WEB-INF

  3. Redirect jumps cannot be used with request domain objects

  4. The address in the browser's address bar will become the redirected path

2. Features of request forwarding:

1. 请求转发的跳转是由服务器发起的,在这个过程中浏览器只会发起一次请求
2. 请求转发只能跳转到本项目的资源,但是可以跳转到WEB-INF中的资源
3. 请求转发可以和request域对象一起使用

Use the character output stream of Response to output the text content of the response body to the browser (operation response body)

1. API for manipulating the response body

ca1bd508a129048d71336b38eb41fa29.png

Page output can only be achieved using one of the streams, and the two streams are mutually exclusive.

General usage:

  • If you are outputting text content to the browser, then you need to output characters to the browser, usegetWriter()

  • If it is to download resources such as pictures, then you need to output the byte stream to the browser, usegetOutputStream()

Let's first demonstrate the situation of outputting text content.

2. Use getWriter() to output text content to the browser

2.1 The response.getWriter().writer() method can only output strings. If it outputs int, float, etc., there will be problems

71f27ab0071fcaccbe9964650e49a623.png

image-20210109085839072
@WebServlet("/ResponseDemo4")
public class ResponseDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //要向浏览器输出响应体的信息,需要通过流来进行操作
        //第一种:字符串,输出文本内容
        PrintWriter writer = response.getWriter();
        //使用字符流往浏览器输出文本
        //1. writer()方法,只能输出字符串,如果输出int、float等等类型的话,则会有问题
        writer.write("hello world");
    }
}

If the int and float types are output, an error will be reported as follows:

60a0c78541470009d40f5a733328e18b.png

image-20210109085940913

It can be seen that the numbers cannot be displayed normally, so what is the need to display the numbers? At this time, it is generally output as a string, as follows:

685e2e8e37b843cedce4f21f292b2b11.png

image-20210109090049756

But if you don't want to do this, what can you do if you want to directly output int, float, etc.? writer.print()method can be used .

2.2 The response.getWriter().print() method can output numbers and strings

d43dcf4b86c401e0541bd2c57063e0a8.png

image-20210109092911409
//2. print()方法,可以输出数字、字符串
writer.print(123456);

It can be seen that using print()the method can indeed output numbers, but we generally only need to remember to use writer()the method to output strings.

2.3 Output Chinese character strings, garbled characters appear

It is possible to output English strings and numbers above, but when we try to output Chinese content, there will be garbled characters, as follows:

f6c24090067a5e909b2b91eea8c36bf7.png

image-20210109093255116

So why there are garbled characters, of course, it is caused by inconsistent encoding formats. So let's take a look at how to solve the garbled problem.

3. Solve the problem of Chinese response garbled characters

The problem of Chinese garbled characters is caused by the inconsistency between the encoding format of the server and the encoding format of the browser. Then we only need to set the encoding format of the server to UTF8, and then inform the browser to also set the encoding format to UTF8.

So what if the browser is notified to set the UTF8 encoding format? It can be set as follows when responding:

  • Solve the problem of character stream output Chinese garbled characters

response.setContentType("text/html;charset=utf-8");
/*
 * 这句代码底层做了什么?
 * 1. 设置服务器响应的字符集为UTF-8
 * 2. 设置Content-Type响应头的信息为 "text/html;charset=UTF-8"
 *    让浏览器知道了服务器的响应字符集UTF-8,那么浏览器也会使用UTF-8解码
 */

3.1 Demonstration of solving the problem of outputting Chinese garbled characters

5c300f5595296ce850f4b4418b7c2e94.png

image-20210109094414469
@WebServlet("/ResponseDemo4")
public class ResponseDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决响应中文乱码
        response.setContentType("text/html;charset=utf-8");

        //要向浏览器输出响应体的信息,需要通过流来进行操作
        //第一种:字符串,输出文本内容
        PrintWriter writer = response.getWriter();
        //使用字符流往浏览器输出文本
        //1. writer()方法,只能输出字符串,如果输出int、float等等类型的话,则会有问题
        writer.write("你好,世界...");

        //2. print()方法,可以输出数字、字符串
//        writer.print(123456);
    }
}

3.2 Shortcuts for setting the response encoding format

Although it is only one line of code to solve the Chinese garbled characters in the response, it is quite troublesome to remember every time. So we can set it as a shortcut to enter.

File | Settings | Editor | Live Templates

6d192c623212b9fa5937e3efe34e46ca.png

image-20210109094658303

95699273e39e562cc175555e72b1eb8c.png

image-20210109094926227
//解决响应中文乱码
response.setContentType("text/html;charset=utf-8");

The test results are as follows:

d102337eb473ab797d04b0e4a749399b.png

image-20210109094950444

08c28008c2776480888fee88139c2592.png

image-20210109095004275

Use Response's byte stream getOutputStream() to output image content to the browser (operation response body)

Above we have implemented the output of the string content to the browser, so of course we also need to consider how to output the image content to the browser.

First, let's take a look at how the default DefaultServlet handles static resources.

DefaultServlet handles static resources

1. Copy a picture to the webapp directory

b2d3796fd71b413643b4b7441dc80a1d.png

image-20210109101643743

2. Start the tomcat service and use the project path to access image resources

65ec94186c1f4f90e0151f21c5b1c443.png

image-20210109101820588

So if you write a Servlet program yourself, how to realize this function?

Write your own Servlet and use getOutputStream() to output image resources to the browser

681320572d17dab4b6adf3ee1526caea.png

image-20210109102247476
@WebServlet("/ResponseDemo5")
public class ResponseDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 读取b.jpg图片,将其转换成字节输入流,使用ServletContext
        ServletContext servletContext = getServletContext();
        InputStream is = servletContext.getResourceAsStream("1.jpeg");

        //2. 使用字节输出流,将is中的字节都输出到浏览器
        //2.1 获取响应字节流
        ServletOutputStream os = response.getOutputStream();
        //2.2 读取文件输入流 拷贝到 响应输出字节流
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = is.read(buffer)) != -1){
            os.write(buffer,0,len);
        }

        //3.关闭流
        os.close();
        is.close();
    }
}

In the above code, we have achieved the effect of outputting the image resource to the browser, but we can find it.

Every time we operate a byte stream, we have to write a string of byte stream buffers to copy to another output stream, which is cumbersome:

//2.2 读取文件输入流 拷贝到 响应输出字节流
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = is.read(buffer)) != -1){
            os.write(buffer,0,len);
        }

Is there an easier way? Of course there is, that is, it can be encapsulated as a public method, and this public method has been provided by a third party, and we can use it directly.

The use of IO stream tools: Simplify the copy operation of byte streams

  • Introduce the jar package of commons-io

  • Use commons-io to simplify the copy operation of byte stream

1. Use Maven to import the jar package dependencies of commons-io

1.1 Visit the Maven warehouse and search for the dependencies of commons-io

Visit https://mvnrepository.com and search for commons-io as follows:

5fcf11cdf5bb64311bb11a221264abd5.png

image-20210109102853302

125a4f92bf16e94ee9faff17482735f4.png

image-20210109103030512

afb56b7be8a1820d2e701a46fe9c261e.png

image-20210109103057156
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

1.2 Import commons-io coordinate dependencies in the pom.xml of the project

da7104d8670fd643172d95388ee78533.png

image-20210109103247691
<!-- 导入 commons-io       -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

2. Use the IOUtils.copy(is,os); method in commons-io to copy the stream

023c1f905a3d653d308bd0963fd1a6a8.png

image-20210109103429361

c6c97296f33a991f77a7fb2ba6fc167e.png

image-20210109103529178
import org.apache.commons.io.IOUtils;

//2.2 使用 commons-io 中的 IOUtils.copy(is,os); 方法来拷贝流
IOUtils.copy(is, os);

3. View the source code of IOUtils.copy(is, os)

16dde66bf46e3a02a35cc60da2f93e99.png

image-20210109103717733

f16f690ea99e065e3eaa9f353dbc220c.png

image-20210109103730824

It can be seen that, in fact, this copy method also copies the byte stream, but the package is better, which is convenient for all of us to use.

Summary of responses

  1. Set the response status code: setStatus()

  2. Set the response header: setHeader(name,value)

    1. The refresh response header is used to jump to a certain page after a few seconds

    2. location response header, used to redirect to a certain page

  3. Redirection writing: sendRedirect(address)

  4. Set the content of the response body

    1. response.getOutputStream() gets the byte output stream

    2. response.getWriter() gets the character output stream

    3. writer.write()/print() output string

    4. Solve the Chinese garbled characters of the response data: response.setContentType("text/html;charset=UTF-8")

    5. Output text content using a character output stream

    6. output file using byte output stream

  5. Use the framework of IO stream to read and write

Guess you like

Origin blog.csdn.net/u012887259/article/details/121219917
Recommended