深度好文之Servlet技术详解(五)HttpServletResponse对象

2年前 (2022) 程序员胖胖胖虎阿
154 0 0

目录

一.设置响应类型

二.设置字符型响应

三.设置字节型响应

四.设置响应编码

1.中文乱码原理

2.设置响应编码有两种方式

五.在响应中添加附加信息

1.重定向响应

2.重定向响应案例

 3.文件下载

(1)下载

(2)解决文件名中文乱码问题


HttpServletResponse
对象代表服务器的响应。这个对象中封装了响应客户端浏览器的流对象,以及向客户端浏览器响应的响应头、
响应数据、响应状态码等信息。

一.设置响应类型

resp.setContentType("MIME")
该方法可通过
MIME-Type
设置响应类型。
默认是text/html,上篇文章最后一个语言的示例中有用到这个函数,那里设置的是text/html,虽然我们传递的是普通文本,但是超文本也包括普通文本,所以客户端浏览器也可以解析出来。
深度好文之Servlet技术详解(五)HttpServletResponse对象

深度好文之Servlet技术详解(五)HttpServletResponse对象

二.设置字符型响应

常见的字符型响应类型:
resp.setContentType("text/html")
设置响应类型为文本型,内容含有
html
字符串,是默认的响应类型 。
resp.setContentType("text/plain")
设置响应类型为文本型,内容是普通文本。
resp.setContentType("application/json")
设置响应类型为
JSON
格式的字符串。
ResponseCharacterServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置响应类型,默认是text/html
        resp.setContentType("text/plain");
        PrintWriter pw=resp.getWriter();
        pw.println("<!DOCTYPE html>");
        pw.println("<html lang=en>");
        pw.println("<head>");
        pw.println("<meta charset=UTF-8>");
        pw.println("<title>Document</title>");
        pw.println("</head>");
        pw.println("<body>");
        pw.println("<font color=blue>hello world!</font>");
        pw.println("</body>");
    }
}

配置web.xml:

    <servlet>
        <servlet-name>ResponseCharacterServlet</servlet-name>
        <servlet-class>com.first.servlet.ResponseCharacterServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ResponseCharacterServlet</servlet-name>
        <url-pattern>/character.do</url-pattern>
    </servlet-mapping>

输出:

默认情况

深度好文之Servlet技术详解(五)HttpServletResponse对象

 查看F12,己得先打开或者打开后再刷新页面,为的是抓取数据

可看到response header中没有Context Type

深度好文之Servlet技术详解(五)HttpServletResponse对象

ContentType设置为text/plain,结果如下:

深度好文之Servlet技术详解(五)HttpServletResponse对象

三.设置字节型响应

常见的字节型响应:
resp.setContentType("image/jpeg")
设置响应类型为图片类型,图片类型为
jpeg

jpg
格式。
resp.setContentType("image/gif")
设置响应类型为图片类型,图片类型为
gif
格式。
ResponseByteServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.File;

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //给定读取响应图片的路径
        File file=new File("d:/heat.jpg");
        //创建读取图片的IO流对象
        InputStream is=new FileInputStream(file);
        //图片缓冲区,字节数组
        byte[] buff=new byte[is.available()];
        //读入buff数组中
        is.read(buff);

        //设置响应类型
        resp.setContentType("image/jpeg");
        //获取字节输出流对象
        OutputStream os=resp.getOutputStream();
        //从buff数组中通过os向客户端输出
        os.write(buff);
        os.flush();
        os.close();
    }
}

 设置web.xml:

    <servlet>
        <servlet-name>ResponseByteServlet</servlet-name>
        <servlet-class>com.first.servlet.ResponseByteServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ResponseByteServlet</servlet-name>
        <url-pattern>/byte.do</url-pattern>
    </servlet-mapping>

输出:

深度好文之Servlet技术详解(五)HttpServletResponse对象

四.设置响应编码

1.中文乱码原理

深度好文之Servlet技术详解(五)HttpServletResponse对象

客户端浏览器请求(汉字)以字节的形式发送到服务器端tomcat,tomcat接收请求信息,将请求信息由字节转换为字符,默认编码方式为ISO-8859-1,所以此时发生了乱码;服务器端tomcat将响应信息由字符转换为字节传输到客户端浏览器,默认编码方式为ISO-8859-1,所以此时又发生了乱码。

2.设置响应编码有两种方式

  • 1 response.setContentType("text/html; charset=UTF-8");
  • 2 response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8"); (推荐使用)
分号前面是类型,分号后面是编码。
不仅发送到浏览器的内容会使用
UTF-8
编码,而且还通知浏览器使用
UTF-8
编码方式进行显示。所以总能正常显示中文 。
即既告诉tomcat用什么编码方式进行字符到字节的转换,又告诉客户端浏览器用什么编码方式进行字节到字符的转换。
response.setCharacterEncoding("utf-8");
仅仅是发送的浏览器的内容是
UTF-8
编码的,至于浏览器是用哪种编码方式显示不管。 所以当浏览器的显示编码方式不是
UTF-8
的时
候,就会看到乱码,需要手动指定浏览器编码。

