【JavaWeb】Request对象详解

HTTP之Request:接上一篇博文HTTP协议详细.


一.Request请求

1.Request对象和Response对象的原理

  • request和response对象是由服务器创建的。我们来使用它们
  • request对象是来获取请求消息,response对象是来设置响应消息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hBSeZsBR-1597939317911)(D:\文档存储\JAVA\技术路线\阶段2 JavaWeb+黑马旅游网\07 -Request和Respons\笔记图\request&response对象原理.bmp)]

2.Request对象继承体系结构

ServletRequest – 接口
| 继承
HttpServletRequest – 接口
| 实现
org.apache.catalina.connector.RequestFacade 类(tomcat内部)


3.Request功能

3.1 获取请求消息数据

1.获取请求行数据

//请求行数据
GET /Http_war_exploded/RequestDemo1?name=dong HTTP/1.1

常用获取请求行数据的方法:通过request对象调用方法

  • String getMethod():获取请求方式get或post
  • String getContextPath():**(重点)**获取虚拟目录
  • String getServletPath():获取Servlet路径
  • String getQueryString():获取get方式所有请求参数
  • String getRequestURI():**(重点)**获取请求URI(统一资源标识符)
    例如:/Http_war_exploded/RequestDemo1、共和国,资源范围大
  • StringBuffer getRequestURL():获取请求URL(统一资源定位符)
    例如:http://localhost:8080/Http_war_exploded/RequestDemo1、中华人民共和国,资源范围小
  • String getProtocol():获取协议及版本
  • String getRemoteAddr():获取客户机的IP地址

代码演示:

先创建一个form表单用于提交数据

<form action="/Http_war_exploded/RequestDemo1" method="GET">
    <input name="username">
    <input type="submit" value="提交">
</form>

再创建访问的Servlet,在浏览器上访问创建的Servlet

@WebServlet(name = "RequestDemo1", urlPatterns = "/RequestDemo1")
public class RequestDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1. 获取请求方式 :GET
        String method = request.getMethod();
        System.out.println(method);
        
        //2.(*)获取虚拟目录:/Http_war_exploded
        String contextPath = request.getContextPath();
        System.out.println(contextPath);
        
        //3. 获取Servlet路径: /RequestDemo1
        String servletPath = request.getServletPath();
        System.out.println(servletPath);
        
        //4. 获取get方式请求参数:username=dong
        String queryString = request.getQueryString();
        System.out.println(queryString);
        
        //5.(*)获取请求URI:/Http_war_exploded/RequestDemo1
        String requestURI = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURI);// /Http_war_exploded/RequestDemo1
        System.out.println(requestURL);// http://localhost:8080/Http_war_exploded/RequestDemo1
        
        //6. 获取协议及版本:HTTP/1.1
        String protocol = request.getProtocol();
        System.out.println(protocol);
        //7. 获取客户机的IP地址:0:0:0:0:0:0:0:1
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);
    }
}

3.2 获取请求头数据

方法:

  • String getHeader(String name); (重点)通过请求头的名称获取请求头的值
  • Enumeration<String> getHeaderNames():获取所有的请求头名称的迭代器(与枚举类似)

代码演示1:获取所有请求头内容

@WebServlet(name = "RequestDemo2", urlPatterns = "/RequestDemo2")
public class RequestDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 演示获取请求头数据
         */
        //1.获取所有请求头名称
        Enumeration<String> headerNames = request.getHeaderNames();
        //2.遍历
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            //根据名称获取请求头的值
            String value = request.getHeader(name);
            System.out.println(name + "---" + value);
        }
    }
}

从浏览器访问http://localhost:8080/Http_war_exploded/RequestDemo2,控制台打印:

在这里插入图片描述

代码演示2:获取请求头数据中user-agent的内容,判断agent的浏览器版本

@WebServlet(name = "RequestDemo3", urlPatterns = "/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 演示获取请求头数据中:user-agent
         * 如果请求头user-agent的内容中包含了谷歌的浏览器的关键字Chrome,就可以认为使用的是谷歌浏览器
         */
        String agent = request.getHeader("user-agent");
        //判断agent的浏览器版本
        if(agent.contains("Chrome")){
            //谷歌
            System.out.println("谷歌来了...");
        }else if(agent.contains("Firefox")){
            //火狐
            System.out.println("火狐来了...");
        }
    }
}

