Servlet p4 HttpServletResponse对象

发布时间 2023-07-02 09:59:08作者: 凉白茶

HttpServletResponse对象

基本介绍

​ Web服务器收到客户端的http请求,会针对每次请求,分别创建一个用于代表请求的 request对象 和代表响应的 response对象。

​ request 和 response对象 代表请求和响应:获取客户瑞数据,需要通过request对象;向客户端输出数据需要通过response对象

​ HttpServletResponse的主要功能用于服务器对客户端的请求进行响应,将Web服务器处理后的结果返回给
客户端。service(O方法中形参接收的是HttpServletResponse接口的实例化对象,这个对象中封装了向客户端发
送数据、发送响应头,发送响应状态码的方法。

响应数据

​ 接收客户端请求后,可以通过 HttpServletResponse对象 直接进行响应,响应时需要获取输出流。

有两种形式:

  • getWriter():获取字符流(只能响应字符)

    //获取字符输出流
    PrintWriter writer = resp.getWriter();
    //输出数据
    writer.write("hello");
    
  • getOutputStream():获取字节流(能响应一切数据)

    //获取字节输出流
    ServletOutputStream outputStream = resp.getOutputStream();
    //输出数据
    outputStream.write("hi".getBytes());
    

注意:二者不能同时使用,因为resp对象只能响应一次,再次调用就不存在了。

响应乱码问题

​ 在响应中,如果我们响应的内容中含有中文,则可能出现乱码。这是因为服务器响应的数据也会经过网络传输,f服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。

  • getWriter()字符乱码问题

    ​ 对于getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用1S0-8859-1格式的编码,该编码方式并不支持中文。

    要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式,比如我们通常用的"UTF-8"。

    response.setcharacterEncoding("UTF-8");

    此时还只完成了一半的工作,要保证数据正确显示,还需要指定客户端的解码方式。

    response.setHeader("content-type","text/html;charset=UTF-8");

    两端指定编码后,乱码就解决了。一句话:保证发送端和接收端的编码一致。

    //设置服务端的编码
    response.setcharacterEncoding("UTF-8");
    //设置客户端的响应类型及编码
    response.setHeader("content-type","text/html;charset-UTF-8");
    //得到字符输出流
    Printwriter writer response.getwriter();
    writer.write("<h2>你好</h2>");
    

    以上两端编码的指定也可以使用一句替代,同时指定服务器和客户端

    response.setcontentType("text/html;charset=UTF-8");

  • getOutputStream()字符乱码问题

    ​ 对于getOutputStream(0方式获取到的字节流,响应中文时,由于本身就是传输的字节,所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时,则文本正确显示,否则出现乱
    码。无论如何我们都应该准确掌握服务器和客户端使用的是那种编码格式,不能留下不确定因素,以确保数据正确显示。

    直接指定客户端和服务器使用的编码方式一致

    response.setHeader("content-type","text/html;charset-UTF-8");

    //设置客户端的编码及响应类型
    Servletoutputstream out response.getoutputstream();
    response.setHeader("content-type","text/html;charset=UTF-8");
    out.write("<h2></h2>".getBytes("UTF-8"))
    

重定向

​ 重定向是一种服务器指导,客户端的行为。客户端发出第一个请求,被服务器接收处理后,服务器会进行响应,在响应的同时,服务器会给客户端一个新的地址(下次请求的地址response.sendRedirect(url:),当客户端接收到响应后,会立刻、马上、自动根据服务器给的新地址发起第二个请求,服务器接收请求并作出响应,重定向完成。

从描述中可以看出重定向当中有两个请求存在,并且属于客户端行为。

//重定向跳转到servlet05
response.sendRedirect("s05");

通过观察浏览器我们发现第一次请求获得的响应码为302,并且含有一个location头信息。并且地址栏最终看到的地址是和第一次请求地址不同的,地址栏已经发生了变化。

1686970195001

1686970116673

servlet04代码:

package com.xxxx.servlet;

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

/**
 * @author: 86199
 * @date: 2023/6/17 10:36
 * Description: 重定向
 * 存在两次请求
 * 地址栏会发生改变
 * request对象不共享
 */
@WebServlet("/s04")
public class Servlet04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet04....");

        // 接收参数
        String uname = req.getParameter("uname");
        System.out.println("servlet04 uname = " + uname);

        //重定向跳转到05
        resp.sendRedirect("s05");
    }
}

servlet05代码:

package com.xxxx.servlet;

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

/**
 * @author: 86199
 * @date: 2023/6/17 10:36
 * Description: 重定向
 */
@WebServlet("/s05")
public class Servlet05 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet05....");

        // 接收参数,无法拿到,毕竟s04和s05之间也没有共享req对象
        String uname = req.getParameter("uname");
        System.out.println("servlet05 uname = " + uname);
    }
}

请求转发和重定向的区别

请求转发和重定向比较

1686972065928

两者都可以进行跳转,根据实际需求选取。

代码演示:

package com.xxxx.servlet;

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

/**
 * @author: 86199
 * @date: 2023/6/17 10:36
 * Description: 重定向和请求转发的区别
 * 1. 请求转发的地址栏不会发生改变,重定向的地址栏会发生改变
 * 2. 请求转发只有一次请求,重定向有两次请求
 * 3. 请求转发时request对象可以共享,重定向不能共享
 * 4. 请求转发是服务端的行为,重定向是客户端行为
 * 5. 请求转发时的地址只能是当前站点下的(当前项目)资源,重定向时地址可以是任意地址
 */
@WebServlet("/s06")
public class Servlet06 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet06....");

        // 接收参数
        String uname = req.getParameter("uname");
        System.out.println(uname);

        //设置request域对象
        req.setAttribute("upwd", "123456");

        //请求转发
        req.getRequestDispatcher("index.jsp").forward(req, resp);

        //重定向
//        resp.sendRedirect("index.jsp");
        //重定向跳转到百度
//        resp.sendRedirect("http://www.baidu.com");

        //请求转发到百度,404找不到
//        req.getRequestDispatcher("http://www.baidu.com");
    }
}

index.jsp文件代码:

<%--
  Created by IntelliJ IDEA.
  User: 86199
  Date: 2023/6/16
  Time: 11:11
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <%--    Java脚本段--%>
  <%
    //获取参数
    String uname = request.getParameter("uname");
    //获取request作用域
    String upwd = (String) request.getAttribute("upwd");

    //输出内容
    out.print(uname);
    out.print("================");
    out.print(upwd);
  %>
  </body>
</html>