如果服务端为客户端产生的响应是字符型的响应且响应内容中含有汉字,这时候容易出现乱码,这时候需要通过设置响应编码的方式解决乱码问题。

如果服务端为客户端产生的响应是字节型的响应,不需要设置响应编码,因为相应编码是针对字符的设置。

以上面字符型响应的例子稍加改造:

深度好文之Servlet技术详解(五)HttpServletResponse对象

输出:

可见中文没有乱码

深度好文之Servlet技术详解(五)HttpServletResponse对象

五.在响应中添加附加信息

1.重定向响应

深度好文之Servlet技术详解(五)HttpServletResponse对象

response.sendRedirect(URL
地址
)
重定向响应会在响应头中添加一个
Location

key
对应的
value
是给定的
URL
。客户端浏览器在解析响应头后自动向
Location
中的
URL
发送请求。
重定向响应特点:
  • 重定向会产生两次请求两次响应。
  • 重定向的URL是由客户端浏览器发送的。
  • 浏览器地址栏会有变化。
RedirectServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //产生重定向响应
        resp.sendRedirect("http://www.baidu.com");
    }
}

 配置web.xml:

    <servlet>
        <servlet-name>RedirectServlet</servlet-name>
        <servlet-class>com.first.servlet.RedirectServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RedirectServlet</servlet-name>
        <url-pattern>/redirect.do</url-pattern>
    </servlet-mapping>

输出:

可见访问自动跳转到了www.baidu.com

按F12查看response header可看到location和http的状态码302

2.重定向响应案例

需求:创建一个搜索页面,通过百度搜索引擎完成内容搜索。  

search.html(在web目录下):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="redirect.do" method="post">
        搜索:<input type="text" name="search">
        <input type="submit" value="search">
    </form>
</body>
</html>
RedirectServlet.java:

package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;

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

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

        //设置请求编码,setCharacterEncoding只管客户端到服务器端
        req.setCharacterEncoding("utf-8");
        //获取用户搜索数据
        String search=req.getParameter("search");
        //产生重定向响应
        resp.sendRedirect("https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd="
                + URLEncoder.encode(search,"utf-8"));
    }
}

输出:

深度好文之Servlet技术详解(五)HttpServletResponse对象

当搜索内容为中文时,跳转到重定向页面时中文会乱码,如下:

深度好文之Servlet技术详解(五)HttpServletResponse对象

因为重定向到那个页面时用是get方法(参数在url里),所以get方法会对中文做一个url编码,所以就乱码了,所以需要提前编码。

URLEncoder.encode(search,"utf-8")

再跳转时就不乱码了

深度好文之Servlet技术详解(五)HttpServletResponse对象

 3.文件下载

(1)下载

在实现文件下载时,我们需要在响应头中添加附加信息。
response.addHeader("Content-Disposition","attachment; filename="+文件名);
键值对Content-Disposition:attachment
该附加信息表示作为对下载文件的一个标识字段。不会在浏览器中
显示而是直接做下载处理。
filename=
文件名 表示指定下载文件的文件名。

FileDownServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //读取下载文件
        File file=new File("d:/heat.jpg");
        //用字节输入流将文件读入
        InputStream is=new FileInputStream(file);
        /*
        is.available()返回is的大小,因为一般大太大的东西一次性读入就行,
        大的话可以设置一次读1024B,2048B等
         */
        //缓冲区
        byte[] buff =new byte[is.available()];
        //将文件读入buff中
        is.read(buff);

        //在响应中添加附加信息
        resp.addHeader("Content-Disposition", "attachment; filename="
                +new String(file.getName().getBytes("gbk"),"iso-8859-1"));
        //产生响应
        //字节输出流
        OutputStream os=resp.getOutputStream();
        os.write(buff);
        os.flush();
        os.close();
    }
}

web.xml配置:

    <servlet>
        <servlet-name>FileDownServlet</servlet-name>
        <servlet-class>com.first.servlet.FileDownServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FileDownServlet</servlet-name>
        <url-pattern>/fileDown.do</url-pattern>
    </servlet-mapping>

输出:

输入http://localhost:8888/ajaxDemo/fileDown.do

可看到左下角下载完成

深度好文之Servlet技术详解(五)HttpServletResponse对象

(2)解决文件名中文乱码问题

这样下载的文件名就不乱码了

resp.addHeader("ContentDisposition","attachment;filename="
+new String(file.getName().getBytes("gbk"),"iso-8859-1"));

相关文章

暂无评论

暂无评论...