代码演示3:获取请求头数据中referer的内容,防盗链应用,可以知道访问从哪里URL过来的。

比如我从一个login.html登录页面访问RequestDemo4,那么请求头中的referer的值就是:http://localhost:8080/Http_war_exploded/login.html,referer中包含正确的URI的内容/Http_war_exploded,就是正确访问。

如果从其它页面访问RequestDemo4referer中不会包含/Http_war_exploded,但是又能访问到RequestDemo4,这就属于盗链。我们要防止这种现象,防止山寨网站嘛。

referer的值为空的情况:比如直接在浏览器地址栏中直接输入http://localhost:8080/Http_war_exploded/RequestDemo4访问,referer的值就是null,因为它并没有从哪里来,直接访问,所以为null。

@WebServlet(name = "RequestDemo4", urlPatterns = "/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 演示获取请求头数据中:referer
         */
        String referer = request.getHeader("referer");
        System.out.println(referer);//http://localhost:8080/Http_war_exploded/login.html

        //防盗链
        if(referer != null ){
            //如果referer中包含正确的URI的内容,就是正确访问
            if(referer.contains("/Http_war_exploded")){
                //正常访问
                // System.out.println("播放电影....");
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("播放电影....");
            }else{
                //盗链
                //System.out.println("想看电影吗?来优酷吧...");
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().write("想看电影吗?来优酷吧...");
            }
        }
    }
}

在这里插入图片描述


3.3 获取请求体数据

请求体:只有POST请求方式,才有请求体,GET方式没有。在请求体中封装了POST请求的请求参数。

获取步骤

1.获取流对象

底层是通过IO流形式传递数据,方法有:

  • BufferedReader getReader():获取字符输入流,只能操作字符数据(包括中文)
  • ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据(包括一些文件,图音视频),在文件上传知识点详细讲解。

2.再从流对象中拿数据

  • 读取数据使用读取相应IO流的方法即可

代码演示:

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/Http_war_exploded/RequestDemo5" method="post">
        <input name="username">
        <input type="submit" value="提交">
    </form>
    <hr>
</body>
</html>

访问的Servlet类RequestDemo5

@WebServlet(name = "RequestDemo5", urlPatterns = "/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 获取请求消息体中请求参数
         */
        //1.获取字符流
        BufferedReader br = request.getReader();
        //2.读取流中的数据
        String line =null;
        while ((line=br.readLine())!=null){
            System.out.println(line);
        }
    }

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

    }
}

启动服务器,访问login.html,点击提交表单:

在这里插入图片描述

控制台打印
在这里插入图片描述



4.Request其它功能

4.1 获取请求参数通用方式

不论get还是post请求方式都可以使用下列方法来获取请求参数,所以get和post请求处理逻辑可以使用同一套代码:

  • String getParameter(String name):(重点)根据参数名称获取参数值,只能获取一个参数值。适合请求参数如:username=zs&password=123
  • String[] getParameterValues(String name):根据参数名称获取参数值的数组。 适合请求参数如:hobby=xx&hobby=game
  • Enumeration<String> getParameterNames():获取所有请求的参数名称
  • Map<String,String[]> getParameterMap(): (重点)获取所有参数的map集合

代码演示

register.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/Http_war_exploded/RequestDemo6" method="post">
        <input type="text" placeholder="请输入用户名" name="username"><br>
        <input type="text" placeholder="请输入密码" name="password"><br>

        <input type="checkbox" name="hobby" value="game">游戏
        <input type="checkbox" name="hobby" value="study">学习
        <br>
        <input type="submit" value="注册">
    </form>
</body>
</html>

访问的Servlet类

@WebServlet(name = "RequestDemo6", urlPatterns = "/RequestDemo6")
public class RequestDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * post 获取请求参数
         */
        //1.根据参数名称获取参数值
        String username = request.getParameter("username");//只能获取到一个参数值
        System.out.println("post");
        System.out.println(username);
        System.out.println("========================");

        //2.根据参数名称获取参数值的数组
        String[] hobbies = request.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("========================");

        //3.获取所有请求的参数名称
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            String value = request.getParameter(name);
            System.out.println(name+"-->"+value);
        }
        System.out.println("========================");

        //4.获取所有参数的map集合
        //泛型是参数名称,参数值数组
        Map<String, String[]> parameterMap = request.getParameterMap();
        //遍历
        Set<String> keyset = parameterMap.keySet();
        for (String name : keyset) {
            //根据键获取值
            String[] values = parameterMap.get(name);
            System.out.println(name);
            for (String value : values) {
                System.out.println(value);
            }
            System.out.println("----------------");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * get获取请求参数
         */
        this.doPost(request,response);
    }
}

