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

时间:2022-07-25
本文章向大家介绍JavaWeb——HTTP请求协议及request对象使用方法一点通与request登录实战案例(含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对象中。

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

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