HttpServletRequest

1、HttpServletRequest

web客户端发送给web服务器的HTTP请求消息能够分为三个部分:请求行、请求消息头、消息正文(也叫实体内容)。Servlet程序经过调用ServletRequest对象的方法能够获知客户端的请求信息,以及客户机和服务器的网络环境信息,例如获取客户发送的请求消息的各个部分和客户端IP地址。HttpServletRequest是专用于HTTP协议的ServletRequest子接口,它用于封装HTTP请求消息,增长了获取HTTP协议专有的头信息的方法,以及获取HTTP请求消息参数的功能。html

2、请求消息

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

HTTP请求消息的请求行能够分为三个部分:请求方式、资源路径和HTTP协议版本,如:java

GET    /project/servlet/RequestURI?parm1=a&parm2=b    HTTP/1.1web

RequestLineServlet.java数组

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RequestLineServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=GB2312"); 
        PrintWriter out = response.getWriter();
        
        out.println("getMethod:" + request.getMethod() + "<br>");
        // 返回位于主机和端口以后、参数部分以前的那部份内容
        out.println("getRequestURI:" + request.getRequestURI() + "<br>");
        // 返回参数部分,无参数返回null
        out.println("getQueryString:" + request.getQueryString() + "<br>");
        // 返回协议名和版本号
        out.println("getProtocol:" + request.getProtocol() + "<br>");
        // 返回Web应用程序的路径(虚拟目录),这个路径以“/”开头
        out.println("getContextPath:" + request.getContextPath() + "<br>");
        // 返回servlet映射的路径(web.xml的url-pattern属性)
        out.println("getServletPath:" + request.getServletPath() + "<br>");
    }
}

 

注:URL和URI的区别,可看http://www.cnblogs.com/gaojing/archive/2012/02/04/2413626.html浏览器

二、获取请求头的信息

ServletRequest和HttpServletRequest接口中定义了若干用于读取HTTP请求消息中的头字段的方法,其中的getHeader方法是一个通用的方法,能够读取全部的头字段。服务器

(1)、获取全部请求头信息网络

RequestHeadersServlet.javaapp

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RequestHeadersServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=GB2312");
        PrintWriter out = response.getWriter();
        
        Enumeration<?> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String headerName = (String)headerNames.nextElement();
            // 同一个请求头名可能出现屡次
            Enumeration<?> values = request.getHeaders(headerName);
            while(values.hasMoreElements()) {
                out.println(headerName + ":" + (String)values.nextElement() + "<br>");
            }
        }
    }
}

 

在浏览器输入访问地址:http://localhost:8888/requestHeadersServlet/servlet/RequestHeadersServletide

现增长一个html文件,从它连接到该Servlet,访问referer.html:编码

<a href="servlet/RequestHeadersServlet">referer test</a>

 

访问referer.html:

点击超连接,再次访问RequestHeadersServlet

注意观察:请求消息包含了referer请求头。

(2)盗链

关于“盗链”:http://baike.baidu.com/link?url=UpFE0AJdwVL2ESHqD6aF1N28Zmwi47RwoKzs50NI2t1HKBR6paci_NFhbv78hW-x

为了防止“盗链”,须要检查请求的来路,只接受本站内的页面连接进来的下载请求,而阻止其余站点的页面连接进来的下载请求。要实现这样功能,就须要检查请求消息的referer头字段是否与本站匹配。

DownManagerServlet.java

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
    public class DownManagerServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=GB2312");
        String referer = request.getHeader("referer");
        String sitePart = "http://" + request.getServerName();
        PrintWriter out = response.getWriter();
        
        // 增长if判断是为了下载请求必须经过本站的下载页面连接进来,也就是防止盗链
        if(referer != null && referer.startsWith(sitePart)) {
            // 处理正当的下载请求,这里只是示意
            out.println("dealing download ...");
        } else {
            // 非法下载请求(即referer为空或不匹配sitePart)跳转到本站的下载说明页
            response.sendRedirect("../down.html");
        }
    }
}

 

down.html

<a href="servlet/DownManagerServlet">down</a>

 

在浏览器输入访问地址:localhost:8888/downManagerServlet/servlet/DownManagerServlet

由于请求消息不含referer请求头,即DownManagerServlet代码中的referer为空,跳转到down.html

点击超连接,再次访问DownManagerServlet,因为这时的请求消息包含有referer请求且值与DownManagerServlet位于同一Web站点,DownManagerServlet接受下载请求。

三、获取请求消息的实体内容

以POST方式提交HTML的FORM表单时,其中的表单字段元素信息都将做为HTTP消息的实体内容(消息正文)发送给Web服务器。对应HTTP请求消息的中的实体内容,ServletRequest以输入流的方式提供给Servlet程序读取,ServletRequest接口中定义了一个getInputStream方法来返回这个字节输入流对象。为了方便读取纯文本形式的实体内容,ServletRequest接口也定义了一个getReader方法,以返回一个表明实体内容的字符输入流对象。

getInputStream与getReader方法

  • getInputStream返回输入流对象类型为ServletInputStream,若是实体内容中包含二进制数据,那么只能使用getInputStream方法返回的输入流对象来读取实体内容。

  • getReader则返回一个BufferedReader对象。

  • 调用了二者任意一个方法后,就不能再调用另外一方法。

3、获取请求参数

HttpServletRequest对象的最基本和最普遍应用就是获取浏览器传递给Web服务器的参数信息,这些参数信息既能够是HTTP请求消息的请求行中的URL地址后的附加信息,又能够是Post方式下application/x-www-form-urlencoded编码格式的实体内容。那么,如何获取这两种参数?

ServletRequest和HttpServletRequest接口中定义了若干方法,这些方法除了能读取HTTP请求消息的请求行的URL地址后的附件信息外,还能读取Post方式下的application/x-www-form-urlencoded编码格式的实体内容。

  • getParameter方法:若是请求消息中没有包含指定名称的参数,该方法返回null,即getParameter("firstname"),不存在这个参数返回null;若是指定名称的参数存在但没有设置值,返回一个空串;若是包含多个指定名称相同的参数,返回第一个出现的参数值。另外,该方法对参数名大小写敏感。

  • getParameterValues方法:该方法用于获取某个指定名称的全部参数的值,并以一个String数组的形式返回这些参数值。若是参数值只有一个,返回的数组的长度就为1,其中包含的元素值与getParameter方法返回的值同样。

  • getParameterNames方法:返回一个包含请求消息中全部参数名的Enumeration对象。

  • getParameterMap方法:返回一个将请求消息中全部参数名和值装进Map的Map对象

问:何为隐藏表单字段?

答:在form表单中可使用隐藏表单字段元素向服务器传递参数信息,浏览器在网页上不会显示出隐藏表单字段元素,但当提交表单时,浏览器会将这个隐藏表单字段元素的name属性和value属性做为参数传递给web服务器。

4、利用请求域属性传递消息

ServletRequest接口的实现类一般都是采用一个HashMap对象来存储某些对象,setAttribute方法就是向这个HashMap对象中增长与某个名称绑定的对象,getAttribute方法则是根据名称从这个HashMap对象中检索对象。这种存储在ServletRequest对象中的对象称之为请求域属性。

  • setAttribute(String name, Object o),若是ServletRequest对象中已经存在指定名称的属性,若属性值对象为null则至关于removeAttribute,不然即覆盖原来对象。

  • getAttribute(String name),返回指定名称的属性对象。

  • removeAttribute(String name),删除指定名称的属性对象。

  • getAttributeNames(),返回一个包含ServletRequest对象中全部属性名的Enumeration对象。

相关文章
相关标签/搜索