Servlet最主要作用就是处理客户端请求并作出回应,为此,针对每次请求,Web容器在调用service()之前都会创建两个对象,分别是HttpServletRequest和HttpServletResponse。其中HttpServletRequest封装HTTP请求消息,HttpServletResponse封装HTTP响应消息。需要注意的是,Web服务器运行过程中,每个Servlet都会只创建一个实例对象,不过每次请求都会调用Servlet实例的service(ServletRequest req, ServletResponse res)方法,这里HttpServletRequest是ServletRequest的子类,HttpServletResponse是ServletResponse的子类。
HttpServletRequest和HttpServletResponse接口继承关系图如下所示:
1、HttpServletResponse
HttpServletResponse接口继承自ServletResponse接口,由于HTTP响应消息分为状态行、响应消息体、消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。虽然HttpServletResponse接口中的方法较多,但是我们常用的也就是那么几个,如果用到其他的方法了可以阅读响应的源码或者相关资料就行了。
发送状态码相关函数
| 方法 | 说明 |
| public void setStatus(int sc) | 设置响应消息状态码,Web服务器默认产生一个状态码为200的状态行 |
| public void sendError(int sc) | 发送表示错误信息的状态码,第二个方法还增加了一个用于提示说明的文本信息 |
| public void sendError(int sc, String msg) |
发送响应消息头相关函数
| 方法 | 说明 |
| public void addHeader(String name, String value) | 设置HTTP响应头字段,name指定字段名称,value指定字段值。addHeader可以增加同名的响应头字段,setHeader则会覆盖同名的头字段 |
| public void setHeader(String name, String value) | |
| public void setContentLength(int len) | 设置响应消息的实体内容的大小,单位为字节,即设置Content-Length字段的值 |
| public void setContentType(String type) | 设置Servlet输出内容的MIME类型,即设置Content-Type字段的值 |
| public void setCharacterEncoding(String charset) | 设置输出内容字符编码,即设置Content-Type字段的值,注意,该方法优先级比setContentType的高 |
| public void sendRedirect(String location) | Servlet请求重定向 |
发送响应消息体相关函数
| 方法 | 说明 |
| public ServletOutputStream getOutputStream() | 获取HttpServletResponse的字节输出流ServletOutputStram类型 |
| public PrintWriter getWriter() | 获取HttpServletResponse的字符输出流ServletWriter类型 |
中文输出乱码问题
计算机中的数据都是以二进制形式存储的,因此,传输文本时,就会发生字符的字节之间的转换。字符与字节之间的转换时通过查码表完成的,字符转换为字节的过程称为编码,字节转换为字符的过程称为解码,如果编码和解码使用的码表不一样,则会出现乱码问题。
注意:HttpServletResponse对象的字符输出流在编码时,默认采用的是ISO 8859-1编码,该编码方式不兼容中文,比如会将"中国"编码为"63 63"(在ISO 8959-1的码表中查不到的字符会显示63)。当浏览器对接收到的数据进行解码时,会默认采用GB2312,将"63"解码为"?",浏览器就将"中国"两个字符解码为"??"。
HttpServletResponse程序示例
package zzz; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Hello extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 设置响应消息编码,注释后"中国"会显示"??"乱码 response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("hello 中国"); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { this.doGet(request, response); } }
有时会遇到定时跳转页面的问题,HTTP中Refresh头字段可以通知浏览器在指定的时间内自动刷新并跳转到其他页面,网页定时刷新并跳转到指定页面。
package zzz; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Hello extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { // 设置响应消息编码 response.setContentType("text/html;charset=utf-8"); response.setHeader("Refresh", "2;url=http://www.baidu.com"); PrintWriter out = response.getWriter(); out.println("hello 中国,2秒后跳转到百度..."); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { this.doGet(request, response); } }