JavaWeb——HTTP请求协议及request对象使用方法一点通与request登录实战案例(含BeanUtils类的使用)

目录

1、Http请求协议概述

2、request和response对象的原理

3、request对象

4、request登录案例

5、BeanUtils的使用


1、Http请求协议概述

HTTP,Hyper Text Transfer Protocol,超文本传输协议,定义了客户端和服务器通信时,发送数据的格式。其特点是:

  • 1)基于TCP/IP的高级协议;
  • 2)默认端口是80;
  • 3)基于请求、响应模型:一次请求对应一次响应;
  • 4)无状态的:每次请求之间相对独立,不能交互数据;

【HTTP历史版本】:

  • 1.0:每一次请求响应都会建立新的连接;
  • 1.1:复用连接;

【请求消息数据格式】:

  • 请求行:请求方式 请求url 请求协议/版本
                   请求方式,HTTP协议有7种请求方式,常见的有2种:
                        *GET:请求参数在请求行中,在url后;请求的url长度有限制;不太安全;
                        *POST:请求参数在请求体中,请求的url长度没有限制;相对安全;
  • 请求头:请求头名称:请求头值
                   常见的请求头:
                        *User-Agent:浏览器告诉服务器,我访问你使用的浏览器版本信息,可以在服务器端获取该头信息,解决浏览器的兼容性问题;
                        *Referer:告诉服务器,当前请求从哪里来,作用是:可以防盗链、统计工作。
  • 请求空行:空行,用于分割POST请求的请求头和请求体的
  • 请求体(正文):封装POST请求消息的请求参数的

关于HTTP协议的详细介绍,可以看下另一篇博文

2、request和response对象的原理

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

3、request对象

1)request对象的继承体系结构如下:
     ServletRequset   ——接口
          |  继承
     HttpServletRequest  ——接口
          |  实现
     org.apache.catalina.connector.RequestFacade类(tomcat)

2)request对象的功能:

  • 获取请求消息数据:
        1、获取请求行数据(GET /4.servlet/demo4?name=zhangsan HTTP1.1)
                   获取请求方式-GET:    String getMethod()
                   获取虚拟目录-/4.servlet:    String getContextPath()
                   获取Servlet路径-/demo4:   String getServletPath()
                   获取get请求方式参数-name=zhangsan:    String getQueryString()
                   获取请求的URI- /4.servlet/demo4:    String getRequestURI()
                                          - http://localhost/4.servlet/demo4:   String getRequestURL()
                          URL,统一资源定位符;URI,统一资源标识符

                   获取协议及版本-HTTP1.1:    String getProtocol()
                   获取客户机的IP地址:    String getRemoteAddr()
    @WebServlet("/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 {
            String method = request.getMethod();
            System.out.println(method);
            String contextPath = request.getContextPath();
            System.out.println(contextPath);
            String servletPath = request.getServletPath();
            System.out.println(servletPath);
            String queryString = request.getQueryString();
            System.out.println(queryString);
            String requestURI = request.getRequestURI();
            System.out.println(requestURI);
            StringBuffer requestURL = request.getRequestURL();
            System.out.println(requestURL);
            String protocol = request.getProtocol();
            System.out.println(protocol);
            String remoteAddr = request.getRemoteAddr();
            System.out.println(remoteAddr);
    
        }
    }

        2、获取请求头数据
                    通过请求头名称获取请求头的值:String getHeader(String name);
                    获取所有的请求头名称:Enumeration<String> getHeaderNames();
    @WebServlet("/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 {
            Enumeration<String> headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()){
                String s = headerNames.nextElement();
                String value = request.getHeader(s);
                System.out.println(s+"---"+value);
            }
            //user-agent头
            String agent = request.getHeader("user-agent");
            if(agent.contains("Chrome")){
                System.out.println("谷歌来了");
            }else if(agent.contains("Firefox")){
                System.out.println("火狐来了");
            }
            //referer头
            String referer = request.getHeader("referer");
            System.out.println(referer);
            //防盗链
            if(referer!=null){
                if(referer.contains("/4.servlet")){
                    System.out.println("非盗链");
                }else{
                    System.out.println("盗链");
                }
            }
        }
    }

        3、获取请求体数据
                    请求体:只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数;
                    获取步骤:1、获取流对象
                                          --BufferedReader getReader():获取字符输入流,只能操作字符数据;
                                          --ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据;
                                     2、从流对象中拿数据
    @WebServlet("/requestDemo3")
    public class RequestDemo3 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            BufferedReader reader = request.getReader();
            String line = null;
            while ((line=reader.readLine())!=null){
                System.out.println(line);
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        }
    }

  • 其他功能(重要):

              1、获取请求参数通用方式:GET或POST方式均可
                       》String getParameter(String name):根据参数名称获取参数值; username=zhang&password=123
                       》String[] getParameterValues(String name):根据参数名称获取参数值的数组;hobby=1&hobby=2
                       》Enumeration<String> getParameterNames():获取所有请求的参数名称
                       》Map<String,String[]> getParameterMap():获取所有参数的map集合

