Servlet执行流程&生命周期&方法介绍&体系结构、Request和Response的功能详解(2)

简介: Servlet执行流程&生命周期&方法介绍&体系结构、Request和Response的功能详解

Servlet执行流程&生命周期&方法介绍&体系结构、Request和Response的功能详解(1)https://developer.aliyun.com/article/1518154

7.3 Request通用方式获取请求参数

  • Map<String,String[]>getParameterMap():获取所有参数Map集合
  • String[]getParameterValues(String name):根据名称获取参数值(数组)
  • String getParameter(String name):根据名称获取参数值(单个值)
  • get方式:
  • html代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>doPost</title>
</head>
<body>
<form action="/BBS/demo5" method="get">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1"> 游泳
    <input type="checkbox" name="hobby" value="2"> 跑步 <br>
    <input type="submit">
</form>
</body>
</html>
  • Java代码:
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Get请求
        System.out.println("get...");
        //1.获取所有参数的Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String key : parameterMap.keySet()) {
            System.out.print(key + ": ");
            //获取值
            String[] strings = parameterMap.get(key);
            for (String string : strings) {
                System.out.print(string + " ");
            }
            System.out.println();
        }
        System.out.println("----------------------");
        //2.根据key获取值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("----------------------");
        //3.获取单个参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }
  • post方式:
  • html代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>doPost</title>
</head>
<body>
<form action="/BBS/demo5" method="post">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1"> 游泳
    <input type="checkbox" name="hobby" value="2"> 跑步 <br>
    <input type="submit">
</form>
</body>
</html>
  • Java代码:
@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Post请求
        System.out.println("get...");
        //1.获取所有参数的Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String key : parameterMap.keySet()) {
            System.out.print(key + ": ");
            //获取值
            String[] strings = parameterMap.get(key);
            for (String string : strings) {
                System.out.print(string + " ");
            }
            System.out.println();
        }
        System.out.println("----------------------");
        //2.根据key获取值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("----------------------");
        //3.获取单个参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }
  • 通用代码:
@WebServlet("/demo5")
public class ServletDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //Get请求
        System.out.println("get...");
        //1.获取所有参数的Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String key : parameterMap.keySet()) {
            System.out.print(key + ": ");
            //获取值
            String[] strings = parameterMap.get(key);
            for (String string : strings) {
                System.out.print(string + " ");
            }
            System.out.println();
        }
        System.out.println("----------------------");
        //2.根据key获取值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("----------------------");
        //3.获取单个参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

7.4 请求参数中文乱码处理

7.4.1 POST 解决方案

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码POST
        //设置字符输入流的编码
        req.setCharacterEncoding("utf-8");
        //获取数据
        String username = req.getParameter("username");
        System.out.println(username);
    }

7.4.1 GET 解决方案

  • GET获取参数方式:getQueryString
  • 产生乱码的原因:
  • 浏览器在解析中文字符时采用UTF-8的字符集通过URL进行编码,将中文转换成%+16进制数的格式,然后将转换后的字符发送给服务器进行解码,tomcat在进行解码时是通过ISO-8859-1的字符集进行URL解码,由于编码和解码时用的字符集不同,所以就会出现乱码。
  • URL编码:
  • 将字符串按照编码方式转为二进制
  • 每个字节转为2个16进制数并在前边加上%
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码GET
        String username = req.getParameter("username");
        //转换为字节数据,编码
        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
        //将字节数组转换为字符串,解码
        username = new String(bytes,"utf-8");
        System.out.println(username);
    }
  • Tomcat8.0之后,已将GET请求乱码问题解决,设置默认的解码方式为UTF-8

7.5 Request请求转发

  • 请求转发(forward):一种在服务器内部的资源跳转方式
req.getRequestDispatcher("资源B路径").forward(req,resp);
  • 请求转发资源间共享数据:使用Request对象
  • void setAttribute(String name,Object o):存储数据到request域中
  • Object getAttribute(String name):根据key,获取值
  • void removeAttribute(String name):根据key,删除该键值对
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo7...");
        //存储数据
        req.setAttribute("msg","hello");
        //请求转发
        req.getRequestDispatcher("/demo8").forward(req,resp);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
