Servlet——Request和Response

目录


Request体系结构

跳转到目录
在这里插入图片描述

  • ServletRequest:是一个接口
  • HttpServletRequest:是一个接口
  • org.apache.catalina.connector.RequestFacade:是 Tomcat 的一个类

RequestFacade 类实现了 HttpServletRequest 接口,HttpServletRequest 接口继承了 ServletRequest 接口

在这里插入图片描述

HttpServletRequest常用方法

跳转到目录

  • ServletRequest接口: 请求对象, 封装了获取所有请求信息(请求行, 请求头, 请求实体)的方法
  • HttpServletRequest接口:是ServletRequest的子接口, 处理HTTP协议请求的方法.

常用方法

  • String getMethod(): 返回请求方式(GET/POST)
  • String getRequestURI():返回请求行中资源名字部分: 如/test/index.html
  • StringBuffer getRequestURL():返回浏览器地址栏的内容
  • String getContextPath():获取上下文路径(虚拟目录),<Context path=“上下文” …/>
  • String getRemoteAddr():返回请求服务器的客户端的IP地址
  • String getHeader(String headName):根据指定的请求头获取对应的请求头的值.

获取请求参数的方法

  • String getParameter(String name):根据参数名称,获取对应参数的值.
  • String[] getParameterValues(String name):根据参数名称,获取该参数的多个值.
  • Enumeration<String> getParameterNames(): 获取所有请求参数的名字
  • Map<String,String[]> getParameterMap():返回请求参数组成的Map集合.
    key:参数名称
    value:参数值,封装在String数组中.

在这里插入图片描述
注意:

  • String getInitParameter(String name): 获取初始化参数, 初始化参数是开发人员设置
  • String getParameter(String name): 获取用户输入的参数, 参数是不同用户输入的(通过表单)
// 注解: 表示Web.xml中给这个Servlet配置的8句
@WebServlet("/req")
public class HttpServletRequestDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //- String getMethod(): 返回请求方式(GET/POST)
        System.out.println(req.getMethod());
        //- String getRequestURI():返回请求行中资源名字部分: 如/test/index.html
        System.out.println(req.getRequestURI());
        //- StringBuffer getRequestURL():返回浏览器地址栏的内容
        System.out.println(req.getRequestURL());
        //- String getContextPath():获取上下文路径,<Context path="上下文" ../>
        System.out.println(req.getContextPath());
        //- String getRemoteAddr():返回请求服务器的客户端的IP地址
        System.out.println(req.getRemoteAddr());
        //- String getHeader(String headName):根据指定的请求头获取对应的请求头的值.
        String userAgent = req.getHeader("User-Agent");
        System.out.println(userAgent.contains("MSIE"));
        System.out.println(userAgent);
        System.out.println("-----------获取请求参数的方法----------");
        // String getParameter(String name):根据参数名称,获取对应参数的值.
        System.out.println(req.getParameter("username"));
        // String[] getParameterValues(String name):根据参数名称,获取该参数的多个值.
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println(Arrays.toString(hobbies));
        // Enumeration<String> getParameterNames():获取所有请求参数的名字
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            System.out.println("====>" + parameterNames.nextElement());
        }
        // Map<String,String[]> getParameterMap():返回请求参数组成的Map集合.
        Map<String, String[]> parameterMap = req.getParameterMap();
        System.out.println(parameterMap);
    }
}

请求转发
跳转到目录
一种在服务器内部的资源跳转方式
在这里插入图片描述

  • 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)

  • 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)

  • 特点:

    扫描二维码关注公众号,回复: 8812867 查看本文章
    • 浏览器地址栏路径不发生变化
    • 只能转发到当前服务器内部资源中
    • 转发只发送一次请求
  • RequestSkipDemo.java

    @WebServlet("/skip")
    public class RequestSkipDemo extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("ServletSkipDemo~~~");
            // 转发到skip2资源
            req.getRequestDispatcher("/skip2").forward(req, resp);
        }
    }
    
  • RequestSkipDemo1.java

    @WebServlet("/skip2")
    public class RequestSkipDemo1 extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("skip2");
        }
    }
    

共享数据
跳转到目录

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

注册案例

跳转到目录

  • 通过RegisterServlet来获取注册界面传送过来的参数.
    在这里插入图片描述

  • register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册界面</title>
</head>
<body>
<h3>注册界面</h3>

<form action="/register/reg" method="post">
    账号:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    性别:
    <input type="radio" name="gender" value="boy" checked><input type="radio" name="gender" value="girl"><br>
    爱好:
    <input type="checkbox" name="hobby" value="Java" checked>java
    <input type="checkbox" name="hobby" value="C" checked>C
    <input type="checkbox" name="hobby" value="Swift" checked>Swift<br>
    城市:
    <select name="city">
        <option value="ny">南阳</option>
        <option value="tb">桐柏</option>
        <option value="bj">北京</option>
    </select><br>
    自我介绍:<textarea rows="5" cols="15" name="intro"></textarea><br>
    <input type="submit" value="注册">