@WebServlet("/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 {
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String s = headerNames.nextElement();
            String value = request.getHeader(s);
            System.out.println(s+"---"+value);
        }
        //user-agent头
        String agent = request.getHeader("user-agent");
        if(agent.contains("Chrome")){
            System.out.println("谷歌来了");
        }else if(agent.contains("Firefox")){
            System.out.println("火狐来了");
        }
        //referer头
        String referer = request.getHeader("referer");
        System.out.println(referer);
        //防盗链
        if(referer!=null){
            if(referer.contains("/4.servlet")){
                System.out.println("非盗链");
            }else{
                System.out.println("盗链");
            }
        }
    }
}

            【中文乱码问题】:get方式:tomcat8 已经将get乱码问题解决了;
                                          post方式:在获取参数前设置request的编码 ,request.setCharacterEncoding("utf-8");

              2、请求转发:一种在服务器内部的资源跳转方式,步骤:
                                   》通过request对象和以前请求转发器对象:RequestDispatcher getRequestDispatcher(String path);
                                   》使用该对象进行转发:forward(ServletRequest request, ServletResponse response);

@WebServlet("/requestDemo4")
public class RequestDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("requestDemo4被访问了");
        //转发到demo5资源
        request.getRequestDispatcher("/requestDemo5").forward(request,response);
    }

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

     请求转发的特点:

  • 浏览器地址栏路径不发生变化;
  • 只能转发到当前服务器内部内部资源中;
  • 转发是一次请求;

              3、共享数据:
                         域对象:一个有作用范围的对象,可以在范围内共享数据;
                         request域对象:代表一次请求的范围,一般用于请求转发的多个资源中共享数据,提供的方法:
                             》setAttribute(String name,Object obj):存储数据;
                             》Object getAttribute(String name):通过键获取值;
                             》void removeAttribute(String name):通过键移除键值对;

              4、获取ServletContext:ServletContext getServletContext();

4、request登录案例

下面通过一个登录案例,对上述的request对象相关方法进行实战,需求如下:

  • 编写login.xml登录页面(username&password 两个输入框);
  • 使用Druid数据库连接池技术,操作mysql,day1数据库中的user表;
  • 登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您;
  • 登录失败跳转到FailServlet展示:登录失败,用户名或密码错误。

对于以上需求,分析如下:

开发步骤:

  • 1)创建项目,导入login1.html页面,配置文件,jar包;
  • 2)创建数据库环境;
          
  • 3)创建一个包cn.test.domain,创建User类;
  • 4)创建一个包cn.test.dao,创建类UserDao,操作user数据库表;
  • 5)创建cn.test.servlet.LoginServlet类,完成登录的具体逻辑;
  • 6)注意login.html的form表单中action路径写法:虚拟目录+Servlet的资源路径;
  • 7)编写LoginServlet、FailServlet、SuccessServlet。

代码就不往上贴了,登录案例的实战代码传送门

5、BeanUtils的使用

以上我们在LoginServlet中封装User对象时,是一个个获取再封装的,若参数较多时就比较麻烦了,有没有简单的封装方式?这里我们介绍下一个开源工具类,BeanUtils,加完jar包(commons-beanutils-1.8.0.jar)后使用步骤如下示例:

        //2、获取所有请求参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        //3、创建user对象
        User loginUser = new User();
        try {
            BeanUtils.populate(loginUser,parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

BeanUtils就是用来封装JavaBean的,JavaBean是标准的Java类,就是用来封装数据的,定义要求如下:

  • 1)类必须被public修饰;
  • 2)必须提供空参的构造类;
  • 3)成员变量必须使用private修饰;
  • 4)提供公共setter和getter方法。

BeanUtils的几个重要方法:

  • 1)setProperty():设置属性值
  • 2)getProperty():获取属性值
  • 3)populate(Object obj,Map map):将Map集合的键值对信息封装都对应的JavaBean对象中。

作于202007032200,已归档

———————————————————————————————————

本文为博主原创文章,转载请注明出处!

若本文对您有帮助,轻抬您发财的小手,关注/评论/点赞/收藏,就是对我最大的支持!

祝君升职加薪,鹏程万里!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Winter_world

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值