文章目录
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); } } -
执行流程

- 请求转发,只有一次请求。
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对象发送字符数据。
-
继承结构
04-响应对象之输出内容(掌握)
-
概述
- 响应对象操作响应体(响应正文)
-
问题分析
-
代码实现
@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
- ①操作响应状态码301/302
-
代码实现
@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); } } -
执行流程
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); } }
本文详细介绍了Servlet中的关键概念,如请求转发、域对象、响应对象操作(包括输出内容、定时跳转、重定向和文件下载),以及线程安全问题。通过实例演示,帮助读者理解如何在Servlet中处理HTTP请求和响应,以及如何正确管理数据和资源跳转。



999

被折叠的 条评论
为什么被折叠?



