Servlet学习整理(四)—— ServletRequest和ServletResponse

基于Servlet的web应用交互过程

web应用一般是基于http的请求响应模式,一个使用servlet实现的web应用典型的交互过程如下:

 

1) 客户端向web服务器发起一个HTTP请求;
2) HTTP请求被web服务器接受,并移交给servlet引擎;
3) servlet引擎根据配置决定调用那个servlet,并把request对象、response对象传给它。
4) servlet通过request获取用户信息和请求的内容,servlet处理完请求后把要返回的信息放入response对象;
5)一旦servlet完成了请求的处理,servlet引擎就会刷新response,把控制权返回给web服务器;
6)web服务器将从servlet引擎获取的内容返回给客户端;

 

 

ServletRequest和ServletResponse

在Servlet规范中,ServletRequest代表客户端对服务器的请求,ServletResponse代表服务器给给客户端的响应;

 

其中,最重要的是HttpServletRequest 和 HttpServletResponse 这两个子接口;

 

这两个接口就是对http协议的请求和响应做面向对象的封装。

 

 

HttpServletRequest

在基于servlet的web应用交互中,客户端通过http协议发送请求至服务器,请求中会包含很多信息,如客户端的浏览器信息以及请求内容等等;这些信息被包含在http头和消息体中,并且以name-value的形式存在,一个name可以对应多个value。

 

web服务器接到客户端的http请求后会转发给内部的servlet容器处理;

 

serlve容器拿到请求后,会解析http请求包含的信息,然后将这些信息封装成HttpServletRequest对象,并传给合适的servlet实例进行处理;

 

1、请求参数

 

通过HttpServletRequest的下列方法,可以获取这些参数信息:

 

  • getParameter(String arg0)
  • getParameterNames()
  • getParameterValues(String arg0)

 

需要注意的是getParameterValues(String arg0)获取的是与arg0对应的value数组,getParameter(String arg0)获取的是value数组中的第一个值;

 

如果过URI中的参数为a=1;POST中的参数为a=2,a=3;请求中的参数a={1,2,3}。

 

如果想获取请求的路径参数,则必须通过解析方法getRequestURI()或getPathInfo()返回的字符串。

 

2、属性

 

request的属性就是一些对象;

 

容器可以将一些不能通过默认接口表达的信息通过属性的方式设置到request中;

 

也可以设置一些属性用来在servlet之间的通信

 

request对象中的关于属性方法有:

  • getAttribute(String arg0)
  • getAttributeNames()
  • setAttribute(String arg0,Object arg1)

与参数不同,这里一个属性名称只能关联一个value。

 

以“java.”或“javax.”为前缀的属性名是规范保留的,类似的“sun.”“com.sun”是sun公司的保留字,这些保留的前缀是不能使用的。

 

3、头信息

 

通过HttpServletRequest的下列方法,servlet可以获取http请求的头信息:

  • getHeader
  • getHeaders
  • getHeaderNames

getHeader 方法返回头的名称。一个名称可以关联多个头信息,如果在这种情况下,getHeader

方法返回第一个头信息。

 

getHeaders返回与一个名称关联的所有头信息存放在Enumeration对象中。

 

HttpServletRequest提供了一些提取头信息的类型转换方法,如:getIntHeader 把头信息中的数据转换成int型等。

 

4、请求路径

 

一个请求映射到一个servlet上,其请求路径包含了很多重要的部分,包括Context Path、Servlet Path、PathInfo。

 

其对应的方法有如下三个:

 

  • getContextPath
  • getServletPath
  • getPathInfo

 

除了编码方式不同外,下列等式是正确的:

 

requestURI = contextPath + servletPath + pathInfo

 

例如:

 

配置关系如下

 

Conteext Path: /catalog

 

Servlet:LawnServlet