启动服务器,访问register.html,点击注册提交表单:

在这里插入图片描述

控制台打印:

在这里插入图片描述


4.1.1 中文请求参数乱码问题

get方式:tomcat 8 内部已经将get方式乱码问题解决了,中文数据使用get请求方式不会乱码。

post方式:会乱码

  • 解决办法:在获取参数前,设置request的编码request.setCharacterEncoding(“utf-8”);

代码演示

修改上面的register.html中表单,访问RequestDemo7。

@WebServlet(name = "RequestDemo7", urlPatterns = "/RequestDemo7")
public class RequestDemo7 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 设置流的编码
         * 需要与页面编码格式一致
         */
        //request.setCharacterEncoding("utf-8");//先注释掉,查看乱码问题

        //获取请求参数username
        String username = request.getParameter("username");
        System.out.println(username);
    }
}

点击注册,提交表单:

在这里插入图片描述

控制台出现乱码:

在这里插入图片描述

取消request.setCharacterEncoding("utf-8");的注释,重写启动服务器再次提交,乱码解决:

在这里插入图片描述


4.2 请求转发

请求转发:是一种在服务器内部的资源跳转方式。

在这里插入图片描述

请求包含

请求包含指的是使用include()方法将Servlet请求转发给其它Web资源进行处理,与请求转发不同的是,在请求包含返回的响应消息中,既包含了当前Servlet的响应消息,也包含了其他Web资源所作出的响应消息。

从图中可以看出,当客户端访问Servlet1时,通过调用include()方法将其它Web资源包含了进来,这样,当请求处理完毕后,回送给客户端的响应结果既包含当Servlet的响应结果,也包含其它Web资源的响应结果。

使用步骤

  • 1.通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
  • 2.使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)

请求转发的特点:

  • 1.浏览器地址栏路径不发生变化。
  • 2.只能转发到当前服务器内部资源中(静态和动态资源)。
  • 3.转发是一次请求。

代码演示

创建了两个Servlet类:RequestDemo8和RequestDemo9

现在从浏览器中访问RequestDemo8,服务器内部会请求转发到RequestDemo9。

@WebServlet(name = "RequestDemo8", urlPatterns = "/RequestDemo8")
public class RequestDemo8 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("Demo8888被访问了。。。。");

        /**
         * 请求转发
         */
        //RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
        //requestDispatcher.forward(request,response);

        //推荐使用链式编程,因为转发对象一般只使用一次
        request.getRequestDispatcher("/RequestDemo9").forward(request,response);
    }
}
@WebServlet(name = "RequestDem9", urlPatterns = "/RequestDemo9")
public class RequestDemo9 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 请求转发
         */
        System.out.println("Demo9也被访问了。。。。");
    }
}

启动服务器,访问RequestDemo8:

在这里插入图片描述

控制台打印情况:

在这里插入图片描述


4.3 共享数据

概念:域对象和request域

域对象:一个有作用范围的对象,可以在范围内共享数据

request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

在这里插入图片描述

共享数据的方法

  • void setAttribute(String name,Object obj):存储数据,参数:
    String name:存储对象的名称,用于获取到存储的对象;
    Object obj:存储的对象;
  • Object getAttitude(String name):通过键获取值
  • void removeAttribute(String name):通过键移除键值对

代码演示

创建了两个Servlet类:RequestDemo8和RequestDemo9

现在从浏览器中访问RequestDemo8,服务器内部会请求转发到RequestDemo9。

在RequestDemo8中存储了数据到request域中,在RequestDemo9中获取存储的数据。

@WebServlet(name = "RequestDemo8", urlPatterns = "/RequestDemo8")
public class RequestDemo8 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("Demo8888被访问了。。。。");

        /**
         * 共享数据
         * 存储数据到request域中
         */
        request.setAttribute("msg","Hello");

        /**
         * 请求转发
         */
        //推荐使用链式编程,因为转发对象一般只使用一次
        request.getRequestDispatcher("/RequestDemo9").forward(request,response);
    }
}
@WebServlet(name = "RequestDem9", urlPatterns = "/RequestDemo9")
public class RequestDemo9 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 请求转发
         */
        System.out.println("Demo9也被访问了。。。。");

        /**
         * 获取共享数据
         * 从request域中获取存储的数据
         */
        Object msg = request.getAttribute("msg");
        System.out.println(msg);
    }
}

