我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。
service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大.
1.response的运行流程
2.通过抓包工具抓取Http响应
因为response代表响应,所以我们可以通过该对象分别设置Http响应的响应行,响 应头和响应体
3.常用方法
(1)setStatus(int sc)
设置响应行的状态码
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class StatusServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setStatus(404); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
运行这个程序,在后台抓包响应头处为404 未找到。
常用状态码:http://tool.oschina.net/commons?type=5
(2)设置响应头
addHeader(String name,string value)
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HeaderServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.addHeader("name", "wangwu"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
运行之后抓包
addIntHeader(String name, int value)
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HeaderServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.addIntHeader("id",1111 ); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
addDateHeader(String name, long date)
import java.io.IOException; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HeaderServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Date date = new Date(); response.addDateHeader("date",date.getTime() ); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
setHeader(String name, String value)
setDateHeader(String name, long date)
setIntHeader(String name, int value)
这三个方法是设置响应头,add的方法是添加,如果name的value唯一,这三个方法与上面方法效果相同
如果如下:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("name", "wangwu"); response.setHeader("name", "zhangsan"); }
如果name先设置为wangwu,后面又设置zhangsan. name值最后被设置为zhangsan
如果addHeader方法则不同,
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.addHeader("name", "wangwu"); response.addHeader("name", "zhangsan"); }
对比可知,
add表示添加,而set表示设置
(3)重定向
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setStatus(302); response.setHeader("Location", "/web14/servlet2"); }
先设置状态码302
302 |
请求的资源现在临时从不同的 URI 响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。 新的临时性的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。 如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。 注意:虽然RFC 1945和RFC 2068规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将302响应视作为303响应,并且使用 GET 方式访问在 Location 中规定的 URI,而无视原先请求的方法。状态码303和307被添加了进来,用以明确服务器期待客户端进行何种反应。 |
随后设置响应头Location,运行结果如下,将进入servlet2页面,url也为servlet2的url
第二种.....重定向的方法sendRedirect(url)
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.sendRedirect("/web14/servlet2"); }
效果与第一种相同
(4)设置响应体
响应体设置文本
PrintWriter getWriter()
获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览 器端。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter writer = response.getWriter(); writer.write("你好"); }
关于设置中文的乱码问题
原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,可以通过 response的setCharacterEncoding(String charset) 设置response的编码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); PrintWriter writer = response.getWriter(); writer.write("你好"); }
但我们发现客户端还是不能正常显示文字
原因:我们将response缓冲区的编码设置成UTF-8,但浏览器的默认编码是本地系 统的编码,因为我们都是中文系统,所以客户端浏览器的默认编码是GBK,我们可以 手动修改浏览器的编码是UTF-8。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Content-Type", "text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); writer.write("你好"); }
response.setHeader("Content-Type", "text/html;charset=UTF-8");我们还可以在代码中指定浏览器解析页面的编码方式,
通过response的setContentType(String type)方法指定页面解析时的编码是UTF-8
response.setContentType("text/html;charset=UTF-8");
上面的代码不仅可以指定浏览器解析页面时的编码,同时也内含 setCharacterEncoding的功能
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); writer.write("你好"); }
响应头设置字节
ServletOutputStream getOutputStream()
获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字 节,在由Tomcat服务器将字节内容组成Http响应返回给浏览器。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //使用response获得字节输出流 ServletOutputStream out = response.getOutputStream(); //获得服务器上的图片 String realPath = this.getServletContext().getRealPath("a.jpg"); InputStream in = new FileInputStream(realPath); int len=0; byte[] bytes = new byte[1024]; while((len=in.read(bytes))!=-1) { out.write(bytes,0,len); } in.close(); out.close(); }