</form>

</body>
</html>
  • RegisterServlet.java
@WebServlet("/reg")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String gender = req.getParameter("gender");
        String city = req.getParameter("city");
        String intro = req.getParameter("intro");
        String[] hobbies = req.getParameterValues("hobby");
        System.out.println(username);
        System.out.println(password);
        System.out.println(gender);
        System.out.println(city);
        System.out.println(intro);
        System.out.println(Arrays.toString(hobbies));
    }
}

在这里插入图片描述

请求的中文乱码处理

跳转到目录

  • 在Tomcat中, 对于POST和GET请求,默认是ISO-8859-1的编码格式, 而该编码格式不支持中文, 所以会产生乱码.
  • 解决方案 :

第一种方式:

  1. 对乱码使用ISO-8859-1解码—>byte数组.
  2. 对byte数组重新使用UTF-8编码
     String username1 = req.getParameter("username");
     // 按照ISO-8859-1把乱码恢复成二进制形式
     byte[] data = username1.getBytes("ISO-8859-1");
     // 再把二进制形式的数据使用UTF-8重新编码
     String username2 = new String(data, "UTF-8");
     System.out.println(username2);
    

问题: 这种方式当一个参数需要使用这两行代码来转码,如果有N个中文参数,就需要写N次,如此一来, 冗余代码很多.

第二种方式:

  • 针对POST请求方式
    req.setCharacterEncoding("UTF-8");
     // 对于POST请求 可以设置请求的编码
     req.setCharacterEncoding("UTF-8");
     String username = req.getParameter("username");
     System.out.println(username);
    
    注意: 这种方式只对POST有效, 必须放在获取任意参数之前
  • 针对GET请求方式(了解)
    在这里插入图片描述
    这种方式只对GET有用.

HttpServletResponse常用方法

跳转到目录

  • ServletResponse接口: 响应对象, 封装了获取所有响应信息(状态行, 响应头, 请求实体)的方法
  • HttpServletResponse接口:是ServletResponse的子接口, 处理HTTP协议响应的方法.

常用方法

  • OutputStream getOutputStream():获取字节输出流对象. :文件下载
  • Writer getWriter():获取字符输出流对象 :输出内容
// 演示HttpServletResponse
@WebServlet("/resp")
public class HttpServletResponseDemo extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 在浏览器中输出Hello_ZYGui
//        ServletOutputStream out = resp.getOutputStream();
//        out.write("Hello_ZYGui桂朝阳".getBytes());

        // 使用字符输出流,中文会出现乱码,需要设置两行代码
        // 设置输出数据的MIME类型
        // resp.setContentType("text/html");
        // 设置输出数据的编码方式
        // resp.setCharacterEncoding("UTF-8");

        // 这两行可以统一设置
        resp.setContentType("text/html;character=utf-8");

        PrintWriter out1 = resp.getWriter();
        out1.println("Hello_桂朝阳"); // 输出到浏览器上
    }
}

重定向

跳转到目录
重定向.png

  • 重定向是一种资源跳转的方式
  • 实现方式
    //当访问responseDemo1,会自动跳转到/responseDemo2
    // ---------方式一------------
    // 设置状态码
    //   resp.setStatus(302);
    //   设置响应头 location
    //   resp.setHeader("location", "/ZYServlet/responseDemo2");
    
    // ---------方式二------------
    resp.sendRedirect("/ZYServlet/responseDemo2");
    
  • 重定向的特点:redirect
    1. 地址栏发生变化
    2. 重定向可以访问其他站点(服务器)的资源
    3. 重定向是两次请求。不能使用request对象来共享数据

  • 转发的特点:forward
    1. 转发地址栏路径不变
    2. 转发只能访问当前服务器下的资源
    3. 转发是一次请求,可以使用request对象来共享数据

  • 路径写法:

  1. 相对路径:通过相对路径不可以确定唯一资源
    * 如:./index.html
    * 不以/开头,以.开头路径
    规则:找到当前资源和目标资源之间的相对位置关系
    * ./:当前目录
    * …/:后退一级目录
    2. 绝对路径:通过绝对路径可以确定唯一资源
    * 如:http://localhost/day15/responseDemo2
    /day15/responseDemo2
    * 以/开头的路径
    规则:判断定义的路径是给谁用的?判断请求将来从哪儿发出
    * 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
    * 建议虚拟目录动态获取:request.getContextPath()
    * <a> , <form> 重定向…
    * 给服务器使用:不需要加虚拟目录
    * 转发路径
发布了149 篇原创文章 · 获赞 68 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/m0_37989980/article/details/103916693