HttpServletRequest

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpServletRequest相关的知识,希望对你有一定的参考价值。

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

//getQueryString 方法返回请求行中的参数部分。 http://localhost:8080/day06/servlet/RequestDemo1?name=aaaa
System.out.println(request.getQueryString());输出name=aaaa,这里与asp.net中有所不同。

/*获取请求头
        Enumeration e = request.getHeaderNames();
        while(e.hasMoreElements()){
            String name = (String) e.nextElement();
            String value = request.getHeader(name);
            System.out.println(name + "=" + value);
        }
        */
        for(Enumeration e = request.getHeaderNames();e.hasMoreElements();){
            String name = (String) e.nextElement();
            String value = request.getHeader(name);
            System.out.println(name + "=" + value);
        }

 

//获取客户机带过来的数据

  getParameter(name)方法
  getParameterValues(String name)方法
  getParameterNames方法
  getParameterMap方法 //
  getInputStream()

 

public class RequestDemo3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //1.
        //http://localhost:8080/day06/servlet/RequestDemo3?name=xxx
        String value = request.getParameter("name");
        System.out.println(value);
        
        System.out.println("-----");
        
        
        //2.
        //http://localhost:8080/day06/servlet/RequestDemo3?name=xxx&password=123
        Enumeration e = request.getParameterNames();
        while(e.hasMoreElements()){
            String name = (String) e.nextElement();
            value = request.getParameter(name);
            System.out.println(name + "=" + value );
        }
        
        System.out.println("----");
        
        //3.
        //http://localhost:8080/day06/servlet/RequestDemo3?name=xxx&name=yyyy
        String values[] = request.getParameterValues("name");//用在复选框上checkbox,可以选中多个值,提交到服务端。比如表单中选择爱好等
        /*if(values!=null){//一般要做判断,可能不选择任何一个
            for(String value1 : values){
                System.out.println(value1);
            }
        }*/  
        for(int i=0;values!=null && i<values.length;i++){   //这样的代码可以预防null指针的问题
            System.out.println(values[i]);
        }//推荐这种方法。
        
        
        System.out.println("--map--");
        //4.
        // http://localhost:8080/day06/servlet/RequestDemo3?a=1&a=2&b=1
        Map<String,String[]> map = request.getParameterMap();  //a=1&a=2&b=1
        for(Map.Entry<String, String[]> entry : map.entrySet()){
            String name  = entry.getKey();
            values = entry.getValue();   //[]
            for(int i=0;values!=null && i<values.length;i++){
                value = values[i];
                System.out.println(name + "=" + value);
            }
        }
        
        //通过流获取
        InputStream in = request.getInputStream();  //这种方式只用在文件上传上
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 

 

Request常见应用:

 

防盗链:

//防盗链
public class RequestDemo4 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        String referer = request.getHeader("referer");//从哪个网站链接到本页面,如果是点击超链接,referer为null,如果是从百度链接进来,referer为www.baidu.com
        if(referer==null || !referer.startsWith("http://localhost")){
            response.sendRedirect("/day06/index.jsp");
            return;
        }
        String data = "slkjdlsjfljadljslfjljlsjaqaa";
        response.getWriter().write(data);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 

获取表单提交的数据

 

        String username = request.getParameter("username");
        if(username!=null && !username.trim().equals("")){
            System.out.println("username="+  username);
        }
         
        String gender = request.getParameter("gender");  //radio
        if(gender!=null){
            System.out.println("gender=" + gender );
        }
         
        String likes[] = request.getParameterValues("like");//checkbox
        for(int i=0;likes!=null && i<likes.length;i++){
            System.out.println("like=" + likes[i]);
        }
         

 

技术分享

出现乱码的原因:当客户端浏览器提交中文数据的时候,会查浏览器使用的码表,把提交的数据转成相应的字符编码提交给服务器,服务器获取数据后,会把编码的数据封装到request对象中,在servlet中使用getParameter获取request中的数据时,服务器默认的会去查ISO8859-1码表得到string类型数据返回,如果客户端使用的不是ISO8859-1码表提交数据。就会出现乱码。