Servlet Mapping Pattern:/lawn/*

 

Servlet:GardenServlet

Servlet Mapping Pattern:/garden/*

 

Servlet:JSPServlet

Servlet Mapping Pattern:*.jsp

 

注意下面的路径的组成

 

 

/catalog/lawn/index.htm;ContextPath:/catalog;ServletPath:/lawn;PathInfo:/index.html

 

/catalog/garden/implements/;ContextPath:/catalog;ServletPath:/garden;PathInfo:/implements/

 

/catalog/help/feedback.jsp;ContextPath:/catalog;ServletPath:/help/feedback.jsp;PathInfo:null

 

 

5、路径转换方法

 

在API中有两个简单的方法允许开发者获得文件系统的路径:

  • ServletContext.getRealPath
  • HttpServletRequet.getPathTranslated

getRealPath(String aPath)方法返回本地文件系统的绝对路径。

 

getPathTranslated方法计算出请求pathInfo中的绝对路径。

 

以上的两个方法,servlet引擎不能辨认文件的路径是否有效,当web应用调用一个不确定远程文件系统,或数据库路径中的文件时,会返回null。

 

 

6、cookie

 

 

HttpServletRequest接口中提供了getCookies方法来返回请求中的cookies数组;

 

在每次客户端请求时cookies数据就从客户端发送给服务器。

 

客户端返回的cookie信息是cookie的name和cookie的value。

 

当cookie被发送至浏览器时,cookie的信息就会被设置。

 

 

7、SSL属性

 

如果一个请求是通过一个安全协议进行传输的,例如HTTPS,那么这个信息必须通过ServletRequest的isSecure方法进行暴露。而且web容器必须将下列属性暴露给开发人员:

 

AttributeAtrribute NameJava type
Cipher suitejavax.servlet.request.cipher_suiteString
bit size of the algo-rithmjavax.servlet.request.key_sizeInteger

 

 

 

 

 

如果过一个请求中包含一个SSL证书信息,servlet引擎必须把它作为一个数组对象暴露给servlet开发者,可以通过ServletRequest属性中的javax.servlet.request.X509Certificate属性获得,该数组的类型为java.security.cert.X509Certificate。

 

数组排列的顺序是按照信任程度的升序,第一个证书是客户端设置的,第二个用来验证第一个,以此类推。

 

8、国际化

 

客户端可以通过http头信息的Accept-Language来告诉web服务器客户端想要哪一种语言的响应;

 

ServletRequest中提供的相关方法如下:

  • getLocale
  • getLocales

getLocale方法将返回客户端首选的Locale。

 

getLocales方法返回一个Enumeration,从首选的locale开始递减。

 

如果客户端没有制定首选的locale,servlet引擎一定要提供一个默认的locale供getLocale方法返回,getLocales方法必须包含一个默认的locale的locale element

 

 

9、请求数据的编码

 

 

有许多web浏览器不发送带有“content-type”头信息的字符编码限定符,而由读取http请求的代码来决定字符的编码方式。

 

默认情况下,如果客户端请求未定义编码限定符,容器(如tomcat)会用“ISO-8859-1”去创建request reader和解析POST的数据;

 

为了向开发者指明客户端没有发送字符编码信息的情况,容器对getCharacterEncoding方法返回null。

 

如果客户端不设置字符编码方式,并且request不是按照以上缺省编码方式(ISO-8859-1)来编码,则会发生问题。

 

为了解决这个问题,在接口ServletRequest中加入了一个新的方法setcharacterencoding(string encoding)。开发者可以调用这个方法来替换包容器提供的缺省字符编码方式。

 

但是,必须在从request中分析任何post数据或者读取任何输入之前调用这个方法。一旦数据已被读取,则调用这个方法将不会影响编码方式

 

注意:自从Tomcat5.x开始,GET和POST方法提交的信息,tomcat采用了不同的方式来处理编码,对于POST请求,Tomcat会仍然使用request.setCharacterEncoding方法所设置的编码来处理,如果未设置,则使用默认的iso-8859-1编码。而GET请求则不同,Tomcat对于GET请求并不会考虑使用request.setCharacterEncoding方法设置的编码,而会永远使用iso-8859-1编码

 

 

10、request对象的生命周期

 

request对象只有在servlet的service()方法或者filter的doFilter()方法中才有效;

 

为了避免创建request对象的性能消耗,容器会重用request对象

 

所以不能在上述范围以外持有对request的引用,否则会出现难以预料的错误。

HttpServletResponse

请求被servlet处理后,一般都会返回处理的结果信息,这些信息被封装到HttpServletResponse对象中并返回给servlet容器;

 

servlet容器将HttpServletResponse对象转化成http响应交给web服务器,web服务器得到响应后将其转发给客户端;

 

1、缓存

 

为了提高效率,servlet容器允许将发送给客户端的内容进行缓存;典型的服务器都会使用缓存,并且允许servlet指定缓存参数。

 

ServletRequest接口中关于缓存的方法如下:

  • getBufferSize
  • setBufferSize
  • isCommitted
  • Reset
  • resetBuffer
  • flushBuffer

这些方法只在servlet调用ServletOutputStream或者Writer之前有效。

 

当使用的缓存已满时,容器必须立刻刷新把缓存的内容发送到客户端,如果这是第一个被发送到客户端的数据,那么response也会被认为是已提交。

 

2、头信息

 

servlet可以通过ServletResponse接口设置响应的头信息,如下方法:

  • setHeader
  • addHeader
  • setIntHeader
  • setDateHeader
  • addIntHeader
  • addDateHeader

在response被提交前头信息必须被设置,否则无效。

 

开发人员有责任设置Content-Type头信息,用来表示servlet生成的内容类型。

 

HTTP1.1规范没有要求设置这个头信息,所以当开发人员没有设置这个类型时容器没必要设置一个默认值。

 

3、简单的方法

 

在HttpServletResponse接口中有下列简单的方法:

  • sendRedirect
  • sendError

sendRedirect方法会设置合适的头信息和消息体,使客户端重定向到两一个url;

 

如果参数是一个相对路径,底层容器会将其转换成绝对路径发送给客户端;如果转换失败则抛出IllegalArgumentException;

 

sendError方法同上。

 

4、国际化

 

servlet应该设置一个response的local和字符编码。

 

local使用ServletRespnse的setLocal方法,如果response被提交前没有设置local,容器的默认local会被使用。

 

setCharacterEncoding用来设置字符编码,response默认的编码方式是“ISO-8859-1”。

 

5、response对象的关闭

 

当一个response对象被关闭,容器必须立即将缓存中的内容发送给客户端。下列条件表示servlet已经满足请求的内容并关闭response对象:

 

  • servlet方法service结束;
  • response中通过setContentLength设置的指定数量的信息被写入到response;
  • 调用sendError方法;
  • 调用sendRedirect方法。

 

6、response对象的生命周期

 

同request对象的生命周期。

 

 

问题:

 

1、HttpServletRequest对象是怎么被容器重用的?

 

可以参考http://bbs.csdn.net/topics/300088535

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值