1、关于请求

简单来说就是客户端向服务器发出的请求

Servlet中定义了协议相关的对象 HttpServletRequest 接口和协议无关的对象 ServletRequest 接口

2、Request请求对象常用方法

1)获取路径

22090204

@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取虚拟目录名称
        String contextPath =req.getContextPath();
        System.out.println(contextPath);
        //2.获取Servlet映射路线
        String servletPath = req.getServletPath();
        System.out.println(servletPath);
        //3.获取访问者ip ipv6
        String remoteUser = req.getRemoteUser();
        System.out.println(remoteUser);
        //4.获取请求的消息数据
        String queryString = req.getQueryString();
        System.out.println(queryString);
        //5.获取统一资源标识符
        String requestURI = req.getRequestURI();
        System.out.println(requestURI);
        //6.获取统一资源定位符
        StringBuffer requestURL = req.getRequestURL();
        System.out.println(requestURL);
    }
}

/crm /servletDemo01 0:0:0:0:0:0:0:1 null /crm/servletDemo01 http://localhost:8080/crm/servletDemo01

2) 请求头信息

22090205

@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //7.根据请求头获得一个值
        String cookie = req.getHeader("Cookie");
        System.out.println(cookie);
        //8.根据请求头名称获取多个值
        Enumeration<String> headers = req.getHeaders("Accept-Encoding");
        while (headers.hasMoreElements()) {
            String value = headers.nextElement();
            System.out.println(value);
        }
        //9.获取所有请求头名称
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String value = headerNames.nextElement();
            System.out.println(value);
        }
3)获取请求参数信息

22090206

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>
    <form action="/crm/servletDemo02" method="Get" autocomplete="off">
        姓名:<input type="text" name="username"> <br>
        密码:<input type="password" name="password"> <br>
        爱好:<input type="checkbox" name="hobby" value="study">学习
              <input type="checkbox" name="hobby" value="game">游戏 <br>
        <button type="submit">注册</button>
    </form>
</body>
</html>
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.根据名称获取数据
        String username = req.getParameter("username");
        System.out.println(username);
        String password = req.getParameter("password");
        System.out.println(password);
        System.out.println("====================");
        //2.根据名称获取所有数据
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("====================");
        //3.获取所有名称
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String s = parameterNames.nextElement();
            System.out.println(s);
        }
        System.out.println("=======================");
        //4.获取所有参数的键值对
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String s : parameterMap.keySet()){
            String[] strings = parameterMap.get(s);
            for (String string : strings) {
                System.out.println(string);
            }
        }
    }
}

3、获取参数封装对象

1) 手动封装
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.根据名称获取数据
        String username = req.getParameter("username");
        System.out.println(username);
        String password = req.getParameter("password");
        System.out.println(password);

       User user= new User();
       user.setUsername(username);
       user.setPassword(password);

       System.out.println(user.toString());
    }
2)反射封装
public class User {
    private String username;
    private String password;
    private String[] hobby;

    public String[] getHobby() {
        return hobby;
    }

    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", hobby=" + Arrays.toString(hobby) +
                '}';
    }
}
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取所有数据
        Map<String, String[]> parameterMap = req.getParameterMap();
        //2.封装User对象
        User user = new User();
        //3.遍历集合
        for (String name : parameterMap.keySet()){
            String[] strings = parameterMap.get(name);
            try {
                //4.获取User对象的属性选择器
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name,user.getClass());
                //5.获取对应的setXXX方法
                Method writeMethod = propertyDescriptor.getWriteMethod();
                //6.执行对应方法
                if(strings.length>1){
                    writeMethod.invoke(user,(Object) strings);
                }else {
                    writeMethod.invoke(user, strings);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println(user.toString());
    }
}
3)工具类封装

下载如下jar包 引入WEB-INF下的libs 记得在项目管理中二次引入

commons-beanutils-1.9.4.jar

commons-logging-1.2.jar

@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取所有数据
        Map<String, String[]> parameterMap = req.getParameterMap();
        //2.封装User对象
        User user = new User();
        try {
            BeanUtils.populate(user,parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println(user.toString());
    }
}

3、流对象获取请求信息

22090207

1)字符流
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //字符流
        BufferedReader reader = req.getReader();
        String line;
        while ((line = reader.readLine()) != null){
            System.out.println(line);
        }
        //不需要手动关闭,不是自己创建的,而是通过req获得的
        //reader.close();
    }
}
2) 字节流
@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //字符流
        ServletInputStream inputStream = req.getInputStream();
        byte[] arr = new byte[1024];
        int len;
        while ((len = inputStream.read(arr)) != -1){
            System.out.println(new String(arr,0,len));
        }
    }
}

4、中文乱码

  • Get方式无乱码问题 在tomcat8后被解决
  • Post方式需要通过setCharacterEncoding()解决

req.setCharacterEncoding("UTF-8");

tips:流对象不生效

5、请求域

可以在一次请求范围内共享数据

22090208

6、请求转发

服务端接收到请求后发现需要借助其他Servlet实现功能

  • 浏览器地址不变
  • 域对象数据不丢失
  • 负责转发的Servlet转发前后的响应正文会丢失(响应正文就是服务器返回的HTML页面)
  • 由转发的目的地来响应客户端
  • 比重定向效率高

22090209

@WebServlet("/servletDemo02")
public class servletDemo02 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("encoding","css");
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("/peopleServlet");
        requestDispatcher.forward(req,resp);
    }
public class PeopleServlet  extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("PeopleServlet");
        Object encoding = req.getAttribute("encoding");
        System.out.println(encoding);
    }
}

tips:前后请求方式要一致

7、请求包含

合并其他Servlet中的功能一起响应给客户端

  • 浏览器地址栏不变
  • 域对象中的数据不丢失
  • 被包含的Servlet响应头会丢失

22090210

  • 请求包含大多数是在jsp页面中,完成多页面的合并
  • 请求转发大多是在Servlet中,转发目标大多是jsp页面