Servlet中的HttpServletRequest和HttpServletResponse对象

moran
2020-09-17 / 0 评论 / 258 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年04月14日,已超过59天没有更新,若内容或图片失效,请留言反馈。

Servlet中的请求和H响应对象

HttpServletRequest

这个对象封装了从客户端提交过来的一切数据。

简单例子

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1.通过request对象获取请求头Name集合
    Enumeration<String> list = req.getHeaderNames();
    // 2.遍历集合
    while(list.hasMoreElements()){
        String name = list.nextElement();
        // 通过头名称获取头内容
        String value = req.getHeader(name);
        System.out.println(name+"==="+value);
    }
}

获取请求参数

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

    // 1.获取请求参数的map集合,有多种集合,这里以map为例
    Map<String,String[]> map = req.getParameterMap();
    // 2.获取键的set集合
    Set<String> set = map.keySet();
    // 3.获取set集合的迭代器
    Iterator<String> iterator = set.iterator();
    // 4.通过迭代器遍历set,map集合
    while(iterator.hasNext()){
        String key = iterator.next();
        // 通过键拿值
        String value = map.get(key)[0];
        System.out.println(key+"==="+value);
    }
    // 通过访问servlet路径?参数=值让程序遍历参数。
    // 为什么map集合的泛型第二个是一个数组?
    // 因为可能会出现?name=lisi&name=zhangsan的情况,因此是一个数组。
    // 上述案例只拿参数的第一个值。
}

请求对象不只局限是所讲内容,还有更多对于客户端请求的操作,比如获取协议,获取远程,本地地址,获取远程,本地端口...

获取中文数据出现乱码

客户端提交数据给服务端,如果数据中带有中文的话,有可能出现乱码的情况,那么可以参照以下方法解决。

  • GET方式

通天get方式传递过来的数据,因为tomcat会以ISO-8859-1编码接收数据,而getParameter()方法取数据默认是使用ISO-8859-1去解码的,而ISO-8859-1不支持中文,因此会出现乱码。
注意:在jdk8以后不再以ISO-8859-1接收数据和解码数据,而已UTF-8编码。因此直接可以使用getParameter()方法接收数据而不出现乱码。

解决方案:先让数据回到ISO-8859-1,然后再按UTF-8解码。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String name = new String(req.getParameter("name").getBytes("ISO-8859-1"),"UTF-8");
    String password = req.getParameter("password");
    System.out.println(name+"==="+password);
}

或者是在tomcat中配置转码不为iso-8859-1。
tomcat路径/config/server.xml中修改<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/><Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URLEncoding="UTF-8"/>,参数可能有些不同,但是就是Connector标签下。

  • POST方式

解决方案:设置请求体编码

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 设置请求体中的编码
    req.setCharacterEncoding("UTF-8");
    String name = req.getParameter("name");
    String password = req.getParameter("password");
    System.out.println(name+"==="+password);
}

改该方法不适用与get方式,因为get方式的参数提交在url后面,而不是在请求体中。

HttpServletResponse

负责返回数据给客户端

简单例子

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 以字符流的方式写出
    resp.getWriter().write("Hello");
    // 以字节流的方式写出,因此就收的是字符数组
    resp.getOutputStream().write("Hello".getBytes());
}

传递中文数据客户端出现乱码

  • 以字符流输出
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1.设置写出数据的编码格式
    resp.setCharacterEncoding("UTF-8");
    // 2.设置客户端将以什么格式对数据进行解码
    resp.setHeader("Content-Type","text/html;charset=UTF-8");
    resp.getWriter().write("你好");
}

在jdk8以后Write()方法将不再用ISO-8859-1编码去写出数据,而是UTF-8,因此第一个步骤可以省略。

  • 以字节流输出
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1.设置客户端以UTF-8编码去解码
    resp.setHeader("Content-Type","text/html;charset=UTF-8");
    resp.getOutputStream().write("你好".getBytes("UTF-8"));
}

其实在getBytes()中也可以不需要写编码,在方法源代码中就是默认以UTF-8编码的。

  • 通用方法

上面两种不同输出流有不同输出方法,也有不同解码方法,其实可以通用一种方法解决。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1.设置文档格式为html,并告知客户端使用UTF-8编码解码。
    resp.setContentType("text/html;charset=UTF-8");
}

小练习

使用servlet来接管链接中的静态资源,像txt文件不再是直接输出而是下载。

html代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        默认情况
        <a href="file/头像.jpg">头像.jpg</a>
        servlet接管
        <a href="downloadServlet?filename=头像.jpg">头像.jpg</a>
    </body>
</html>

java代码(downloadServlet):

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1.获取要下载的文件名称
    String fileName = req.getParameter("filename");

    // 2.获取文件在tomcat中的绝对路径
    String path = getServletContext().getRealPath("file/"+fileName);
    // 3.实例化输入流和输出流
    InputStream is = new FileInputStream(path);
    OutputStream out = resp.getOutputStream();

    // 4.设置响应头,不再直接显示而是弹出下载框
    resp.setHeader("Content-Disposition","attachment;filename="+fileName);

    // 5.输出流写出数据
    int len = 0;
    byte[] buffer = new byte[1024];
    while((len=is.read(buffer))!=-1){
        out.write(buffer,0,len);
    }
    is.close();
    out.close();
}

除这些方法外还有setHeader(),setStatus()方法。通过setHeader方法可以重定向页面,但必须通过setStatus()方法设置状态码(最好为300+的状态码,因为该码表示重定向)

0

评论 (0)

取消