解决乱码的办法是:告诉服务器使用 客户端浏览器提交数据时采用的码表就可以解决。这只对post有限,get方式提交要手工处理

另外还有一种解决办法:更改tomcat服务器的配置,但不建议这么做。

 

//解决get和post提交的乱码
public class RequestDemo6 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    
        if(request.getMethod().equals("POST")){
            //request.setCharacterEncoding("UTF-8");  //只对post提交有效,对get无效
            request.setCharacterEncoding("UTF-8"); 
            String username = request.getParameter("username");
            System.out.println(username);
        }else{
            //如为get提交,username中的乱码想正常,只能采用如下方式手工处理
            String username = request.getParameter("username");
            username = new String(username.getBytes("iso8859-1"),"UTF-8");
            System.out.println(username);
        }

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 

 

URL编码: 超链接中提交的数据如果包含中文,一定要url编码 

<a href="/day06/servlet/RequestDemo7?name=中国">点点</a> ---------这里没有采用url编码,必须使用下面的方式获取。get方式提交

public class RequestDemo7 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        
        String username = request.getParameter("name");
        username = new String(username.getBytes("iso8859-1"),"UTF-8");
        System.out.println(username);
         
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 

请求转发:

request对象实现请求转发:请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。
请求转发的应用场景:MVC设计模式
request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发

 

request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。
  setAttribute方法
  getAttribute方法
  removeAttribute方法
  getAttributeNames方法

 

 //请求转发(mvc设计模式)
/*
    在mvc设计模式下,都是servlet处理用户请求,并产生用户想看的数据,然后转交给jsp显示,转交给jsp显示时,
    会把数据存在request域里面带给jsp  (请求转发是同一个请求,共享request与response,不同于重定向)
*/
public class RequestDemo8 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        //方式1   通过ServletContext对象获取转发对象
        this.getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
        
        String data = "a";
        //方式2   通过request对象获取转发对象    request也是个容器,可以通过setAttribute来存数据,转发给jsp可以获取
        request.setAttribute("data", data);  //存属性    一般不使用servletcontext的setAttribute来存,因为会覆盖,servletcontex是域对象,所有servlet共享
        request.getRequestDispatcher("/index.jsp").forward(request, response);
        
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

 

 

请求转发的细节:

forward方法用于将请求转发到RequestDispatcher对象封装的资源。
如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常。
如果在调用forward方法之前向Servlet引擎的缓冲区(response)中写入了内容,只要写入到缓冲区中的内容还没有被真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空,但是,已写入到HttpServletResponse对象中的响应头字段信息保持有效。

 

请求重定向和请求转发的区别:

一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发。
一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源,称之为请求重定向。

 

RequestDispatcher.forward方法只能将请求转发给同一个WEB应用中的组件;而HttpServletResponse.sendRedirect 方法还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。

 


如果传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
调用HttpServletResponse.sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会发生改变,由初始的URL地址变成重定向的目标URL;调用RequestDispatcher.forward 方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变。


HttpServletResponse.sendRedirect方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;RequestDispatcher.forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道在服务器程序内部发生了转发行为。


RequestDispatcher.forward方法的调用者与被调用者之间共享相同的request对象和response对象,它们属于同一个访问请求和响应过程;而HttpServletResponse.sendRedirect方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。

 

 

include方法:
RequestDispatcher.include方法用于将RequestDispatcher对象封装的资源内容作为当前响应内容的一部分包含进来,从而实现可编程的服务器端包含功能。
被包含的Servlet程序不能改变响应消息的状态码和响应头,

以上是关于HttpServletRequest的主要内容,如果未能解决你的问题,请参考以下文章

httpservletrequest - 创建新会话/更改会话 ID

需要 javax.servlet.http.HttpServletRequest 的 JAR 文件 [重复]

从 HttpServletRequest 获取 POST 请求正文

为啥 HttpServletRequest 输入流为空?

如何从 HttpServletRequest 获取完整的 url? [复制]

HttpServletRequest获取请求路径