(二)Servlet就是这样—Servlet中Response和Request

来源:互联网 发布:广州白云电气知乎 编辑:程序博客网 时间:2024/05/23 10:44

Servlet读书笔记系列文《Servlet就是这样》第二篇- Servlet中Response和Request

Servlet 是 J2EE 最重要的一部分,有了Servlet 你就是 J2EE 了,J2EE 的其他方面的内容择需采用。而 Servlet 规范你需要掌握的就是servletfilter这两项技术。绝大多数框架不是基于 servlet 就是基于 filter,如果它要在 Servlet 容器上运行,就永远也脱离不开这个模型。

Web 开发是离不开 HTTP 协议的,而Servlet规范其实就是对 HTTP 协议做面向对象的封装,HTTP协议中的请求和响应就是对应了HttpServletRequestHttpServletResponse这两个接口。

你可以通过HttpServletRequest 来获取所有请求相关的信息,包括 URI、Cookie、Header、请求参数等等,别无它路。因此当你使用某个框架时,你想获取HTTP请求的相关信息,只要拿到 HttpServletRequest 实例即可。

而 HttpServletResponse接口是用来生产 HTTP 响应,包含 Cookie、Header 以及响应的内容等等。

当浏览器(客户端)请求网页(向服务器请求数据)时,它会向 Web 服务器发送特定信息,这些信息不能被直接读取,因为这些信息是作为HTTP请求的头的一部分进行传输的。

一、           Servlet 客户端 HTTP 响应(Response)

1.   Response的继承结构

ServletResponse

--HttpServletResponse

Response代表响应,于是响应消息中的状态码、响应头、实体内容都可以由它进行操作,由此引伸出如下实验:

2.   利用Response输出数据到客户端

response.getOutputStream().write("中文".getBytes())输出数据,这是一个字节流,是什么字节输出什么字节,而浏览器默认用平台字节码打开服务器发送的数据,如果服务器端使用了非平台码去输出字符的字节数据就需要明确的指定浏览器编码时所用的码表,以防止乱码问题。response.addHeader("Content-type","text/html;charset=gb2312")

response.getWriter().write(“中文”);输出数据,这是一个字符流,response会将此字符进行转码操作后输出到浏览器,这个过程默认使用ISO8859-1码表,而ISO8859-1中没有中文,于是转码过程中用?代替了中文,导致乱码问题。可以指定response在转码过程中使用的目标码表,防止乱码。response.setCharcterEncoding("gb2312");

其实response还提供了setContentType("text/html;charset=gb2312")方法,此方法会设置content-type响应头,通知浏览器打开的码表,同时设置response的转码用码表,从而一行代码解决乱码。

3.   利用Response 设置 content-disposition头实现文件下载

设置响应头content-disposition为“attachment;filename=xxx.xxx,利用流将文件读取进来,再利用Response获取响应流输出,如果文件名为中文,一定要进行URL编码,编码所用的码表一定要是utf-8

4.   refresh头控制定时刷新

设置响应头Refresh为一个数值,指定多少秒后刷新当前页面

设置响应头Refresh为 3;url=/Day05/index.jsp,指定多少秒后刷新到哪个页面

可以用来实现注册后“注册成功,3秒后跳转到主页”的功能

在HTML可以利用<metahttp-equiv= "" content="">标签模拟响应头的功能。

5.   浏览器缓存资源

利用response设置expiresCache-ControlPragma实现浏览器是否缓存资源,这三个头都可以实现,但是由于历史原因,不同浏览器实现不同,所以一般配合这三个头使用

控制浏览器不要缓存(验证码图片不缓存)设置expires为0或-1设置Cache-Control为no-cache、Pragma为no-cache

控制浏览器缓存资源。即使不明确指定浏览器也会缓存资源,这种缓存没有截至日期。当在地址栏重新输入地址时会用缓存,但是当刷新或重新开浏览器访问时会重新获得资源。

如果明确指定缓存时间,浏览器缓存是,会有一个截至日期,在截至日期到期之前,当在地址栏重新输入地址或重新开浏览器访问时都会用缓存,而当刷新时会重新获得资源。

6.   Response实现请求重定向

古老方法:response.setStatus(302);response.addHeader("Location","URL");

快捷方式:response.sendRedirect("URL");

7.   Response注意的内容:

l  对于一次请求,Response的getOutputStream方法和getWriter方法是互斥,只能调用其一,特别注意forward后也不要违反这一规则。

l  利用Response输出数据的时候,并不是直接将数据写给浏览器,而是写到了Response的缓冲区中,等到整个service方法返回后,由服务器拿出response中的信息组成HTTP响应消息返回给浏览器。

l  service方法返回后,服务器会自己检查Response获取的OutputStream或者Writer是否关闭,如果没有关闭,服务器自动帮你关闭,一般情况下不要自己关闭这两个流。

8.   web服务器响应报头

当一个 Web 服务器响应一个 HTTP 请求时,响应通常包括一个状态行、一些响应报头、一个空行文档。一个典型的响应如下所示:

HTTP/1.1 200 OK

Content-Type: text/html

Header2: ...

...

HeaderN: ...

  (Blank Line)

<!doctype ...>

<html>

<head>...</head>

<body>

...

</body>

</html>

状态行包括 HTTP 版本(在本例中为HTTP/1.1)、一个状态码(在本例中为 200)和一个对应于状态码的短消息(在本例中为 OK)。

头信息

描述

Allow

这个头信息指定服务器支持的请求方法(GET、POST 等)。

Cache-Control

这个头信息指定响应文档在何种情况下可以安全地缓存。可能的值有:public、privateno-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 Extension)类型。

Expires

这个头信息指定内容过期的时间,在这之后内容不再被缓存。

Last-Modified

