• request


    本节内容:

    • HttpServletRequest概述
    • request的运行流程
    • 通过抓包工具抓取Http请求
    • 通过request获得请求行
    • 通过request获得请求头
    • 通过request获得请求体
    • request的其他功能
    • 示例:注册
    • 示例:登录

    一、HttpServletRequest概述

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

    service方法中的request的类型是ServletRequest,而doGet/doPost方法的request的类型是HttpServletRequest,HttpServletRequest是ServletRequest的子接口,功能和方法更加强大。

    二、request的运行流程

    三、通过抓包工具抓取Http请求

     

    request代表请求,我们可以通过该对象分别获得Http请求的请求行,请求头和请求体。

    注意:GET方式是没有请求体的。现阶段只有表单,并且表单的方法是post的是POST提交,其他都是GET提交。

    四、通过request获得请求行

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

    获得请求的资源:

    • String getRequestURI():所有的资源地址,比如C:a.txt,还有相对地址
    • StringBuffer getRequestURL():一般情况指的是网络资源,比如http
    • String getContextPath():获取web应用的名称
    • String getQueryString():获取get方式提交url地址后的参数字符串,比如username=zhangsan&password=123
    • request.getRemoteAddr():获得访问的客户端IP地址
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <form action="/WEB15/line" method="get"> <!-- get和post都测试下-->
            <input type="text" name="username"><br>
            <input type="password" name="password"><br>
            <input type="submit" value="提交"><br>
        </form>
    </body>
    </html>
    form.html
    public class LineServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //1、获得请求方式
            String method = request.getMethod();
            System.out.println("method:"+method);
            //2、获得请求的资源相关的内容
            String requestURI = request.getRequestURI(); 
            StringBuffer requestURL = request.getRequestURL();
            System.out.println("uri:"+requestURI); // /WEB15/line
            System.out.println("url:"+requestURL); // http://localhost:8080/WEB15/line
            //获得web应用的名称
            String contextPath = request.getContextPath();
            System.out.println("web应用:"+contextPath); // /WEB15
            //地址后的参数的字符串
            String queryString = request.getQueryString();
            System.out.println(queryString); // GET方式才有值,POST方式提交为null
            //3、获得客户机的信息---获得访问者IP地址
            String remoteAddr = request.getRemoteAddr();
            System.out.println("IP:"+remoteAddr);
            
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    LineServlet.java

    五、通过request获得请求头

    • long getDateHeader(String name)
    • String getHeader(String name):header都是键值对。
    • Enumeration getHeaderNames():获取所有header头的名字。返回类型是枚举。
    • Enumeration getHeaders(String name):某些头可能有多个值。基本不用,因为基本不会有同名的头。
    • int getIntHeader(String name)
    public class HeaderServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //1、获得指定的头
            String header = request.getHeader("User-Agent");
            System.out.println(header);
            //2、获得所有的头的名称和值
            Enumeration<String> headerNames = request.getHeaderNames(); //Enumeration,枚举类型,你可以认为它是一个集合,现在用的不多了
            while(headerNames.hasMoreElements()){
                String headerName = headerNames.nextElement();
                String headerValue = request.getHeader(headerName);
                System.out.println(headerName+":"+headerValue);
            }
            
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    HeaderServlet.java

    referer头的作用:执行该此访问(请求)的的来源。即这次请求来源于哪个资源。

    【示例】:在页面中写一个a标签,一点击访问HeaderServlet。header中就有referer。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <a href="/WEB15/referer">访问headerServlet资源</a>
    </body>
    form.html
    public class HeaderServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //1、获得指定的头
            String header = request.getHeader("User-Agent");
            System.out.println(header);
            //2、获得所有的头的名称和值
            Enumeration<String> headerNames = request.getHeaderNames(); //Enumeration,枚举类型,你可以认为它是一个集合,现在用的不多了
            while(headerNames.hasMoreElements()){
                String headerName = headerNames.nextElement();
                String headerValue = request.getHeader(headerName);
                System.out.println(headerName+":"+headerValue);
            }
            
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    HeaderServlet.java

    浏览器访问http://localhost:8080/WEB15/form.html,点击a标签,查看eclipse控制台打印的header结果,发现有个refer:

    referer:http://localhost:8080/WEB15/form.html

    【示例】:利用referer头做防盗链。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <a href="/WEB15/referer">访问headerServlet资源</a>
        <form action="/WEB15/line" method="get">
            <input type="text" name="username"><br>
            <input type="password" name="password"><br>
            <input type="submit" value="提交"><br>
        </form>
    </body>
    </html>
    form.html
    public class RefererServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //对该新闻的来源的进行判断
            String header = request.getHeader("referer");
            if(header!=null&&header.startsWith("http://localhost")){ //企业里面可以把localhost换成域名
                //是从我自己的网站跳转过来的 可以看新闻
                response.setContentType("text/html;charset=UTF-8");
                response.getWriter().write("中国确实已经拿到100块金牌....");
            }else{
                response.getWriter().write("你是盗链者,可耻!!");
            }    
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    RefererServlet.java

    六、通过request获得请求体

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

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

    以上面参数为例,通过一下方法获得请求参数:

    • String getParameter(String name)
    • String[] getParameterValues(String name)
    • Enumeration getParameterNames()
    • Map<String,String[]> getParameterMap()
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <form action="/WEB15/content" method="post"> <!-- post和get都试下,后台写代码都是可以获取到请求参数的>
            <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="pq">排球
            <input type="checkbox" name="hobby" value="ppq">乒乓球<br>
            <input type="submit" value="提交"><br>
        </form>
    </body>
    </html>
    form.html
    public class ContentServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //1、获得单个表单值
            String username = request.getParameter("username");
            System.out.println(username);
            String password = request.getParameter("password");
            System.out.println(password);
            //2、获得多个表单的值 --比如checkbox的多值情况
            String[] hobbys = request.getParameterValues("hobby");
            for(String hobby:hobbys){
                System.out.println(hobby);
            }
            //3、获得所有的请求参数的名称
            Enumeration<String> parameterNames = request.getParameterNames();
            while(parameterNames.hasMoreElements()){
                System.out.println(parameterNames.nextElement());
            }
            System.out.println("------------------");
            //4、获得所有的参数 参数封装到一个Map<String,String[]>
            /*
            username                [zhangsan]
            password                [123]
            hobby                [football,basketball]
            */
            Map<String, String[]> parameterMap = request.getParameterMap();
            for(Map.Entry<String, String[]> entry:parameterMap.entrySet()){
                System.out.println(entry.getKey());
                for(String str:entry.getValue()){
                    System.out.println(str);
                }
                System.out.println("---------------------------");
            }
            
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    ContentServlet.java

    【注意】:get请求方式的请求参数,上述的方法一样可以获得。

    七、request的其他功能

    1. request是一个域对象

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

    • setAttribute(String name, Object o)
    • getAttribute(String name)
    • removeAttribute(String name)

    注意:request域的作用范围:一次请求中。每次访问都会产生新的request和response对象。

    2. request完成请求转发 

    先获得请求转发器 --path是转发的地址
    RequestDispatcher getRequestDispatcher(String path)

    在通过转发器对象的forward方法转发

    requestDispathcer.forward(ServletRequest request, ServletResponse response)

    public class Servlet1 extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //想request域中存储数据
            request.setAttribute("name", "tom");
            
            //servlet1 将请求转发给servlet2
            RequestDispatcher dispatcher = request.getRequestDispatcher("/servlet2");
            //执行转发的方法
            dispatcher.forward(request, response);
            
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    Servlet1.java
    public class Servlet2 extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            //从request域中取出数据
            Object attribute = request.getAttribute("name");
            
            response.getWriter().write("hello haohao..."+attribute);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    Servlet2.java

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

    ServletContext域:

    创建:服务器启动
    销毁:服务器关闭
    域的作用范围:整个web应用
    request域:

    创建:访问时创建request
    销毁:响应结束request销毁
    域的作用范围:一次请求中

    转发与重定向的区别?

    1)重定向是两次请求,转发是一次请求
    2)重定向地址栏的地址变化,转发地址不变
    3)重新定向可以访问外部网站(比如可以重定向到百度),转发只能访问内部资源(转发给内部的地址)。
    4)转发的性能要优于重定向

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

    客户端地址:是客户端去访问服务器的地址,属于服务器外部的地址,就是从外部访问服务器资源。特点:需要写上web应用名称。

    • 直接输入地址
    • 重定向


    服务器端地址:服务器内部资源的跳转的地址,特点:不需要写web应用的名称。

    • 转发

    八、示例:注册

    表:

    CREATE TABLE `user` (
      `uid` varchar(50) NOT NULL,
      `username` varchar(20) DEFAULT NULL,
      `password` varchar(20) DEFAULT NULL,
      `name` varchar(20) DEFAULT NULL,
      `email` varchar(30) DEFAULT NULL,
      `telephone` varchar(20) DEFAULT NULL,
      `birthday` varchar(20) DEFAULT NULL,
      `sex` varchar(10) DEFAULT NULL,
      `state` int(11) DEFAULT NULL,
      `code` varchar(64) DEFAULT NULL,
      PRIMARY KEY (`uid`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

     页面:

    <div class="container"
        style=" 100%; background: url('image/regist_bg.jpg');">
        <div class="row">
            <div class="col-md-2"></div>
            <div class="col-md-8"
                style="background: #fff; padding: 40px 80px; margin: 30px; border: 7px solid #ccc;">
                <font>会员注册</font>USER REGISTER
                <form class="form-horizontal" style="margin-top: 5px;" action="/WEB15_request/register" method="post">
                    <div class="form-group">
                        <label for="username" class="col-sm-2 control-label">用户名</label>
                        <div class="col-sm-6">
                            <input type="text" class="form-control" id="username" name="username"
                                placeholder="请输入用户名">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
                        <div class="col-sm-6">
                            <input type="password" class="form-control" id="inputPassword3" name="password"
                                placeholder="请输入密码">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="confirmpwd" class="col-sm-2 control-label">确认密码</label> <!-- 确认密码不需要传到数据库 -->
                        <div class="col-sm-6">
                            <input type="password" class="form-control" id="confirmpwd"
                                placeholder="请输入确认密码">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="inputEmail3" class="col-sm-2 control-label">Email</label>
                        <div class="col-sm-6">
                            <input type="email" class="form-control" id="inputEmail3" name="email"
                                placeholder="Email">
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="usercaption" class="col-sm-2 control-label">姓名</label>
                        <div class="col-sm-6">
                            <input type="text" class="form-control" id="usercaption" name="name"
                                placeholder="请输入姓名">
                        </div>
                    </div>
                    <div class="form-group opt">
                        <label for="inlineRadio1" class="col-sm-2 control-label">性别</label>
                        <div class="col-sm-6">
                            <label class="radio-inline"> <input type="radio"
                                name="sex" id="inlineRadio1" value="male"></label> <label class="radio-inline"> <input type="radio"
                                name="inlineRadioOptions" id="inlineRadio2" value="female"></label>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="date" class="col-sm-2 control-label">出生日期</label>
                        <div class="col-sm-6">
                            <input type="date" class="form-control" name="birthday">
                        </div>
                    </div>
    
                    <div class="form-group">
                        <label for="date" class="col-sm-2 control-label">验证码</label>
                        <div class="col-sm-3">
                            <input type="text" class="form-control">
    
                        </div>
                        <div class="col-sm-2">
                            <img src="./image/captcha.jhtml" />
                        </div>
    
                    </div>
    
                    <div class="form-group">
                        <div class="col-sm-offset-2 col-sm-10">
                            <input type="submit" width="100" value="注册" name="submit"
                                style="background: url('./images/register.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0); height: 35px;  100px; color: white;">
                        </div>
                    </div>
                </form>
            </div>
    
            <div class="col-md-2"></div>
    
        </div>
    </div>
    register.jsp

    处理注册的Servlet:

    public class RegisterServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //设置request的编码,request编码默认也是ISO-8859-1 ---只适合post方式
            request.setCharacterEncoding("UTF-8");
            
            //get方式乱码解决,该方式也适用POST方式。但是表单一般都是POST方式提交
            //String username = request.getParameter("username");//乱码
            //先用iso8859-1编码 在使用utf-8解码
            //username = new String(username.getBytes("iso8859-1"),"UTF-8");
             
            
            //1、获取数据
            //String username = request.getParameter("username");
            //System.out.println(username);
            //String password = request.getParameter("password");
            //.....
    
            //2、将散装的封装到javaBean,这种比较麻烦,一般都不用,用BeanUtils工具
            //User user = new User();
            //user.setUsername(username);
            //user.setPassword(password);
    
            //使用BeanUtils进行自动映射封装。依赖两个包commons-beanutils-1.8.3.jar和commons-logging-1.1.1.jar
            //BeanUtils工作原理:将map中的数据 根据key与实体的属性的对应关系封装
            //只要key的名字与实体的属性 的名字一样 就自动封装到实体中
            Map<String, String[]> properties = request.getParameterMap(); //如果是get方式提交的,要循环这个Map,去解码编码,防止中文乱码
            User user = new User();
            try {
                BeanUtils.populate(user, properties);
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
    
            //到目前为止,user对象已经封装好了。但是user表有个uid字段,它是个主键
            //手动封装uid----使用uuid产生随机不重复的字符串32位--但是java代码生成后是36位
            user.setUid(UUID.randomUUID().toString());
    
            //3、将参数传递给一个业务操作方法
            try {
                regist(user);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
            //4、认为注册成功跳转到登录页面
            response.sendRedirect(request.getContextPath()+"/login.jsp");
    
        }
    
        //注册的方法
        public void regist(User user) throws SQLException{
            //操作数据库
            QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
            String sql = "insert into user values(?,?,?,?,?,?,?,?,?,?)";
            
            runner.update(sql,user.getUid(),user.getUsername(),user.getPassword(),user.getName(),
                    user.getEmail(),null,user.getBirthday(),user.getSex(),null,null);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    RegisterServlet.java

    http请求提交时,post方式提交时数据在请求体,get方式提交时数据是请求行中。request对请求行和请求体的处理是不一样的。

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

    解决get提交的方式的乱码:
    parameter = new String(parameter.getbytes("iso8859-1"),"utf-8");

     

    九、示例:登录

    转发:

    <body>
    
        <!-- 引入header.jsp -->
        <jsp:include page="/header.jsp"></jsp:include>
    
    
        <div class="container"
            style=" 100%; height: 460px; background: #FF2C4C url('images/loginbg.jpg') no-repeat;">
            <div class="row">
                <div class="col-md-7">
                    <!--<img src="./image/login.jpg" width="500" height="330" alt="会员登录" title="会员登录">-->
                </div>
    
                <div class="col-md-5">
                    <div
                        style=" 440px; border: 1px solid #E7E7E7; padding: 20px 0 20px 30px; border-radius: 5px; margin-top: 60px; background: #fff;">
                        <font>会员登录</font>USER LOGIN
                        <div><%=request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo") %>></div>
                        <form class="form-horizontal" action="/WEB15_request/login" method="post">
                            <div class="form-group">
                                <label for="username" class="col-sm-2 control-label">用户名</label>
                                <div class="col-sm-6">
                                    <input type="text" class="form-control" id="username" name="username"
                                        placeholder="请输入用户名">
                                </div>
                            </div>
                            <div class="form-group">
                                <label for="inputPassword3" class="col-sm-2 control-label">密码</label>
                                <div class="col-sm-6">
                                    <input type="password" class="form-control" id="inputPassword3" name="password"
                                        placeholder="请输入密码">
                                </div>
                            </div>
                            <div class="form-group">
                                <label for="inputPassword3" class="col-sm-2 control-label">验证码</label>
                                <div class="col-sm-3">
                                    <input type="text" class="form-control" id="inputPassword3"
                                        placeholder="请输入验证码">
                                </div>
                                <div class="col-sm-3">
                                    <img src="./image/captcha.jhtml" />
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="col-sm-offset-2 col-sm-10">
                                    <div class="checkbox">
                                        <label> <input type="checkbox"> 自动登录
                                        </label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <label> <input
                                            type="checkbox"> 记住用户名
                                        </label>
                                    </div>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="col-sm-offset-2 col-sm-10">
                                    <input type="submit" width="100" value="登录" name="submit"
                                        style="background: url('./images/login.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0); height: 35px;  100px; color: white;">
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    
        <!-- 引入footer.jsp -->
        <jsp:include page="/footer.jsp"></jsp:include>
    
    </body>
    login.jsp
    public class LoginServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            
            request.setCharacterEncoding("UTF-8");
            
            //1、获得用户名和密码
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            //2、调用一个业务方法进行该用户查询
            User login = null;
            try {
                login = login(username,password);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            //3、通过user是否为null判断用户名和密码是否正确
            if(login!=null){
                //代表用户名和密码正确
                //登录成功 跳转到网站的首页
                response.sendRedirect(request.getContextPath()); //重定向
            }else{
                //代表用户名或密码错误
                //跳回当前login.jsp
                //使用转发 转发到login.jsp  向request域中存储错误信息
                request.setAttribute("loginInfo", "用户名或密码错误");
                request.getRequestDispatcher("/login.jsp").forward(request, response); //转发,转发时可以往request域中存些内容
            }
            
        }
        
        public User login(String username,String password) throws SQLException{
            QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
            String sql = "select * from user where username=? and password=?";
            User user = runner.query(sql, new BeanHandler<User>(User.class), username,password);
            return user;
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    }
    LoginServlet.java
  • 相关阅读:
    阿里巴巴集团2014年校园招聘系统project师北京笔试题
    HDU 3104 Combination Lock(数学题)
    MYSQL数据迁移
    nginx配置文件中的location中文详解
    使用JQuery解析、处理JSON数据(应用在课程表)
    OpenResty+lua+GraphicsMagick生成缩略图
    解决使用base64解码太慢的问题,原因是根本就不应该使用此方法解决。
    Bringing up interface eth0: Determining if ip address 10.109.67.81 is already in use for device eth0...
    高效访问Internet-启用ISA Server的缓存
    在OpenResty中使用lua-zlib的方法
  • 原文地址:https://www.cnblogs.com/zhaojiankai/p/7813624.html
Copyright © 2020-2023  润新知