Javaweb Servlet核心接口学习记录(4)—HttpServletResponse接口

Javaweb Servlet核心接口学习记录(4)—HttpServletResponse接口

HttpServletResponse 接口继承自 ServletResponse 接口,主要用于封装 HTTP 响应消息。由于 HTTP 响应消息分为状态行、响应消息头、消息体三部分。因此,在 HttpServletResponse 接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。
javax.servlet.http.HttpServletResponse 接口的定义为 :

public interface HttpServletResponse  extends 

在 Servlet API 中, ServletResponse 接口被定义为用于创建响应消息,ServletResponse 对象由 Servlet 容器在用户每次请求 Servlet 时创建并传入Servlet 的 service() 方法中。 HttpServletResponse 接口继承自ServletResponse 接口,是专用于 HTTP 协议的子接口,用于封装 HTTP 响应消息。在 HttpServlet 类的 service() 方法中,传入的 ServletResponse 对象被强制转换为 HttpServletResponse 对象来进行 HTTP 响应信息的处理 。
1.HTTP 协议响应报文
一个响应报文信息格式样例:
在这里插入图片描述
2.设置响应状态
HttpServletResponse 接口提供了如下设置状态码和生成响应状态行的方法:

方法方法描述
setStatus(int sc)以指定的状态码将响应返回给客户端
setError(int sc)使用指定的状态码向客户端返回一个错误响应
sendError(int sc,String msg)使用指定的状态码和状态描述向客户端返回一个错误响应
sendRedirect(String location)请求的重定向,会设定响应Location报头以及改变状态码

演示:
通过设置资源暂时转移状态码和 location 响应头,实现sendRedirect() 方法的重定向功能:
创建SetStatusServlet

package com;

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

/**
 * Servlet implementation class SetStatusServlet
 */
@WebServlet("/SetStatusServlet")
public class SetStatusServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public SetStatusServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.sendError(406, "错误信息");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}


}

运行
在这里插入图片描述
3.HTTP协议
客户端浏览器和服务器端Servlet通过HTTP协议进行通信,HTTP 协议采用请求/响应模型,协议的请求报文由请求行、请求头和可选的请求正文组成。
Http请求报文结构
在这里插入图片描述
4.构建响应消息头
响应头有两类设置方法,一类是addXxx()方法,另一类是setXxx()方法,addXxx()方法会添加属性,不会覆盖原来的属性。setXxx()会覆盖掉原来的属性
1.addXxx()

addHeader(String name;String value);
addIntHeader(String name;int value);
addDateHeader(String name;long date);

2.setXxx()

setHeader(String name;String value);
setIntHeader(String name;int value);
setDateHeader(String name;long date);
响应方法说明
setContentType(String mime)设定Content-Type消息头
setContentLength(int length)设定Content-Length消息头
addHeader(String name,String value)新增String类型的值到名为name的http头部
addIntHeader(String name,int value)新增int类型的值到名为name的http头部
addDateHeader(String name,long date)新增long类型的值到名为name的http头部
addCookie(Cookie c)为Set-Cookie消息头增加一个值

示例:使用setHeader()方法设置消息头"Refresh"实现一个页面动态时钟效果
创建ResponseRefreshHeadServlet

package com;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

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

/**
 * Servlet implementation class ResponseRefreshHeadServlet
 */
@WebServlet("/ResponseRefreshHeadServlet")
public class ResponseRefreshHeadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ResponseRefreshHeadServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		response.setHeader("refresh", "1");

		PrintWriter out = response.getWriter();
		out.print("现在时间是:");
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		out.print(sdf.format(date));
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

运行
在这里插入图片描述
5.创建响应正文
在 Servlet 中,向客户端输出的响应数据是通过输出流对象来完成的,HttpServletResponse 接口提供了两个获取不同类型输出流对象的方法:

