Day_05 request

本文详细介绍了Servlet中的关键概念,如请求转发、域对象、响应对象操作(包括输出内容、定时跳转、重定向和文件下载),以及线程安全问题。通过实例演示,帮助读者理解如何在Servlet中处理HTTP请求和响应,以及如何正确管理数据和资源跳转。

01-请求转发(掌握)

  • 概述

    • 跳转资源,站内资源跳转。
  • 代码实现

    @WebServlet("/demo01")
    public class Demo01Servlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("Demo01Servlet");
            //①获取请求调度对象
            //RequestDispatcher requestDispatcher = req.getRequestDispatcher("demo02");
            //②执行转发
            //requestDispatcher.forward(req, resp);
    		req.getRequestDispatcher("demo02").forward(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    @WebServlet("/demo02")
    public class Demo02Servlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("Demo02Servlet");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • 执行流程

    • image-20220309093254047
    • 请求转发,只有一次请求。

02-request作为域对象(掌握)

  • 域对象

    • 存储数据并共享
  • 代码实现

    @WebServlet("/demo03")
    public class Demo03Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("Demo03Servlet");
            request.setAttribute("msg", "hello");
            //请求转发到Demo04Servlet
            request.getRequestDispatcher("demo04").forward(request, response);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
    @WebServlet("/demo04")
    public class Demo04Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("Demo04Servlet");
            //request.removeAttribute("msg");
            Object msg = request.getAttribute("msg");
            System.out.println("msg = " + msg);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
  • 注意事项

    • request作为域对象,共享范围是当前请求有效。

03-响应对象概述(掌握)

  • 概述

    Defines an object to assist a servlet in sending a response to the client. The servlet container creates a ServletResponse object and passes it as an argument to the servlet's service method. 
    
    To send binary data in a MIME body response, use the ServletOutputStream returned by getOutputStream(). To send character data, use the PrintWriter object returned by getWriter(). To mix binary and text data, for example, to create a multipart response, use a ServletOutputStream and manage the character sections manually. 
    
    • ServletResponse对象用于发送响应给客户端,通过Servlet的services方法传递给Servlet;
    • 通过ServletOutputStream对象发送字节数据,通过PrintWriter对象发送字符数据。
  • 继承结构

    • image-20220309094703298

04-响应对象之输出内容(掌握)

  • 概述

    • 响应对象操作响应体(响应正文)
  • 问题分析

    • image-20220309102440047
  • 代码实现

    @WebServlet("/demo06")
    public class Demo06Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //告诉服务器,以utf-8编码响应正文
            //response.setCharacterEncoding("utf-8");
            //告诉浏览器,以utf-8解码响应正文
            //response.setHeader("Content-Type","text/html;charset=utf-8");
            //告诉服务器,以utf-8编码响应正文 ;告诉浏览器,以utf-8解码响应正文。
            response.setContentType("text/html;charset=utf-8");
            String content = "你好世界";
            PrintWriter writer = response.getWriter();
            writer.write(content);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    

05-响应对象之定时跳转(掌握)

  • 概述

    • 响应对象操作响应头Refresh来完成。
  • 代码实现1

    /**
     * 05-响应对象之定时跳转
     * 需求:3秒后跳转到Demo08Servlet
     */
    @WebServlet("/demo07")
    public class Demo07Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("Demo07Servlet");
            response.setHeader("Refresh", "3;url=demo08");
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
    @WebServlet("/demo08")
    public class Demo08Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("Demo08Servlet");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
  • 代码实现2

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="Refresh" content="3;url=index.html">
        <title>05-响应对象之定时跳转</title>
    </head>
    <body>
    
    <span id="spn">3</span>秒后跳转,如果没有跳转,<a href="index.html">请点击</a>
    
    </body>
    <script>
    
        window.setInterval("showCount()",1000);
    
        function showCount() {
            var count = document.getElementById("spn").innerText;
            if (count <= 1) {
                return;
            }
            count--;
            document.getElementById("spn").innerText = count;
        }
    
    </script>
    </html>
    

06-重定向(掌握)

  • 概述

    • 跳转资源,站外资源跳转。
  • 开发步骤

    • ①操作响应状态码301/302
      • 301 : 永久重定向 , 销毁历史记录
      • 302 : 临时重定向,保存历史记录
    • ②操作响应头location
  • 代码实现

    @WebServlet("/demo09")
    public class Demo09Servlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("Demo09Servlet");
            //①操作响应状态码
            //resp.setStatus(302);
            //②操作响应头location
            //resp.setHeader("location","demo10");
    
            resp.sendRedirect("demo10");
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    @WebServlet("/demo10")
    public class Demo10Servlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("Demo10Servlet");
            
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • 执行流程

    • image-20220309104849073

07-资源跳转的路径问题(掌握)

  • 概述

    • 请求转发:站内资源跳转;
      • 相对路径:和原来一样,没有问题
      • 绝对路径 :和原来不一样,"/资源访问路径"
    • 重定向:站外资源跳转。
      • 相对路径:和原来一样,没有问题
      • 绝对路径:和原来一样,"/项目访问路径/资源访问路径"
  • 代码实现1

    @WebServlet("/demo11")
    public class Demo11Servlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("Demo11Servlet");
            //相对路径 : ok
            //req.getRequestDispatcher("demo12").forward(req,resp);
            //绝对路径
            req.getRequestDispatcher("/day05/demo12").forward(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
  • 代码实现2

    @WebServlet("/demo13")
    public class Demo13Servlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("Demo13Servlet");
            //相对路径
            //resp.sendRedirect("demo14");
            //绝对路径
            resp.sendRedirect("/day05/demo14");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    

08-响应对象之文件下载(掌握)

  • 概述

    • 将服务器中的文件拷贝到客户端中。
  • 开发步骤

    • ①获取下载文件的名称
    • ②告诉浏览器必须打开一个下载窗口(Content-Disposition)
      • 浏览器会有默认下载功能(无法解析文件)
    • ③告诉浏览器下载文件的mimeType
    • ④IO拷贝
    • ⑤释放资源
  • 代码实现1

    @WebServlet("/demo15")
    public class Demo15Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //①获取下载文件的名称
            String fileName = request.getParameter("fileName");
            //②告诉浏览器必须打开一个下载窗口(Content-Disposition)
            response.setHeader("Content-Disposition", "attachement;filename=" + fileName);
            //③告诉浏览器下载文件的mimeType
            String mimeType = getServletContext().getMimeType(fileName);
            response.setContentType(mimeType);
            //④IO拷贝
            //E:\day05_war_exploded\download\girl1.jpg
            String downloadFilePath = getServletContext().getRealPath("/download/" + fileName);
            System.out.println("downloadFilePath = " + downloadFilePath);
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(downloadFilePath));
            BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
            byte[] bys = new byte[8192];
            int len = -1;
            while ((len = bis.read(bys)) != -1) {
                bos.write(bys, 0, len);
            }
            //⑤释放资源
            bis.close();
            bos.close();//手动刷新最后的一次的缓冲区
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
  • 代码实现2

    @WebServlet("/demo15")
    public class Demo15Servlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //①获取下载文件的名称
            String fileName = request.getParameter("fileName");
            //②告诉浏览器必须打开一个下载窗口(Content-Disposition)
            //手动编码文件名称
            String newFileName = URLEncoder.encode(fileName,"utf-8");
            response.setHeader("Content-Disposition", "attachement;filename=" + newFileName);
    
    
            //③告诉浏览器下载文件的mimeType
            String mimeType = getServletContext().getMimeType(fileName);
            response.setContentType(mimeType);
            //④IO拷贝
            //E:\day05\out\artifacts\day05_war_exploded\download\girl1.jpg
            String downloadFilePath = getServletContext().getRealPath("/download/" + fileName);
            System.out.println("downloadFilePath = " + downloadFilePath);
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(downloadFilePath));
            BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
            byte[] bys = new byte[8192];
            int len = -1;
            while ((len = bis.read(bys)) != -1) {
                bos.write(bys, 0, len);
            }
            //⑤释放资源
            bis.close();
            bos.close();//手动刷新最后的一次的缓冲区
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    

09-Servlet的线程安全(掌握)

  • 概述

    • Servlet是多线程单实例的。
  • 代码实现1

    @WebServlet("/demo16")
    public class Demo16Servlet extends HttpServlet {
    
        private String num;
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
                num = request.getParameter("num");
    
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                //线程1 : num=250
                //线程2 : num=500
                response.getWriter().write("num = " + num);
    
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
  • 代码实现2 : 使用锁机制

    @WebServlet("/demo16")
    public class Demo16Servlet extends HttpServlet {
    
        private String num;
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            synchronized (this){
                num = request.getParameter("num");
    
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                //线程1 : num=250
                //线程2 : num=500
                response.getWriter().write("num = " + num);
            }
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
  • 代码实现3 : 尽量避免在Servlet中使用成员变量,而使用局部变量

    @WebServlet("/demo16")
    public class Demo16Servlet extends HttpServlet {
    
        //private String num;//成员变量,也叫对象变量
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            String num = request.getParameter("num");
    
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            //线程1 : num=250
            //线程2 : num=500
            response.getWriter().write("num = " + num);
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request, response);
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值