这个头信息指示文档的最后修改时间。然后,客户端可以缓存文件,并在以后的请求中通过 If-Modified-Since 请求头信息提供一个日期。

Location

这个头信息应被包含在所有的带有状态码的响应中。在 300s 内,这会通知浏览器文档的地址。浏览器会自动重新连接到这个位置,并获取新的文档。

Refresh

这个头信息指定浏览器应该如何尽快请求更新的页面。您可以指定页面刷新的秒数。

Retry-After

这个头信息可以与 503(Service Unavailable 服务不可用)响应配合使用,这会告诉客户端多久就可以重复它的请求。

Set-Cookie

这个头信息指定一个与页面关联的 cookie。

9.   Servlet 中设置 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)
为该响应设置状态码。

 

 

二、           Servlet 服务器 HTTP 请求(Request)

1.   获取客户机信息

getRequestURL方法返回客户端发出请求完整URL

getRequestURI方法返回请求行中的资源名部分,在权限控制中常用

getQueryString 方法返回请求行中的参数部分

getRemoteAddr方法返回发出请求的客户机的IP地址

getMethod得到客户机请求方式

getContextPath 获得当前web应用虚拟目录名称,特别重要!!!,工程中所有的路径请不要写死,其中的web应用名要以此方法去获得。

2.   获取请求头信息

getHeader(name)方法 --- String,获取指定名称的请求头的值

getHeaders(Stringname)方法 --- Enumeration<String> ,获取指定名称的请求头的值的集合,因为可能出现多个重名的请求头

getHeaderNames方法 ---Enumeration<String> ,获取所有请求头名称组成的集合

getIntHeader(name)方法  --- int ,获取int类型的请求头的值

getDateHeader(name)方法 --- long(日期对应毫秒) ,获取一个日期型的请求头的值,返回的是一个long值,从1970年1月1日0时开始的毫秒值

*实验:通过referer信息防盗链

                     Stringref = request.getHeader("Referer");

                     if(ref == null || ref == "" ||!ref.startsWith("http://localhost")) {

                            response.sendRedirect(request.getContextPath()+ "/homePage.html");

                     }else {

                            this.getServletContext().getRequestDispatcher("/WEB-INF/fengjie.html").forward(request,response);

                     }

3.   获取请求参数

getParameter(name)--- String 通过name获得值

getParameterValues(name)  --- String[ ] 通过name获得多值 checkbox

getParameterNames  --- Enumeration<String> 获得所有请求参数名称组成的枚举

getParameterMap  --- Map<String,String[ ]> 获取所有请求参数的组成的Map集合,注意,其中的键为String,值为String[]

获取请求参数时乱码问题:

浏览器发送的请求参数使用什么编码呢?当初浏览器打开网页时使用什么编码,发送就用什么编码。

服务器端获取到发过来的请求参数默认使用ISO8859-1进行解码操作,中文一定有乱码问题

对于Post方式提交的数据,可以设置request.setCharacterEncoding("gb2312");来明确指定获取请求参数时使用编码。但是此种方式只对Post方式提交有效。

对于Get方式提交的数据,就只能手动解决乱码:String newName = new String(name.getBytes("ISO8859-1"),"gb2312");此种方法对Post方式同样有效。

在tomcat的server.xml中可以配置http连接器的URIEncoding可以指定服务器在获取请求参数时默认使用的编码,从而一劳永逸的决绝获取请求参数时的乱码问题。也可以指定useBodyEncodingForURI参数,令request.setCharacterEncoding也对GET方式的请求起作用,但是这俩属性都不推荐使用,因为发布环境往往不允许修改此属性。

4.   利用请求域传递对象

生命周期:在service方法调用之前由服务器创建,传入service方法。整个请求结束,request生命结束。

作用范围:整个请求链

       作用:在整个请求链中共享数据,最常用的:在Servlet中处理好的数据要交给Jsp显示,此时参数就可以放置在Request域中带过去。

5.   request实现请求转发

ServletContext可以实现请求转发,request也可以。

在forward之前输入到response缓冲区中的数据,如果已经被发送到了客户端,forward将失败,抛出异常

在forward之前输入到response缓冲区中的数据,但是还没有发送到客户端,forward可以执行,但是缓冲区将被清空,之前的数据丢失。注意丢失的只是请求体中的内容,头内容仍然有效。

在一个Servlet中进行多次forward也是不行的,因为第一次forward结束,response已经被提交了,没有机会再forward了

总之,一条原则,一次请求只能有一次响应,响应提交走后,就再没有机会输出数据给浏览器了。

             

6.   RequestDispatcher进行include操作

forward没有办法将多个servlet的输出组成一个输出,因此RequestDispatcher提供了include方法,可以将多个Servlet的输出组成一个输出返回个浏览器

                     request.getRequestDispatcher("/servlet/Demo17Servlet").include(request,response);

                     response.getWriter().write("fromDemo16");

                     request.getRequestDispatcher("/servlet/Demo18Servlet").include(request,response);

常用在页面的固定部分单独写入一个文件,在多个页面中include进来简化代码量。

7.   请求报头   

以下是来自于浏览器端的重要头信息,是浏览器请求服务器的请求报头信息

头信息

描述

Accept

这个头信息指定浏览器或其他客户端可以处理的 MIME 类型。值 image/pngimage/jpeg 是最常见的两种可能值。

Accept-Charset

这个头信息指定浏览器可以用来显示信息的字符集。例如 ISO-8859-1。

Accept-Encoding

这个头信息指定浏览器知道如何处理的编码类型。值 gzipcompress 是最常见的两种可能值。

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

这个头信息识别发出请求的浏览器或其他客户端,并可以向不同类型的浏览器返回不同的内容。

8.   Servlet读取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()
返回接收到这个请求的端口号。

 


0 0
原创粉丝点击