@WebServlet("/demo8")
public class ServletDemo8 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo8...");
        //获取数据
        Object msg = req.getAttribute("msg");
        System.out.println(msg);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}
  • 请求转发特点:
  • 浏览器地址栏路径不发生变化
  • 只能转发到当前服务器的内部资源
  • 一次请求,可以在转发的资源间使用request共享数据

八、Response

8.1 设置相应数据功能

  • 响应数据分为3部分:
  • 响应行
  • 设置响应状态码:
void setStatus(int sc)
  • 响应头
  • 设置响应键值对
void setHeader(String name,String value)
  • 响应体
  • 获取字符输出流
PrintWriter getWriter();
  • 获取字节输出流
ServletOutputStream getOutputStream();

8.2 完成重定向

  • 重定向(Redirect):一种资源跳转方式
@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp1...");
        //重定向
        //设置响应状态码302
        //resp.setStatus(302);
        //设置响应头
        //resp.setHeader("Location","/BBS/resp2");
        //简化方式
        resp.sendRedirect("/BBS/resp2");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp2...");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
  • 重定向特点:
  • 浏览器地址栏路径发生变化
  • 可以重定向到任意位置的资源(服务器内部、外部均可)
  • 两次请求,不能在多个资源使用request:共享数据

8.3资源路径问题

  • 明确路径谁使用?
  • 浏览器使用:需要加虚拟目录(项目访问路径)
  • 服务端使用:不需要加虚拟目录
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("resp1...");
        //简化方式
        //动态获取虚拟目录
        String contextPath = req.getContextPath();
        resp.sendRedirect(contextPath + "/resp2");
    }

8.4 Response响应字符数据

  • 使用:
  • 1.通过Response对象获取字符输出流
PrintWriter writer resp.getWriter();
  • 2.写数据
writer.write("hello~");

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        resp.setHeader("content-type","text/html");
        writer.write("<h1>hello~</h1>");
        writer.write("<h1>你好~</h1>");
    }

注意:

  • 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
  • 中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1

8.5 Response响应字节数据

  • 使用:
  • 通过Response对象获取字符输出流
ServletOutputStream outputStream resp.getOutputStream();
  • 写数据
outputStream.write("字节数据");

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //读取文件
        FileInputStream fis = new FileInputStream("d://head.jpg");
        //获取response字节输出流
        ServletOutputStream os = resp.getOutputStream();
        //完成流的copy
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = fis.read(buff)) != -1) {
            os.write(buff,0,len);
        }
        fis.close();
    }
  • IOUtils工具类使用:
  • 导入坐标:
<dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.6</version>
</dependency>
  • 使用:
IOUtils.copy(fis,os);

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //读取文件
        FileInputStream fis = new FileInputStream("d://head.jpg");
        //获取response字节输出流
        ServletOutputStream os = resp.getOutputStream();
        //完成流的copy
        IOUtils.copy(fis,os);
        fis.close();
    }
相关文章
|
10天前
|
Java 数据库连接 开发者
Java中的Servlet生命周期详解
Java中的Servlet生命周期详解
|
17天前
|
XML 数据格式
XML配置Servlet文件,不使用注解配置路径的方法
XML配置Servlet文件,不使用注解配置路径的方法
|
17天前
|
前端开发 应用服务中间件
servlet执行流程&生命周期
servlet执行流程&生命周期
|
17天前
|
应用服务中间件
|
19天前
Servlet的生命周期
Servlet的生命周期
12 2
|
24天前
|
Java
servlet生命周期面试题
servlet生命周期面试题
|
13天前
|
XML 存储 前端开发
JavaEE:Servlet创建和使用及生命周期介绍
JavaEE:Servlet创建和使用及生命周期介绍
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术
|
24天前
|
Java 应用服务中间件 开发工具
基于Servlet的3.1以上注解方式完成上传功能。
基于Servlet的3.1以上注解方式完成上传功能。
8 0
|
25天前
|
Java Apache
基于servlet完成文件上传功能
基于servlet完成文件上传功能
22 0