您的位置:首页 > 理论基础 > 计算机网络

J2EE HTTP的请求和响应原理,servlet处理原理

2013-12-03 16:05 645 查看
HTTP的请求与响应

    当发生下列事件时,浏览器都会向Web服务器发送HTTP请求:

    1.用户在网页上点击一个超链接;

    2.用户提交在网页上填好的表单;

    3.用户在浏览器地址栏中输入URL地址并回车。

    Servlet中对HTTP请求的处理过程:

    1.Web浏览器通过打开一个到Web服务器的TCP Socket套接字初始化一个HTTP请求,Socket的输入流包含了HTTP请求数据,Socket的输出流中包含了HTTP响应数。

    2.对于一个Servlet的每次访问请求,Web容器都会解析Socket输入流中的HTTP请求数据,创建一个请求对象,同时也创建一个响应对象。

    3.Web容器调用所请求的Servlet对象的service()方法,并将请求和响应对象作为参数传递给该方法,其中作为参数传递进来的响应对象就是HttpServletResponse对象,在Servlet对象的service()方法内部可以调用HttpServletRespnse对象的各种方法来创建响应消息。

    4.HttpServletResponse响应对象给Servlet提供一个PrintWriter对象,使Servlet可以产生响应消息体。

 

    用户在提交网页或表单时,浏览器向服务器发送的请求方法有以下几种:GET,HEAD,POST,PUT,DELETE,OPTION,REACE,在Servlet中每一种方法都对象一个请求方法,在使用时,我们一般只需在Servlet中实现需要的方法即可。请求方法最常用的是GET和POST方法,在以下这些条件下使用这两种方法:1.请求一个静态页面或图形文件时使用GET方法,因为仅需要发送文件名;2.发送大数据时,使用POST方法;3.上传文件时,使用POST方法;4.发送用户名、密码或其它保密信息时使用POST方法。

    在Servlet中我们需要访问请求行的信息,需要用请求对象调用以下的方法:

    getMethod():获取HTTP的请求方法,如:GET和POST等

   getRequestURI():获取请求的URI资源,如:/lovobook/index.html

    getRequestURL():获取请求的URL,包含协议名、服务器名或IP、端口号和请求资源但不包括查询字符串参数,如:http://127.0.0.1:8080/lovobook/index.html

    getQueryString():获取请求URL后面的查询字符串,如:name=aaa(POST没有这个方法)

    getProtocol():获取协议名和版本号,如:HTTP/1.1

    getContextPath():获取请求URI资源的上下文路径,始终以"/"开头,如:/lovobook

    getServletPath():获取Servlet的映射路径(参见http://hi.baidu.com/pangang107/blog/item/fd664d2d0cad45f48b139925.html中Servlet在web.xml中的部署)

    HTTP请求头通过HttpServletRequest对象的下列方法调用:

    getHeader(String name):返回请求头的值,如没有则返回null

    getHeaders(String name):如果请求的值有多个,用此方法返回一个Enumeration枚举包含这些值

    getHeaderNames():返回一个Enumeration包含所有的请求头的名称

    getIntHeader(String name):获取请求头的值,并转换为int类型,不存在则返回1,不能转换则跑异常,NumberFormatException

    getDateHeader(String name):获取特定请求头的值,并转换为Date类型

    通过请求对象HttpServletRequest调用以下方法获得请求参数,即表单数据:

    getParameter(String parameterName):通过参数名(区分大小写,与表单参数名相同)获得表单参数值,对GET/POST方法都适用,如果没有这个参数,则返回null

    getParameterValues(String parameterName):返回一个数组包含,这个参数名的所有值

    getParameterNames():返回一个Enumeration包含所有的参数名

    注意,如果上传文件时网页上表单应包含这些参数:

    <form type="file" method="post" enctype="mutipart/form-data">

    ....

    </form>

   请求转发可以通过javax.servlet.RequestDispatcher对象来实现,RequestDispatcher对象可以通过下列方式得到:

   getRequestDispatcher(String path):path路径必须以根目录"/"开始,并且可以导向Web应用程序中的任何资源,如:request.getRequestDispatcher("/HelloWorld"),容器会把这看作是从Web应用程序的根开始,如果不用"/"开始,容器会认为路径相对于原来的请求。

    getNamedDispatcher(String name):name名称必须在web.xml中servlet-name元素中定义的名称

    通过上下文对象ServletContext的getRequestDispatcher()得到,路径必须以根目录"/"开始

    RequestDispatcher对象提供了两种方法来包含不同的资源,以及将请求转发到不同资源

    forward(ServletRequest, ServerletResponse):派发请求和响应对象到RequestDispatcher对象所确定的新资源(Servlet,JSP,或HTML等),该资源通过利用请求和响应对象来处理HTTP请求,用法如:request.getRequestDispatcher("/success.html").forward(request,response);

    include(ServletRequest, ServletResponse):用法同forward()方法,有一些限制,它能包含服务器端的资源,被包含的资源不能改变响应状态代码或设置头信息,任何制式改变的尝试都会被忽略,一般情况下不用。

 

    响应状态码的设置一般使用response.setStaauts(int)方法,但HttpServletResponse定义了两种情况的专用方法:

    sendError(int code,String message):生成一个404应答,同时生成一个简短的html错误信息文档发送给客户端

    sendRedirect(String URL):生成一个302应答,同时在Location中指示新文档的URL地址,也就是重定向

    设置响应头信息的方法:

    containsHeader(String name):返回一个布尔值指示是否设定了指定的响应头

    setHeader(String name,String value):用一个给定的名称和字符串值设置响应头的通用方式,如过响应头已本设置,则会覆盖

    setIntHeader(String name,int value):同上,值为int类型

    setDateHeader(String name,long date):同上,date为日期值,日期值应该反应自1970-1-1日(GMT)以来的精确到毫秒的长整数

    addHeader(String name,String value):用于在response中添加一个给定名称和字符串的响应头,而不管是否已经存在同名的报头,因为该方法允许响应头有多个值

    addIntHeader(String name,int value):同上,值为int类型

    addDateHeader(String name,long date):同上,值为日期值的长整型数值

    setContentType(String mimetype):设置返回给客户端的MIME类型,大多数的Servlet都要用这个方法,用法如:responde.setContentType("text/html;charset=utf-8");

    addCookie(Cookie c):用于向Set-Cookie报头插入一Cookie,因为可以设置多个Cookie,所有没有setCookie方法。

    重定向的流程为:1.Web浏览器通过HTTP发送请求;2.服务器端响应的Servlet把真实连接URL地址和302响应码发送到客户端;3.响应结束,浏览器断开但前连接,然后在根据Location响应头的URL地址,重新发出HTTP请求。设置重定向:

    一般情况下使用绝对地址,并且是完整的URL路径来实现重定向,如:

   response.sendRedirect("http://127.0.0.1:8080/lovobook/bar.html");

    或者从Web应用程序的跟"/"开始,使用一个URL路径,如:

    response.sendRedirect("/lovobook/bar.html");

    Web应用程序可以部署到War文件中执行,HttpServletRequest的getContextPath()方法得到Web应用程序根目录的绝对路径,可以用于一个据对URL地址的联合,如:

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

    设置自动刷新和等待页(不能保证所有的浏览器都支持),代码:

    response.setHeader("Refresh","time;URL=url");

    如:response.setHeader("Refresh","10;URL=http://127.0.0.1/foo.html");

    得到请求中参数的原始字节数据,可以使用HttpServletRequest对象的getInputStream()方法得到字节流,或通过getReader()方法来得到字符流,通过这些来访问表单数据。

    得到请求之后服务器用字符流java.io.PrintWriter对象(通过response.getWriter()来得到)用来返回文本内容,字节流ServletOutputStream对象(通过response.getOutputStream()来得到)允许开发者用来操作字节流

 

1、  HttpServletRequest简介:

(1)WEB客户端发送给WEB服务器的HTTP请求消息分为三个部分:

a)         请求行 POST /demo/login HTTP/1.1

