1、Request
1.1、请求行
| * 请求行例子 |
| GET /day06_request/requestLine?name=zs HTTP/1.1 |
| |
| * 重要方法: |
| 1. String getMethod() 获取请求方式 GET/POST |
| 2. String getRequestURL() 获取请求完整路径(URL) `http://localhost:8080/day06_request/requestLine` |
| 3. String getRequestURI() 获取请求资源部分(URI) `/day06_request/requestLine` |
| 4. String getContextPath() 获取项目虚拟目录 `/day06_request` |
| 5. String getServletPath() 获取项目资源路径 `/requestLine` |
| 6. String getProtocol() 获取请求协议和版本号 HTTP/1.1 |
| 7. int getLocalPort() 获得服务器端口号 8080 |
| 8. String getRemoteAddr() 获得客户端 ip 地址 |
| - 如果写的是 localhost, 显示 ipv6 地址 |
| - 如果写的是 127.0.0.1, 显示 ipv4 地址 |
| 9. #{pageContext.request.contextPath} |
1.2、请求头
| * 请求头例子 |
| User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36 |
| |
| * 重要方法: |
| 1. String getHeader(String name) 以 String 的形式返回指定请求头的值 |
| 2. Enumeration getHeaderNames() 返回此请求包含的所有头名称的枚举 |
1.3、请求参数(重要)
| * 请求参数的位置 |
| get 请求: URL 上 |
| post 请求: 请求体中 |
| |
| * 请求参数例子 |
| name=张三&age=18&hobby=抽烟&hobby=喝酒&hobby=烫头 |
| |
| * 重要方法 |
| 1. String getParameter(String name) 根据参数名获得参数值(单个) |
| 2. String[] getParameterValues(String name) 根据参数名获得参数值(数组) |
| 3. Map<String, String[]> getParameterMap() 获得所有的参数, 封装到 Map 集合 |
1.4、将请求参数封装成实体(重要)
| * https://www.hutool.cn/docs/#/ |
| * hutool 提供了一个方法可以将请求的 Map 转成一个实体对象 BeanUtil.copyProperties(map, user, true) (源, 目标, 是否忽略属性大小写) |
| * 需要注意的是: map 中的 key 要和实体类中的属性保持一致 |
| Map<String, String[]> map = req.getParameterMap(); |
| User user = new User(); |
| BeanUtil.copyProperties(map, user, false); |
| System.out.println(user); |
1.5、总结
| 1. Request 概念: Tomcat 创建出来, 用于封装请求行头体 |
| 2. 接收请求行 |
| - 虚拟路径 request.getContextpath() |
| 3. 接收请求头 |
| - 接收所有 key: request.getHeaderNames() |
| - 根据 key 接收 value: request.getHeader(key) |
| 4. 接收请求参数 |
| - getParameter("name") getParameterValues("name") |
| - getParameterMap() ------> Map<String, String[]> ------> BeanUtil.copyProperties(map, obj) =====> obj |
| - 转发: request.getRequestDispatcher("流转路径{不需要写虚拟路径}").forward(req, resp); |
| - 域对象: set get remove |
2、Responce
2.1、响应行头体
| * 响应行 |
| - 响应行格式例子 |
| - HTTP/1.1 200 OK |
| - HTTP/1.1 302 OK |
| - 设置响应行: |
| - void setStatus(int sc) |
| |
| * 响应头 |
| - 响应头格式例子 |
| - Location:http://www.baidu.com |
| - Content-Type:text/html;charset=utf-8 |
| - 设置响应头 |
| - void setHeader(String name, String value) |
| |
| * 响应体 |
| - 通过 response 获取输出流 |
| - 字符流: PrintWriter getWriter() |
| - 字节流: ServletOutputStream getOutputStream() |
| - 注意: 在同一个 servlet 中, 不能同时使用字节流和字符流 |
2.2、响应重定向
| 1. 方式一 |
| - response.setStatus(302); |
| - response.setHeader("Location", 目标资源位置); |
| 2. 方式二 |
| - response.sendRedirect(目标资源位置); |
2.3、向浏览器输出中文
| * 使用字符流输出内容到浏览器 |
| - PrintWriter writer = response.getWriter(); |
| - writer.write() 将其他类型转换为字符, 再输出 |
| - writer.print() 只能输出字符 |
2.4、总结
| * response |
| 1. 重定向 |
| - resp.sendRedirct(req.getContextPath() + "/资源路径") |
| 2. 设置编码 |
| - resp.setContentType("text/html;charset=utf-8"); |
3、请求转发和响应重定向
| 1. 实现 |
| - 请求转发(request 对象的方法) |
| - request.getRequestDispatcher("/BServlet").forward(request,response); |
| - 响应重定向(response 对象的方法) |
| - response.sendRedirect(request.getContextPath() + "/BServlet"); |
| 2. 区别 |
| - 请求转发 |
| - 地址栏: 没有改变 |
| - 浏览器: 发了一次请求 |
| - 服务器: 只有一对请求和响应对象 |
| - 发生的位置: 服务器内部 |
| - 响应重定向 |
| - 地址栏: 发生了改变 |
| - 浏览器: 发了两次请求 |
| - 服务器: 有两对请求和响应对象 |
| - 发生的位置: 浏览器外部 |
4、Cookie 和 Session
| 1. cookie 基本原理 |
| - 创建服务器, 保存在客户端, 用于记录一次会话中的请求和响应的信息 |
| - 使用的头: |
| - 响应头: 服务器向浏览器保存 cookie Set-Cookie: product=xiaomi |
| - 请求头: 浏览器向服务器报告 cookie Cookie: product=xiaomi |
| 2. api |
| - 创建 cookie: new Cookie(key, value) |
| - 设置存活时间: cookie.setMaxAge(正整数时长) |
| - 设置数据共享路径: cookie.setPath("服务器路径") |
| - cookie 数据的覆盖因素: cookie 的 path 相同并且 name 相同 |
| - 中文和字符: 使用编码技术 URL |
| - 将 cookie 写回浏览器: resp.addCookie(cookie) |
| - 从请求中获取 cookie: req.getCookies() |
| |
| 3. Cookie 特点 |
| - cookie 创建在服务器, 存储数据在客户端(浏览器) |
| - cookie 只能存储字符串 |
| - cookie 单个大小不能超过 4KB |
| - cookie 存储数据不太安全 |
| 1. session 基本原理 |
| - 创建服务器, 保存在服务器, 用于记录一次会话中的请求和响应的信息 |
| - 使用的头: |
| - 响应头: 服务器向浏览器保存 cookie Set-Cookie: JESESSIONID=session 标识 |
| - 请求头: 浏览器向服务器报告 cookie Cookie: JESESSIONID=session 标识 |
| |
| 2. api |
| 1) 创建 Session: req.getSession() |
| 2) 向 session 中保存数据: setAttribute(key, value) |
| 3) 从 session 中获取数据: getAttribue(key) |
| 4) 摧毁 session: session.invlidate() |
| |
| 3. sessione 特点 |
| - session 存储数据在服务器 |
| - session 存储类型任意(Object) |
| - session 存储大小和数量没有限制(相对于内存) |
| - session 存储相对安全 |
| |
| 4. Cookie 和 Session 的选择 |
| - cookie: 将数据保存在浏览器端, 数据相对不安全, 而且数据大小是有限制的, 建议不太敏感的数据使用它 |
| - session: 将数据保存在服务器端, 数据相对安全, 数据的大小要比 cookie 中数据灵活很多, 但是会占用服务器内存, 建议敏感且小量数据使用它 |
5、Get 和 Post
| POST `/day05_tomcat/index.html` HTTP/1.1 |
| |
| * 请求行由三部分组成: 请求方式 请求路径 请求协议/版本 |
| * 请求方式有很多, 我们需要关注两种: get 和 post |
| 1. get |
| - 请求参数在地址栏显示, 不太安全 |
| - 请求参数大小有限制 |
| - 没有请求体 |
| 2. post |
| - 请求参数没有在地址栏显示, 而是在请求体显示, 相对安全 |
| - 请求参数大小没有限制 |
| - 有请求体 |
6、乱码
| request.setCharacterEncoding("UTF-8"); |
| response.setContentType("text/html;charset=UTF-8"); |
7、注解
| @WebServlet( |
| name = "servlet", // 指定 Servlet 名称, 等价于 web.xml 中的 servlet-name, 如果省略, 则为 Servlet 的完整类名 |
| urlPatterns = {"/servlet.do","/s.do"}, // Servlet 的访问 URL, 支持多个, 等价于 web.xml 中的 urlPatterns |
| loadOnStartup = 6, // 自启动 Servlet, 指定 Servlet 的加载顺序, 等价于 web.xml 中的 load-on-startup |
| initParams = { // 给 servletConfig 初始化, 设置初始化参数, 等价于 web.xml 中的 init-param |
| @WebInitParam(name = "brand", value = "ASUS"), |
| @WebInitParam(name = "screen", value = "三星") |
| } |
| ) |
| |
| @WebFilter( |
| urlPatterns = {"/myServlet1.do"}, // Filter 过滤 Servlet 的 URL, 支持多个 |
| // 指定过滤器将应用于哪些 Servlet, 支持多个 |
| // 取值是 @WebServlet 中的 name 属性的取值, 或者是 web.xml 中 <servlet-name> 的取值 |
| servletNames = {"myServlet1"}, |
| initParams = { // 给 filterConfig 初始化 |
| @WebInitParam(name = "realName", value = "张三"), |
| @WebInitParam(name = "charset", value = "utf-8") |
| } |
| ) |
| |
| |
| @WebFilter(urlPatterns = "/*") |
8、Servlet
8.1、示例
| public class HelloServlet extends HttpServlet { |
| |
| @Override |
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
| this.doPost(req, resp); |
| } |
| |
| @Override |
| protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { |
| resp.getWriter().write("Hello World."); |
| } |
| } |
8.2、Servlet 的生命周期
阶段 |
次数 |
时机 |
创建 new |
1 次 |
第一次请求 |
初始化 init |
1 次 |
实例化之后 |
执行服务 service |
多次 |
每次请求 |
销毁 destroy |
1 次 |
停止服务 |
8.3、ServletConfig 和 ServletContext
| * 当 Tomcat 初始化一个 Servlet 时, 该 Servlet 的配置信息, 封装到一个 ServletConfig 对象中 |
| - ServletConfig servletConfig = this.getServletConfig() 获取当前 servet 的配置信息对象 |
| - getInitParameter("key") 根据 key 获取当前 servet 的配置信息 |
| * ServletContext 作为域对象可以在同一个应用中共享数据 |
| * 获取服务器上的资源 |
| - getRealPath(String filename) 获取资源真实路径[重要] |
| - getResourceAsStream(String filename) 将项目中的文件转换成流 |
| * 获取全局配置参数 |
| - servletContext.getInitParameter("key") [重要] |
8.4、Servlet 三大域对象
域对象 |
类 |
作用域 |
Request 域 |
HttpServletRequest |
一次请求 / 请求转发 |
Session 域 |
HttpSession |
一次会话(跨请求) |
Application 域 |
ServletContext |
任意一次请求和会话(跨会话) |
三大于对象的获取
- Request 域:request(只有请求转发,Request 域中的数据才可以传递)
- Session 域:HttpSession session = request.getSession();
- Application 域:ServletContext application = request.getServletContext();
三大于对象的共有方法
- 设置和修改数据:setAttribute(key, value);
- 获得数据的方法:getAttribute(key);
- 移除数据的方法:removeAttribute(key);
9、web.xml 三大组件
执行流程:ServletContext、监听器、过滤器、Servlet
- Servlet(前端控制器 DisptcherServlet)
- 过滤器
- 监听器
- 在启动 Web 项目时,Tomcat 会读取 web.xml 中的 comtext-param 节点,获取这个 Web 应用的全局参数
Tomcat 创建一个 ServletContext 实例,是全局有效的
将 context-param 的参数转换为键值对,存储在 ServletContext 里
- 创建 listener 中定义的监听类的实例,按照规定 Listener 要继承自 ServletContextListener
监听器初始化方法是 contextlnitialized(ServletContextEvent event)
初始化方法中可以通过 event.getServletContext().getlnitParameter("name") 方法获得上下文环境中的键值对
- 当 Tomcat 完成启动,也就是 contextlnitialized 方法完成后,再对 Filter 过滤器进行初始化
- servlet 初始化:有一个参数 load-on-startup,它为正数的值越小优先级越高,会自动启动,如果为负数或未指定这个参数,会在 servlet 被调用时再进行初始化
init-param 是一个 servlet 整个范围之内有效的参数,在 servlet 类的 init 方法中通过 this.getInitParameter('"param1") 方法获得
Servlet
| |
| <servlet> |
| |
| <servlet-name>myServlet</servlet-name> |
| |
| <servlet-class>servlet.MyServlet</servlet-class> |
| |
| |
| |
| <load-on-startup>6</load-on-startup> |
| </servlet> |
| |
| |
| <servlet-mapping> |
| <servlet-name>myServlet</servlet-name> |
| <url-pattern>/myServlet.do</url-pattern> |
| </servlet-mapping> |
| |
| |
| <welcome-file-list> |
| <welcome-file>a.html</welcome-file> |
| <welcome-file>index.html</welcome-file> |
| </welcome-file-list> |
| <servlet> |
| <servlet-name>servlet4</servlet-name> |
| <servlet-class>servlet.Servlet4</servlet-class> |
| <init-param> |
| <param-name>brand</param-name> |
| <param-value>联想</param-value> |
| </init-param> |
| |
| <init-param> |
| <param-name>screen</param-name> |
| <param-value>京东</param-value> |
| </init-param> |
| </servlet> |
| <servlet-mapping> |
| <servlet-name>servlet4</servlet-name> |
| <url-pattern>/servlet4.do</url-pattern> |
| </servlet-mapping> |
配置
| |
| <context-param> |
| <param-name>username</param-name> |
| <param-value>dodo</param-value> |
| </context-param> |
| <context-param> |
| <param-name>password</param-name> |
| <param-value>123456</param-value> |
| </context-param> |
| |
| |
| <session-config> |
| <session-timeout>1</session-timeout> |
| </session-config> |
| |
| |
| <error-page> |
| <error-code>500</error-code> |
| <location>/error500.JSP</location> |
| </error-page> |
过滤器和监听器
| |
| <filter> |
| |
| <filter-name>filter</filter-name> |
| |
| <filter-class>filter.MyFilter</filter-class> |
| </filter> |
| |
| <filter-mapping> |
| |
| <filter-name>filter</filter-name> |
| |
| |
| <servlet-name>myServlet1</servlet-name> |
| <servlet-name>myServlet2</servlet-name> |
| |
| |
| <url-pattern>/</url-pattern> // 不包括 JSP |
| <url-pattern>/*</url-pattern> // 包括 JSP |
| </filter-mapping> |
| <listener> |
| <listener-class>com.z.listener.MyRequestListener</listener-class> |
| </listener> |
10、其他
| <dependency> |
| <groupId>cn.hutool</groupId> |
| <artifactId>hutool-all</artifactId> |
| <version>5.2.3</version> |
| </dependency> |
| |
| private void save(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { |
| |
| ServletInputStream inputStream = request.getInputStream(); |
| |
| String json = IoUtil.read(inputStream, "UTF-8"); |
| |
| Student student = new ObjectMapper().readValue(json, Student.class); |
| studentService.save(student); |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步