在Servlet api 中,ServletResponse接口被定义为用于创建响应消息,ServletResponse对象由Servlet容器在用户每次请求Servlet时创建并传入Servlet的service()中。HttpServletResponse继承自ServletResponse接口,是专用于HTTP协议的子接口,用于封装HTTP响应消息。在HTTPServlet类的service()方法中,传入的ServletResponse对象被强制转换为HttpServlet对象来进行HTTP响应消息的处理。
1.设置响应状态
响应格式如下:
协议版本 状态码 状态描述
头部字段名:值
....
头部字段名:值
(空行)
响应正文
状态码:
分类 | 分类描述 |
1** | 表示信息,服务器收到请求,需要请求者继续执行操作 |
2** | 表示请求已成功被服务器接受、理解并接受 |
3** | 表示需要客户端采取进一步的操作才能完成请求。比如用于重定向 |
4** | 表示客户端错误。请求包含语法错误或无法完成请求 |
5** | 表示服务器在处理请求的过程中有错误或异常状态产生,也可能是服务器意识到以当前的软硬件资源无法完成对于请求的处理。 |
常见的状态码:
状态码 | 表示含义 |
200 | 表示请求成功 |
302 | 表示资源(网页等)暂时转移到其他URL |
404 | 表示请求的资源不存在 |
500 | 表示服务器内部错误 |
HttpServletResponse接口提供了设置状态码并生成响应状态行的方法
方法 | 描述 |
setStatus(int sc) | 以指定的状态码将响应返回给客户端 |
setError(int sc) | 使用指定的状态码向客户端返回一个错误描述 |
sendError(int sc, String msg) | 使用指定的状态码和状态描述向客户端返回一个错误 |
sendRedirect(String location) | 请求的重定向,会设定响应Location报头以及改变状态码 |
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //表示资源暂时转移到其他url response.setStatus(302); //设置响应头 location,指定转移资源为test.jsp response.setHeader("location", "test.jsp"); }
执行结果就是跳转到了test.jsp页面
2.构建响应消息头
在servlet中,可以通过HTTPServletResponse的setHeader()方法来设置响应消息头。对于含有整数和日期的报头,可以使用setIntHeader(),或者setDateHeader()。
常用HTTP响应消息头:
Server | 一种表明web服务器软件及其版本号的头标 |
Content-Type | 返回文档时所采用的的MIME对象 |
Transfer-Encoding | 表示为了达到安全传输或数据压缩的目的而面对实体进行的编码。如chunked编码,该编码将实体分块传送并表明长度,直到长度为0的块出现传输结束,在面对实体长度位置的时候有用(如数据库动态产生的数据)。 |
Date | 发送HTTP消息的日期 |
Content-Encoding | 用于说明页面在传输过程中已经采用的编码方式 |
Content-Length | 响应内容的长度,以字节为单位 |
Expires | 特定的一段时间,这段时间后的文档会被认作是过期的,不在继续缓存 |
Refresh | 多少秒后浏览器应该重新载入页面 |
Cache-Control | 用来指定响应遵循的缓存机制,若取值no-cache值表示阻止浏览器缓存页面 |
Last-Modified | 文档最后被改动的时间。一般不设置而是提供getLastModified()方法 |
Location | 浏览器应该重新连接到的URL。一般不设置而是使用sendRedirect()方法 |
Content-Disposition | 通过这个报头,可以请求浏览器询问用户将响应存储到磁盘上给定的文件夹 |
Set-Cookie | 浏览器应该记下来的cookie。一般不设置而是使用addCookie |
WWW-Authenticate | 授权的类型和范围。需要在Authorization报头中给出 |
例子:
实现动态刷新时间
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //设置刷新头,刷新时间为1秒 response.setHeader("refresh", "1"); out.print("时间:"+ new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())); }
3.创建响应正文
方法 | 描述 |
getOutputStream() | 返回字节输出流对象ServletOutputStream |
getWriter() | f返回字符输出流对象PrintWriter |
ServletOutPutStream对象主要用于输出一个二进制字节数据,如图片、视频等,PrintWriter主要用于输出字符文本内容,但是内部实现还是将字符串转换成了某种字符集编码的字节数组后再进行输出。ServletOutputStream对象虽然可以输出文本字符,但是PrintWriter对象更易与完成文本到字节数组的转换。
当向ServletOutputStream或PrintWriter对象写入数据后,Servlet容器会将这些数据作为响应消息的正文,然后再也响应状态行和各响应报文输出到客户端。同时service()方法结束后,容器会自动检查,并结束上述两个对象没有结束的close()方法。
4.响应输出中文乱码问题
java程序中的字符文本在内存中是以Unicode编码形式存在的,在使用PrintWriter输出输出字符文本时,默认使用的是iso-8859-1进行Unicode字符串到字节数组的转换,所以中文字符无法转换从而造成乱码。
//该方法只能设置PrintWriter输出流中字符的编码方式,优先权最高,可以覆盖其他两种方法 response.setCharacterEncoding("utf-8"); //该方法可以设置PrintWriter输出流中字符的编码方式,也可以设置浏览器接受到这些字符后用什么编码方式来解码,优先权第二 response.setContentType("text/html;charset=utf-8"); //该方法只能设置PrintWriter输出流中字符的编码方式,它的优先权最低,而且会被前两种覆盖 response.setLocale(new java.util.Locale("zh", "CN"));