HttpServletRequest

Posted hzhjxx

tags:

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

1 HttpServletRequest概述

在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。

service方法中的request的类型是ServletRequest,

doGet/doPost方法的request的类型是HttpServletRequest,

HttpServletRequest是ServletRequest的子接口,功能和方法更加强大

 

1.1 request的运行流程

技术分享图片 

1.2通过抓包工具抓取Http请求

 技术分享图片

 

因为request代表请求,所以可以通过该对象分别获得Http请求的请求行,请求头和请求体:

 

2通过request获得请求行

1)获得客户端的请求方式:String getMethod()

2)获得请求的资源:

String getRequestURI()  绝对路径或相对路径或网络地址

StringBuffer getRequestURL() 网络地址

String getContextPath() ---web应用的名称(重要)因为项目名有可能改,所以不能写死

String getQueryString() ---- get提交url地址后的参数字符串,只有get请求才有

request.getRemoteAddr() --- 获得访问的客户端IP地址

 

例:

建一个login.jsp:

<form action="/20190111WEB/LoginServlet" method="get">
    用户名:<input type="text" name="username" /><br />
    密码:<input type="password" name="password" /><br />
    <input type="submit" value="提交" />
</form>

 

建一个LoginServlet:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求行中内容
        //1获取请求方式
        String method=request.getMethod();
        System.out.println("请求方式为"+method);        
        //2获得请求资源的相关内容
        String requestURI=request.getRequestURI();
        StringBuffer requestURL=request.getRequestURL();
        System.out.println("URI"+requestURI);
        System.out.println("URL"+requestURL);
        //3获得web应用名称
        String contextPath=request.getContextPath();
        System.out.println("web应用名称"+contextPath);
        //4获取get方式提交的url后的参数字符串
        String queryString=request.getQueryString();
        System.out.println("get提交的参数"+queryString);
        //5获取访问者的ip地址
        String ip=request.getRemoteAddr();
        System.out.println("ip为"+ip);
    }

技术分享图片

 

3通过request获得请求头

3.1常用方法

String getHeader(String name)

long getDateHeader(String name)

Enumeration getHeaderNames() 枚举

Enumeration getHeaders(String name)

int getIntHeader(String name)

 

例:HeaderServlet

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //通过枚举获得所有头的名称
        Enumeration<String> headNames=request.getHeaderNames();
        while(headNames.hasMoreElements()){
            String headerName=headNames.nextElement();
            String headerValue=request.getHeader(headerName);
            System.out.println(headerName+":"+headerValue);
        }
    }

技术分享图片

 

3.2 referer头做防盗链

referer头的作用:获取该访问的的来源

 

例:news.jsp:

<a href="/20190111WEB/ReferServlet">某某新闻标题</a>

 

ReferServlet:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求头中的referer
        String referer=request.getHeader("referer");
        //判断referer
        if(referer!=null&&referer.startsWith("http://localhost")){
            response.sendRedirect("/20190111WEB/login.jsp");
        }else{
            //解决中文乱码
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("你是盗链者,可耻");
        }
    }

技术分享图片 

 技术分享图片

 

如果改成:(随意改)

技术分享图片 

 技术分享图片

 

4通过request获得请求体

请求体中的内容是通过post提交的请求参数,格式是:

username=zhangsan&password=123&hobby=football&hobby=basketball

key                 value

username      [zhangsan]

password       [123]

hobby            [football,basketball]

 

4.1获得请求参数方法

String getParameter(String name)

String[] getParameterValues(String name)(多选可用这个)

Map<String,String[]> getParameterMap()

  一个key对应多个value,例如多选,就可以用map

  Map集合作用:例如注册,封装成一个对象,传到后台

 

get请求方式的请求参数上述的方法一样可以获得

 

4.2中文乱码问题

1)解决post提交方式的乱码:request.setCharacterEncoding("UTF-8"); 

2)解决get提交的方式的乱码:

因为get的参数是从地址栏获得,所以一次只能解决一个字符串的中文乱码,

先获得参数,用iso8859-1编码,getbytes("iso8859-1")

再用utf-8解码:new String(byte[], "utf-8")

完整为:

parameter = new String(parameter.getbytes("iso8859-1"),"utf-8");

 

表单一般不用get提交,所以不常用

 

例:

Login.jsp:

<form action="/20190111WEB/BodyServlet" method="post">
        用户名:<input type="text" name="username" /><br />
        密码:<input type="password" name="password" /><br />
        爱好:
        <input type="checkbox" name="hobby" value="zq"/>足球
        <input type="checkbox" name="hobby" value="lq"/>蓝球
        <input type="checkbox" name="hobby" value="ppq"/>乒乓球
        <input type="checkbox" name="hobby" value="pq"/>排球<br>            
        <input type="submit" value="提交" />
    </form>

 