b)        请求消息头

c)        消息正文(也叫实体内容) username=xxxx&password=1234

(2)Servlet API中定义的ServletRequest接口类用于封装请求消息。

(3)HttpServletRequest是专用于HTTP协议的ServletRequest子接口,它用于封装HTTP请求消息。

(4)在service()方法内部调用HttpServletRequest对象的各种方法来获取请求消息。

2、获取请求行的相关信息

(1)HTTP请求消息的请求行包括请求方式、资源路径和HTTP协议版本:

       GET /it315/servlet/RequestURI?param1=a¶m2=b HTTP/1.1

(2)getMethod方法返回HTTP请求消息中的请求方式。

(3)getRequestURI方法返回请求行中的资源名部分。

(4)getQueryString 方法返回请求行中的参数部分。

(5)getProtocol方法返回请求行中的协议名和版本。

(6)getContextPath方法返回请求资源所属于的WEB应用程序的路径。

(7)getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。

(8)getPathTranslated方法返回URL中的额外路径信息所对应的资源的真实路径。

(9)getServletPath方法返回Servlet的名称或Servlet所映射的路径。 

3、获取请求行的相关信息---------举例

 

4、获取网络连接信息

(1)getRemoteAddr方法返回发出请求的客户机的IP地址,其格式为“192.168.0.3”这种形式的字符文本。 (*)

(2)getRemoteHost方法返回发出请求的客户机的完整主机名,即“pc1.it315.org”这种格式。

(3)getRemotePort方法返回发出请求的客户机所使用的网络接口的端口号。

(4)getLocalAddr方法返回WEB服务器上接收当前请求的网络接口的IP地址。

(5)getLocalName方法返回WEB服务器上接收当前请求的网络接口的IP地址所对应的主机名。

(6)getLocalPort方法返回WEB服务器上接收当前请求的网络接口的端口号。

(7)getServerName方法返回当前请求所指向的主机名。

(8)getServerPort方法返回当前请求所连接的服务器端口号。

(9)getScheme方法返回请求的协议名,例如http、https或ftp。

(10)getRequestURL方法返回客户端发出请求时的完整URL。   

5、获取所有请求头的编程实例

Enumeration headerNames = request.getHeaderNames();

while(headerNames.hasMoreElements())

{

       String headerName = (String)headerNames.nextElement();

       out.print(headerName + " : " + request.getHeader(headerName) + "<br>");

       /*如果要考虑同一个请求头名可能出现多次,

       那么应该用下面的代码段代替上面一行程序代码*/

       /*Enumeration values = request.getHeaders(headerName);

       while(values.hasMoreElements())

        {

              out.print(headerName + " : " + (String)values.nextElement() + "<br>");

       }*/



6、利用Referer请求头阻止“盗链”

String referrer = request.getHeader("referer");

String sitePart = "http://" + request.getServerName();

if(referrer!=null && referrer.startsWith(sitePart))

{

       //处理正当的下载请求,这里只进行示意

       out.println("dealing download ...");

}

else

{

       //非法下载请求跳转到本站的下载说明页

       RequestDispatcher rd = request.getRequestDispatcher("/down.html");

       rd.forward(request,response);

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