方法方法描述
getOutputStream()返回字节输出流对象ServletOutputStream
getWriter()返回字符输出流对象PrintWriter
  • ServletOutputStream 对象主要用于输出二进制字节数据 ,如配合setContentType() 方法响应输出一个图像、视频等。
  • PrintWriter 对象主要用于输出字符文本内容,但其内部实现仍是将字符串转换成某种字符集编码的字节数组后再进行输出 。
  • 当向ServletOutputStream或PrintWriter对象中写入数据后,Servlet容器会将这些数据作为响应消息的正文,然后再与响应状态行和各响应头组合成完整的响应报文输出到客户端。同时,在Serlvet的service()方法结束后,容器还将检查getWriter()或getOutputStream(方法返回的输出流对象是否已经调用过close()方法,如果没有,容器将调用close()方法关闭该输出流对象.

示例:使用ServletOutputStream对象响应输出一个服务器端的图案
创建OutputStreamServlet

package com;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class OutputStreamServlet
 */
@WebServlet("/OutputStreamServlet")
public class OutputStreamServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public OutputStreamServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("image/jpeg");

		ServletContext context = getServletContext();
		InputStream is = context.getResourceAsStream("/images/tupian.jpg");

		ServletOutputStream os = response.getOutputStream();
		int i = 0;
		while ((i = is.read()) != -1) {
			os.write(i);
		}
		is.close();
		os.close();
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

运行
在这里插入图片描述
6.响应输出中文问题
ServletResponse 接口中定义 了 setCharacterEncoding() 、setContentType()和 setLocale() 等方法 来指定 ServletResponse.getWriter() 方法 返回的PrintWriter 对象所使用的字符集编码。
示例:指定字符集编码

response.setCharacterEncoding ("UTF-8");
response.setContentType ("text/ html;charset =UTF-8");
response.setLocale (new  java.util.Locale (" zh","CN "));// 简体中文

setCharacterEncoding () 、setContentType() 和 setLocale () 三种方法之间的差异分析:

  • setCharacterEncoding() 方法只能用来设置 PrintWriter 输出流中字符的编码方式,它的优先权最高,可以覆盖后面两种方法中的设置;
  • setContentType() 方法既可以设置 PrintWriter 输出流中字符的编码方式,也可以设置浏览器接收到这些字符后以什么编码方式来解码,它的优先权低于第一种方法,但高于第三种方法;
  • setLocale() 方法只能用来设置 PrintWriter 输出流中字符的编码方式,它的优先权最低,在已经使用前两种方法中的一个设置了编码方式以后,它将被覆盖而不再起作用。

7.本章总结

  • 容器在初始化一个 Servlet 时,会为这个 Servlet 创建一个唯一的 ServletConfig 对象,并将这个对象通过 init(ServletConfig config) 方法传递并保存在此 Servlet 对象中。
  • 使用 ServletConfig 接口中的方法主要可以访问两项内容: Servlet 初始化参数和 ServletContext对象。
  • ServletContext 对象代表当前 Servlet 运行环境, Servlet 容器在启动一个 Web 应用时,会为该应用创建一个唯一的 ServletContext 对象供该应用中的所有 Servlet 对象共享, Servlet 对象可以通过ServletContext对象来访问容器中的各种资源。
  • ServletContext 对象可以获取应用范围的初始化参数、在应用范围内存取共享数据等。
  • HttpServletRequest 接口继承了 ServletRequest 接口,是专用于 HTTP 协议的子接口,用于封装HTTP 请求信息。
  • HttpServletRequest 对象主要用于获取请求报文信息、获取网络连接信息、存取请求域属性 。
  • HttpServletResponse 接口继承自 ServletResponse ,是专用于 HTTP 协议的子接口,用于封装 HTTP
    响应消息。
  • HttpServletResponse 对象主要用于创建响应报文。
  • ServletContex 接口 、 HttpServletRequest 接口具有相同的存取域属性的方法。
  • HttpServletRequest 接口提供了统一的获取 GET 请求参数和 POST 请求参数的方法。
  • 在 Servlet 中可以通过两种主要方式完成对新 URL 地址的跳转:重定向和请求转发。

版权声明:本文为asdfghjkl_zth原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。