一、Response概述
response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。
response对象的功能分为以下四种:
-
设置响应头信息;
-
发送状态码;
-
设置响应正文;
-
重定向;
二、Response响应正文
response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象:
-
PrintWriter out = response.getWriter():获取字符流;
-
ServletOutputStream out = response.getOutputStream():获取字节流;
当然,如果响应正文内容为字符,那么使用response.getWriter(),如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream()。
注意,在一个请求中,不能同时使用这两个流!也就是说,要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用这两个流。不然会抛出IllegalStateException异常。
2.1 字符流的编码问题
- 问题描述
通过服务器端发送中文时浏览器无法正确解析,会出现乱码,英文的时候则不会出现。 - 编码问题出现的原因
服务器使用respon对象发送中文时使用的不是Utf-8或者GBK编码,客户端无法识别,或者客户端和服务器端使用的编码格式不一样也会出现问题。 - 解决的办法
//设置服务端的编码
resp.setCharacterEncoding("GBK");
//通过设置相应头设置客户端(浏览器的编码)
resp.setHeader("Content-type","text/html;utf-8");
//这个方法可以同时设置客户端和服务端,因为它会调用setCharacterEncoding方法
resp.setContentType("text/html;charset=utf-8");
2.2 缓冲区问题(需要注意)
response.getWriter()是PrintWriter类型,所以它有缓冲区,缓冲区的默认大小为8KB。也就是说,在响应数据没有输出8KB之前,数据都是存放在缓冲区中,而不会立刻发送到客户端。当Servlet执行结束后,服务器才会去刷新流,使缓冲区中的数据发送到客户端。
如果希望响应数据马上发送给客户端:
-
向流中写入大于8KB的数据;
-
调用response.flushBuffer()方法来手动刷新缓冲区
三、Response响应头信息
可以使用response对象的setHeader()方法来设置响应头!使用该方法设置的响应头最终会发送给客户端浏览器。
resp.setHeader(String,String);
resp.setIntHeader(String,int);
resp.setDateHeader(String,Long);
//这段代码是实现客户端浏览器的自动跳转
resp.setHeader("Refresh","5;http://www.baidu.com");
四、Response状态码
//设置错误的响应码
resp.sendError(int,String);
//设置正确的响应码
resp.setStatus(int);
//设置错误的响应码
resp.setError(404,"未找到请求的资源!");
//设置正确的响应码
resp.setStatus(200);
五、重定向
六、什么是重定向
当你访问http://www.sun.com时,你会发现浏览器地址栏中的URL会变成http://www.oracle.com/us/sun/index.htm,这就是重定向了。重定向是服务器通知浏览器去访问另一个地址,即再发出另一个请求。
6.1 演示重定向过程
响应码为200表示响应成功,而响应码为302表示重定向。所以完成重定向的第一步就是设置响应码为302。
因为重定向是通知浏览器再第二个请求,所以浏览器需要知道第二个请求的URL,所以完成重定向的第二步是设置Location头,指定第二个请求的URL地址。
resp.setStatus(302);
resp.setHeader("Location","http://www.baidu.com");
上面代码的作用是:当访问AServlet后,会通知浏览器重定向到百度。客户端浏览器解析到响应码为302后,就知道服务器让它重定向,所以它会马上获取响应头Location,然发出第二个请求。
6.2 快捷的重定向方式
response.sendRedirect("http://www.baidu.com");
6.3 重定向小结
-
重定向是两次请求;
-
重定向的URL可以是其他应用,不局限于当前应用;
-
重定向的响应头为302,并且必须要有Location响应头;
-
重定向就不要再使用response.getWriter()或response.getOutputStream()输出数据,不然可能会出现异常;
七、注意
如果要重定向的URL是在同一个服务器内,那么可以使用相对路径,例如:
//myweb是项目的名称,TServlet是要访问的资源
resp.sendRedirect("/myweb/TServlet2");