启动服务器,访问RequestDemo8,控制台打印情况:

在这里插入图片描述


4.4 获取ServletContext对象

ServletContext官方叫servlet上下文。服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象。这个对象全局唯一,而且工程内部的所有servlet都共享这个对象。所以叫全局应用程序共享对象。

获取方法

  • ServletContext getServletContext():获取servlet上下文对象

代码演示

@WebServlet(name = "RequestDemo10", urlPatterns = "/RequestDemo10")
public class RequestDemo10 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 获取ServletContext容器对象
         */
        ServletContext servletContext = request.getServletContext();
        System.out.println(servletContext);//org.apache.catalina.core.ApplicationContextFacade@694468f2
    }
}

到这HTTP之Request对象细节结束,学无止境,每天都要全力以赴!

推荐阅读

欢迎点赞评论,指出不足,笔者由衷感谢哦!~

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: request对象JavaWeb的一个重要对象,它代表了客户端向服务器发送的HTTP请求。request对象包含了请求的各种信息,如请求的URL、请求的参数、请求的头部信息等等。通过request对象,我们可以获取客户端发送的请求信息,并且可以向客户端发送响应信息。在JavaWeb开发request对象是非常常用的一个对象,它可以帮助我们实现各种功能,如登录、注册、数据查询等等。 ### 回答2: Request对象是Java Web程序处理HTTP请求的主要方式之一。在基于Web的应用程序,客户端向服务器发送HTTP请求。请求是客户端指示服务器要求某种操作的方式。 Request对象表示客户端请求的信息。当服务器接收到请求时,会创建一个Request对象来表示该请求。该对象包含有关请求的所有信息,例如,URL,HTTP方法,头信息等。开发人员可以使用Request对象从请求获取所需的信息。这些信息可以是请求参数,请求头,服务器路径,URL等。 Request对象主要用于从客户端获取数据,例如,表单输入和URL查询字符串。Request对象还用于跟踪客户端会话状态,例如,在应用程序保存用户信息和验证用户身份。 Request对象HttpServletRequest接口的实例。HttpServletRequest接口提供各种方法来读取请求数据和元数据,例如getParameter,getAttribute和getRequestDispatcher等。 Request对象可以用于以下用途: 1.获取请求的参数和头信息; 2.获取请求的HTTP方法和URI; 3.设置和获取请求属性; 4.获取客户端IP地址; 5.获取域名和服务端口号; 6.获取会话信息; 7.重定向和转发请求。 总之,Request对象是Java Web编程的重要组成部分,可以使开发人员轻松地获取客户端请求的各种信息,并实现复杂的Web应用程序。 ### 回答3: JavaWebRequest对象指的是HttpServletRequest对象,是Web应用程序用来接收和处理HTTP请求信息的重要组成部分。在JavaHttpServletRequestServlet的一个子接口,可以通过Servlet API提供的各种方法来获取请求信息。 Request对象包含了客户端的请求信息,包括请求的URL、请求方法、请求参数、请求头信息以及上传的文件等等。通过调用HttpServletRequest提供的各种方法,我们可以获取这些信息并进行相应的处理。例如,使用getParameter方法可以获取表单的数据,使用getHeader方法可以获取请求头信息,使用getInputStream方法可以获取上传的文件流等等。 除了获取请求信息,HttpServletRequest还提供了其他的一些常用功能。例如,使用setAttribute方法可以在请求设置属性,使用getSession方法可以获取当前会话的Session对象,使用getRequestDispatcher方法可以获取请求分发器等等。 需要注意的是,Request对象是由Servlet容器根据收到的请求创建的,并在请求处理完成之后销毁。因此,在使用Request对象时,需要尽量避免长时间保存和复用,以避免可能的内存泄露等问题。 综上所述,HttpServletRequest作为JavaWeb的重要组成部分,通过封装和处理HTTP请求信息,为开发者提供了丰富的功能和灵活的扩展性。在Web应用程序,合理地运用HttpServletRequest对象将极大提升程序的性能和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值