BodyServlet:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决中文乱码-post方式提交
        request.setCharacterEncoding("utf-8");            
        //获取request请求体的指定参数
        String uesrname=request.getParameter("username");    
        //解决中文乱码-get方式
        uesrname=new String(uesrname.getBytes("iso8859-1"),"utf-8");            
        String password=request.getParameter("password");
        System.out.println(uesrname+":"+password);
        System.out.println("-------------");        
        //获取所有参数的map集合
        Map<String,String[]> map=request.getParameterMap();
        Set<String> set=map.keySet();
        for(String s:set){
            //获取name值
            String name=s;
            System.out.print(name+":");
            //获取value数据
            String[] values=map.get(name);
            //遍历数组
            for(String v:values){                
                System.out.println(v);
            }
            System.out.println("-------------");
        }        
    }

技术分享图片

 

5 request是一个域对象

5.1方法和作用范围

request对象也是一个存储数据的区域对象,所以也具有如下方法:

setAttribute(String name, Object o)

getAttribute(String name)

removeAttribute(String name)

 

request域的作用范围:一次请求中

 

5.2 ServletContext域与Request域的生命周期比较

ServletContext:

  创建:服务器启动

  销毁:服务器关闭

  域的作用范围:整个web应用

request:

  创建:访问时(请求时)创建request

  销毁:响应结束request销毁

  域的作用范围:一次请求中

 

6 request完成请求转发

6.1方法

获得请求转发器----path是转发的地址

  RequestDispatcher getRequestDispatcher(String path)

通过转发器对象转发

  requestDispathcer.forward(ServletRequest request, ServletResponse response)

 

例:

Servlet01:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //请求转发        
        //设置一个值
        request.setAttribute("name", "zhangsan");        
        //1获得转发器
        RequestDispatcher dis=request.getRequestDispatcher("/Servlet02"); //因为是在项目内部,所以不用写项目名
        //2调用转发方法
        dis.forward(request, response);        
    }

 

Servlet02:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name=(String)request.getAttribute("name");
        response.getWriter().write("hello! "+name+",this is Servlet02...");
    }

技术分享图片

 

6.2请求转发与重定向的区别

相同点:都跳转

不同点:

1)请求转发是Request对象的,重定向是response对象的

2)重定向两次请求,转发一次请求

3)重定向地址栏的地址变化,转发地址不变

4)重新定向可以访问外部网站,转发只能访问内部资源

5)转发的性能要优于重定向(因为只请求一次)

 

需要带值,用请求转发

不需要,可以用重定向

 

6.3客户端地址与服务器端地址的写法

客户端地址:

  是客户端去访问服务器的地址,是服务器外部的地址

  所以要写上web应用名称

服务器端地址:

  服务器内部资源的跳转的地址,所以不需要写web应用的名称

 

7注册实例

1)准备数据库和表

2)建项目,分包,导入jsp页面,添加工具类(注意修改数据库名)和jdbc jar包

3)建Users实体类

4)register.jsp上添加form的action和method,表单元素加上name,必须要和Users实体类对应上

5)编写RegisterServlet

 

 1.BeanUtils工具实现自动映射封装:

map中的数据根据key与实体的属性对应关系进行封装,所在要保证jsp表单中的name和Users中的成员变量一样。

只要key的名字与实体属性的名字一样,就会自动封装到实体中

 

把两个jar包导进去

技术分享图片 

//创建对象

Users users=new Users();

//调用方法

BeanUtils.populate(users, map);

 

2.手动封装uid--利用工具UUID,随机生成不重复的32位字符串,但是经过java代码生成生是36位

users.setUid(UUID.randomUUID().toString());

(返回值是UUID对象,再toString成字符串)

 

6)登录错误提示信息的处理

带着值,所以用请求转发

LoginServlet中添加一个loginInfo,

Login.jsp页面中加上:

<%=request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo")%>

 

完整项目源码:

 (过两天贴上)

 

重点总结:

1 通过request获得请求行

request.getMethod()

request.getRequestURI()

request.getRequestURL()

request.getContextPath()

request.getRemoteAddr()

 

2 通过request获得请求头

request.getHeader(name)

 

3 通过request获得请求体

String request.getParameter(name)

Map<String,String[]> request.getParameterMap();

String[] request.getParameterValues(name);

注意:客户端发送的参数,到服务器端都是字符串

 

4 中文乱码问题

post方式:

request.setCharacterEncoding(“UTF-8”);

get方式:

parameter = new String(parameter.getBytes(“iso8859-1”),”UTF-8”);

 

5 request是一个域对象,方法和作用范围

setAttribute(String name, Object o)

getAttribute(String name)

removeAttribute(String name)

作用范围:一次请求中

 

6请求转发

request.getRequestDispatcher(转发的地址).forward(request, response);

 

7注册实例

BeanUtils工具进行对象封装

UUID工具封装uid

错误提示信息的处理

 

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

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

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

从 HttpServletRequest 获取 POST 请求正文

为啥 HttpServletRequest 输入流为空?

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

HttpServletRequest获取请求路径