1. 接口的定义
HttpServletResponse 是 ServletResponse 的子接口,所以在学习该接口前,有必要对后者进行一个简单的探索。
依然先看官方文档对 ServletResponse 接口的描述:
Defines an object to assist a servlet in sending a response to the client. The servlet container creates a ServletResponse object and passes it as an argument to the servlet’s service method.
它的作用显而易见,就是一个帮助 servlet 向客户端发送响应的一个对象。servlet 容器会创建一个 ServletResponse 对象并且将该对象作为参数传给 servlet 的 service() 方法。
那么进而联想到 HttpServletResponse 的作用必然就是帮助 HttpServlet 对象向客户端发送响应。在 HttpServlet 类中,重载了 Servlet 类的 service 方法,该方法主要就是用来处理请求业务逻辑的,该方法的定义是这样的: public void service(ServletRequest req, ServletResponse resp)
,可能学到这里会有疑问,为什么参数的类型不是 HttpServletRequset 和 HttpServletResponse 呢,然而看源码就可以发现,在 service 方法的内部,一开始就对 req 和 resp 对象的类型进行了强转,只是在强转前又做了类型的判断,源码如下:
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
至此,应该对 HttpServletResponse 有个很清晰的认识了,既然它作为一个“帮手”的角色,那么它的实现类就必须实现该接口定义的方法来帮助 servlet 向客户端发送响应,接下来就看看该接口具体定义了哪些方法。
2. 接口中定义的方法
HttpServletResponse 目前定义了20个方法,此外还定义了一堆代表 HTTP 响应状态码的静态常量。这里只列举部分方法。这些方法见名知意,就不在此多做解释了,具体可见 API 文档。
- addHeader(String name, String value)
- sendError(int sc)
- sendError(int sc, String msg)
- setHeader(String name, String value)
- setStatus(int sc)
- addCookie(Cookie cookie)
不过纵观这个接口中定义的方法,貌似都是在响应行和响应头两部分做工作,那么响应体可能就是由它的父接口 ServletResponse 去处理了。它的父接口也有个实现类 ServletResponseWrapper,那么显然需要 HttpServletResponseWrapper 这个类去继承它。而之前说到的参数 resp 的实际类型就是 HttpServletResponseWrapper 类,所以 resp 可以调用 HttpServletResponse 接口和 ServletResponse 中定义的方法,而后者接口中定义了两个方法用来向浏览器写入数据(响应体),这两个方法分别为 getWriter 和 getOutputStream。
3. 应用案例 - 请求重定向
所谓重定向就是当客户端 A 请求 B 资源时,B 让 A 去请求 C资源。设置重定向的代码很简单,只有简单的一行,看如下代码:
public class SexgirlServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.sendRedirect("hello");
}
}
通过调用 resp 的 sendRedirect() 方法即可向客户端发送一个重定向,只有客户端会去请求该方法的参数路径,关于路径的设置参考如下官方描述。
If the location is relative without a leading ‘/‘ the container interprets it as relative to the current request URI. If the location is relative with a leading ‘/‘ the container interprets it as relative to the servlet container root. If the location is relative with two leading ‘/‘ the container interprets it as a network-path reference
当访问 localhost:10086/resp/sexgirl 时,它会将请求重定向为 localhost:10086/resp/hello。
