第四节 HttpServletResponse与HttpServletRequest对象的复习
一、概述:
- 请求和响应
Servlet最主要的作用就是处理客户端请求,并向客户端做出响应。
为此,针对Servlet的每次请求,web服务器在调用service()方法之前,都会创建两个对象。
分别是HttpServletRequest和HttpServletResponse。
其中HttpServletRequest用于封装HTTP请求信息
,简称request对象
。
——HttpServletResponse用于封装HTTP响应信息
,简称response对象
。
二、HttpServletResponse
-
HttpServletResponse对象
当一个 Web 服务器响应一个 HTTP 请求时,响应通常包括一个状态行、一些响应报头、一个空行和文档。一个典型的响应如下所示: HTTP/1.1 200 OK Content-Type: text/html Header2: ... ... HeaderN: ... (Blank Line) <!doctype ...> <html> <head>...</head> <body> ... </body> </html>
2.1. 状态行包括 HTTP 版本(在本例中为 HTTP/1.1)、一个状态码(在本例中为 200)和一个对应于状态码的短消息(在本例中为 OK)。
Web 服务器端返回到浏览器的最有用的 HTTP 1.1 响应报头 Allow 这个头信息指定服务器支持的请求方法(GET、POST 等)。 Cache-Control 这个头信息指定响应文档在何种情况下可以安全地缓存。可能的值有: public、private 或 no-cache 等。Public 意味着文档是可缓存,Private 意 味着文档是单个用户私用文档,且只能 存储在私有(非共享)缓存中, no-cache 意味着文档不应被缓存。 Connection 这个头信息指示浏览器是否使用持久 HTTP 连接。值 close 指示浏览器不使用持久 HTTP 连接,值 keep-alive 意味着使用持久连接。 Content-Disposition 这个头信息可以让您请求浏览器要求用户以给定名称的文件把响应保存到磁盘。 Content-Encoding 在传输过程中,这个头信息指定页面的编码方式。 Content-Language 这个头信息表示文档编写所使用的语言。例如,en、en-us、ru 等。 Content-Length 这个头信息指示响应中的字节数。只有当浏览器使用持久(keep-alive) HTTP 连接时才需要这些信息。 Content-Type 这个头信息提供了响应文档的 MIME类型(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。) Expires 这个头信息指定内容过期的时间,在这之后内容不再被缓存。 Last-Modified 这个头信息指示文档的最后修改时间。然后,客户端可以缓存文件, 并在以后的请求中通过 If-Modified-Since 请求头信息提供一个日期。 Location 这个头信息应被包含在所有的带有状态码的响应中。在 300s 内,这会通知浏览器文档的地址。浏览器会自动重新连接到这个位置,并获取新的文档。 Refresh 这个头信息指定浏览器应该如何尽快请求更新的页面。您可以指定页面刷新的秒数。 Retry-After 这个头信息可以与 503(Service Unavailable 服务不可用)响应配合使 用,这会告诉客户端多久就可以重复它的请求。 Set-Cookie 这个头信息指定一个与页面关联的 cookie
发送状态码方法 (1)setStatus(int status)方法 ————该方法用于设置HTTP响应信息的状态码,并生成响应状态行。HTTP版本由服务器确定,因此,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。需要注意的是正常情况下,web服务器会默认产生一个状态码是200的状态行。 (2)sendError(int sc)方法 ————该方法用于发送表示错误信息的状态码,例如,404表示找不到客户请求的资源。 (3)sendError(int code,String message)方法 ————该方法即可以发送表示错误的状态码,又可以增加一些说明信息。
2.2. 设置 HTTP 响应报头的方法
下面的方法可用于在 Servlet 程序中设置 HTTP 响应报头。这些方法通过 HttpServletResponse 对象可用。 (1)String encodeRedirectURL(String url) //为 sendRedirect 方法中使用的指定的 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。 (2)String encodeURL(String url) //对包含 session 会话 ID 的指定 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。 (3)boolean containsHeader(String name) //返回一个布尔值,指示是否已经设置已命名的响应报头。 (4)boolean isCommitted() //返回一个布尔值,指示响应是否已经提交。 (5)void addCookie(Cookie cookie) //把指定的 cookie 添加到响应。 (6)void addDateHeader(String name, long date) //添加一个带有给定的名称和日期值的响应报头。 (7)void addHeader(String name, String value) //添加一个带有给定的名称和值的响应报头。 (8)void addIntHeader(String name, int value) //添加一个带有给定的名称和整数值的响应报头。 (9)void flushBuffer() //强制任何在缓冲区中的内容被写入到客户端。 (10)void reset() //清除缓冲区中存在的任何数据,包括状态码和头。 (11)void resetBuffer() //清除响应中基础缓冲区的内容,不清除状态码和头。 (12)void sendError(int sc) //使用指定的状态码发送错误响应到客户端,并清除缓冲区。 (13)void sendError(int sc, String msg) //使用指定的状态发送错误响应到客户端。 (14)void sendRedirect(String location) //使用指定的重定向位置 URL 发送临时重定向响应到客户端。 (15)void setBufferSize(int size) //为响应主体设置首选的缓冲区大小。 (16)void setCharacterEncoding(String charset) //设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。 (17)void setContentLength(int len) //设置在 HTTP Servlet 响应中的内容主体的长度,该方法设置 HTTP Content-Length 头。 (18)void setContentType(String type) //如果响应还未被提交,设置被发送到客户端的响应的内容类型。 (19)void setDateHeader(String name, long date) //设置一个带有给定的名称和日期值的响应报头。 (20)void setHeader(String name, String value) //设置一个带有给定的名称和值的响应报头。 (21)void setIntHeader(String name, int value) //设置一个带有给定的名称和整数值的响应报头。 (22)void setLocale(Locale loc) //如果响应还未被提交,设置响应的区域。 (23)void setStatus(int sc) //为该响应设置状态码。
2.3. 发送响应信息体相关的方法
(1)getOutputStream() 方法
该方法所获取的字节输出流对象为ServletOutputStreanm类型。由于ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。例如: String data="itcast"; OutputStream out=response.getOutputStream(); out.write(data.getBytes());
(2)getWriter()方法
该方法所获取的字符输出流对象为PrintWriter类型。由于PrintWriter类型的对象可以直接输出字符文本内容,因此,要想输出内容全是字符文本的网页文档,需要使用getWriter()方法。例如: String data="itcast"; PrintWriter print=response.getWriter(); print.write(data);
-
HttpServletResponse应用
-
解决乱码问题
编码和解码方式不一致就会出现乱码问题,解决办法:1) //设置HttpServletResponse使用utf-8编码 response.setCharacterEncoding(“utf-8”); //通知浏览器使用utf-8编码 response.setHeader(“Content-Type”,”text/html;charset=utf-8”); 2)//包含第一种方式的两个功能 response.setContentType(“text/html;charset=utf-8”);
-
实现网页定时刷新并跳转
1)//2秒后刷新并跳转到传智博客官网首页 response.setHeader(“Refresh”,”2;URL=http://www.itcast.cn”); 2)//页面每隔3秒刷新一次,并且输出当时的时间值 response.setHeader(“Refresh”,”3”); response.getWriter().println(new java.util.Data());
-
实现请求重定向
示例:用户登陆过程1)登录页面login.html关键代码 <form action="/chapter04/LoginServlet" method="post"> 用户名: <input type=”text” name="username"/><br /> 密&nbap;&nbap;&nbap码: <input type="password" name="password"/><br /> <input type="submit" value="登录"/> </form>
2)登录成功页面welcome.html关键代码 <body> 欢迎你,登录成功! </body>
3)LoginServlet关键代码 response.setContentType("text/html;charset=utf-8"); String username=request.getParameter("username"); String password=requset.getParameter("password"); if(("itcast").equals(username) && ("123").equals(password)){ response.sendRedirect("/chapter04/welcome.html"); }else{ response.sendRedirect("/chapter04/login.html"); }
-
三、HttpServletRequest对象
-
HttpServletRequest对象专门用来封装HTTP请求信息,请求信息分为请求行、请求信息头和请求信息体3个部分,HttpServletRequest接口定义了大量获取请求信息的方法。
1、获取请求行信息的相关方法。
2、获取请求信息头的相关方法
以下是来自于浏览器端的重要头信息,您可以在 Web 编程中频繁使用: Accept 这个头信息指定浏览器或其他客户端可以处理的 MIME 类型。值 image/png 或 image/jpeg 是最常见的两种可能值。 Accept-Charset 这个头信息指定浏览器可以用来显示信息的字符集。例如 ISO-8859-1。 Accept-Encoding 这个头信息指定浏览器知道如何处理的编码类型。值 gzip 或 compress 是最常见的两种可能值。 Accept-Language 这个头信息指定客户端的首选语言,在这种情况下,Servlet 会产生多种语言的结果。例如,en、en-us、ru 等。 Authorization 这个头信息用于客户端在访问受密码保护的网页时识别自己的身份。 Connection 这个头信息指示客户端是否可以处理持久 HTTP 连接。持久连接允许客户端或其他浏览器通过单个请求来检索多个文件。值 Keep-Alive 意味着使用了持续连接。 Content-Length 这个头信息只适用于 POST 请求,并给出 POST 数据的大小(以字节为单位)。 Cookie 这个头信息把之前发送到浏览器的 cookies 返回到服务器。 Host 这个头信息指定原始的 URL 中的主机和端口。 If-Modified-Since 这个头信息表示只有当页面在指定的日期后已更改时,客户端想要的页面。如果没有新的结果可以使用,服务器会发送一个 304 代码,表示 Not Modified 头信息。 If-Unmodified-Since 这个头信息是 If-Modified-Since 的对立面,它指定只有当文档早于指定日期时,操作才会成功。 Referer 这个头信息指示所指向的 Web 页的 URL。例如,如果您在网页 1,点击一个链接到网页 2,当浏览器请求网页 2 时,网页 1 的 URL 就会包含在 Referer 头信息中。 User-Agent 这个头信息识别发出请求的浏览器或其他客户端,并可以向不同类型的浏览器返回不同的内容。
3、读取 HTTP 头的方法
下面的方法可用在 Servlet 程序中读取 HTTP 头。这些方法通过 HttpServletRequest 对象可用。 1 Cookie[] getCookies() //返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。 2 Enumeration getAttributeNames() //返回一个枚举,包含提供给该请求可用的属性名称。 3 Enumeration getHeaderNames() //返回一个枚举,包含在该请求中包含的所有的头名。 4 Enumeration getParameterNames() //返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。 5 HttpSession getSession() //返回与该请求关联的当前 session 会话,或者如果请求没有 session 会话,则创建一个。 6 HttpSession getSession(boolean create) //返回与该请求关联的当前 HttpSession,或者如果没有当前会话,且创建是真的,则返回一个新的 session 会话。 7 Locale getLocale() //基于 Accept-Language 头,返回客户端接受内容的首选的区域设置。 8 Object getAttribute(String name) //以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。 9 ServletInputStream getInputStream() //使用 ServletInputStream,以二进制数据形式检索请求的主体。 10 String getAuthType() //返回用于保护 Servlet 的身份验证方案的名称,例如,"BASIC" 或 "SSL",如果JSP没有受到保护则返回 null。 11 String getCharacterEncoding() //返回请求主体中使用的字符编码的名称。 12 String getContentType() //返回请求主体的 MIME 类型,如果不知道类型则返回 null。 13 String getContextPath() //返回指示请求上下文的请求 URI 部分。 14 String getHeader(String name) //以字符串形式返回指定的请求头的值。 15 String getMethod() //返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。 16 String getParameter(String name)//以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。 17 String getPathInfo() //当请求发出时,返回与客户端发送的 URL 相关的任何额外的路径信息。 18 String getProtocol() //返回请求协议的名称和版本。 19 String getQueryString() //返回包含在路径后的请求 URL 中的查询字符串。 20 String getRemoteAddr() //返回发送请求的客户端的互联网协议(IP)地址。 21 String getRemoteHost() //返回发送请求的客户端的完全限定名称。 22 String getRemoteUser() //如果用户已通过身份验证,则返回发出请求的登录用户,或者如果用户未通过身份验证,则返回 null。 23 String getRequestURI() //从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。 24 String getRequestedSessionId() //返回由客户端指定的 session 会话 ID。 25 String getServletPath() //返回调用 JSP 的请求的 URL 的一部分。 26 String[] getParameterValues(String name) //返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。 27 boolean isSecure() //返回一个布尔值,指示请求是否使用安全通道,如 HTTPS。 28 int getContentLength() //以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。 29 int getIntHeader(String name) //返回指定的请求头的值为一个 int 值。 30 int getServerPort() //返回接收到这个请求的端口号。 31 int getParameterMap() //将参数封装成 Map 类型。
-
HttpServletRequest应用
(1)利用Referer请求头防止“盗链” DownManagerServlet.java————关键代码: response.setContentType("text/html;charset=utf-8"); PrintWriter out=response.getWriter(); String referer=request.getHeader("referer"); Strint sitePart="http://"+request.getServletName(); //判断referer头是否为空,这个头的首地址是否以sitePart开始的 if(referer != null && referer.startsWith(sitePart)){ //处理正在下载的请求 out.println("dealing download..."); }else{ //非法下载请求转发到download.html页面 RequestDispatcher rd=request.getRequestDispatcher("/download.html"); rd.forward(request,response); }
(2)download.html————关键代码: <a href="/chapter04/DownManagerServlet">download</a>
(3)请求转发与请求重定向的区别: 转发是在服务器端完成的,重定向是在客户端发生的; 转发的速度快,重定向速度慢; 转发是同一次请求,重定向是两次请求; 转发地址栏没有变化,重定向地址栏有变化; 转发必须是在同一台服务器下完成,重定向可以在不同的服务器下完成。
-
获取请求参数
1)编写 form.html <!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitionan//EN” “http://www.w3.org/TR/html4/loose.dtd”> <html> <head> <mea http-equiv=”Content-Type” content=”text/html;charset=UTF-8”> <title>Insert title here</title> </head> <body> <form action=”/chapter04/RequestParamsServlet” method=”post”> 用户名:<input type=”text” name=”username”><br /> 密 码<input type=”password” name=”password”><br /> 爱好:<input type=”checkbox” name=”hobby” value=”sing”>唱歌 <input type=”checkbox” name=”hobby” value=”dance”>跳舞 <input type=”checkbox” name=”hobby” value=”football”>足球<br /> <input type=”submit” value=”提交”> </form> </body> </html>
2)编写 RequestParamsServlet.java
-
解决请求参数的中文乱码问题
在(2)中由于HTML设置了浏览器在传递请求参数时,采用的编码方式是UTF-8,但在解码时采用的是默认的IS0-8859-1,如果“用户名”中输入中文,则会出现乱码问题。
解决办法:在servlet中设置request对象的解码方式即可。
在RequestParamsServlet.java的doGet方法首行插入如下代码:request.setCharacterEncoding(“utf-8”);通过Request对象传递参数 setAttribute()方法 该方法用于将一个对象与一个名称关联后存储进ServletRequest对象中,其完整语法定义为: public void setAttribute(java.lang.String name , java.lang.Object o); 需要注意的是,如果servletRequest对象中已经存在指定名称的属性,setAttribute()方法将会删除原来的属性,然后再添加新的属性。如果传递给setAttribute()方法的属性值对象为null,则删除指定名称的属性,这时的效果等同于removeAttribute()方法。 getAttribute()方法 该方法用于从ServletRequest对象中返回指定名称的属性对象,其完整的语法定义如下: public java.lang.Object getAttribute(java.lang.String name); removeAttribute()方法 该方法用于从ServletRequest对象中删除指定名称的属性,其完整的语法定义如下: public void removeAttribute(java.lang.String name); getAttributeNames()方法 该方法用于返回一个包含ServletRequest对象中所有属性名的Enumeration对象,在此基础上,可以对ServletRequest对象中的所有属性进行遍历处理,其完整的语法定义如下: public java.util.Enumeration getAttributeNames(); 需要注意的是,只有属于同一个请求中的数据才可以通过ServletRequest对象传递数据。具体语法以后详解,在此,了解即可。 RequestDispatcher对象的使用 该对象用来实现请求转发,前面已经提到过,这里再补充一个方法请求包含: include(ServletRequest request, ServletResponse response); 该方法用于将其他的资源作为当前响应内容包含进来。既包含了当前Servlet的响应信息,也包含了其他web资源所作出的响应信息。
End.