JavaWeb开发进阶SpringMVC的DispatcherServlet

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 DispatcherServlet简介 DispatcherServlet是Spring MVC框架的核心组件,充当前端控制器(Front Controller)的角色。它负责接收所有的HTTP请求,并将它们分发给适当的处理器(控制器)。DispatcherServlet是整个Spring MVC应用程序的入口点,管理请求的整个生命周期。 通过源码查看DispatcherServlet定义: public class DispatcherServlet extends FrameworkServlet public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware DispatcherServlet继承了FrameworkServlet,继承了HttpServletBean,继承了HttpServlet。HttpServlet来自jakarta.servlet.http.HttpServlet,也就是新版Servlet: <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.1.0</version> <scope>provided</scope> </dependency> 果然,Spring MVC是基于Servlet的! DispatcherServlet注册 DispatcherServlet是个Servlet,需要注册后才能使用。有3种注册方式:web.xml、Spring MVC、Spring Boot ① web.xml <web-app> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/app-context.xml</param-value> </context-param> <servlet> <servlet-name>app</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/app/*</url-pattern> </servlet-mapping> </web-app> ② Spring MVC ...

JavaWeb开发进阶SpringMVC简介

Spring MVC,又称为Spring Web MVC,名字来源于Spring模块spring-webmvc,是一个基于Servlet API开发的Web框架。

JavaWeb开发基础ServletFilter

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Filter是什么 Filter用于对请求和响应进行预处理和后处理。Filter链(Filter Chain)允许多个Filter依次处理同一个请求和响应。 Filter的使用场景 日志记录:记录请求和响应的详细信息,例如请求时间、响应时间、请求参数等 安全检查:检查用户是否有权限访问特定资源,例如验证用户身份、检查用户角色等 压缩:对响应内容进行压缩,例如使用GZIP压缩响应数据 字符编码设置:设置请求和响应的字符编码,例如将请求和响应的字符编码设置为UTF-8 输入验证:对请求参数进行验证,例如检查参数是否为空、参数格式是否正确等 Filter Interface Filter接口有3个方法: package javax.servlet; import java.io.IOException; public interface Filter { void init(FilterConfig var1) throws ServletException; void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; void destroy(); } 容器在启动时创建Filter实例,并调用其init(FilterConfig filterConfig)方法进行初始化。每次请求到达时,容器调用Filter的doFilter(ServletRequest request, ServletResponse response, FilterChain chain)方法进行过滤。容器在关闭时调用Filter的destroy()方法进行清理。 Filter可以通过两种方式进行配置: 1.在web.xml中配置: <filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 如果采用web.xml,那么去掉Filter只需要修改web.xml即可,不需要修改代码。 web.xml在低版本Servlet是必须的,在高版本Servlet已经不再需要。 2.使用注解配置: import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/*") public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化操作 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 预处理操作 System.out.println("Request received at " + System.currentTimeMillis()); // 继续执行下一个过滤器或目标资源 chain.doFilter(request, response); // 后处理操作 System.out.println("Response sent at " + System.currentTimeMillis()); } @Override public void destroy() { // 清理操作 } } FilterChain Interface Filter接口的doFilter方法,第3个参数类型是FilterChain,它的定义如下: ...

JavaWeb开发基础Servlet事件和监听器

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 事件和监听器 事件是指在程序运行过程中发生的特定动作或情况。比如: 用户操作,如点击按钮、输入文本 系统操作,如文件读取完成、网络连接断开 应用程序内部的状态变化,如对象属性改变、方法调用 监听器是一个接口或类,用于定义在特定事件发生时要执行的操作。监听器会“监听”特定的事件,当事件发生时,监听器中的相应方法会被调用,从而执行预定义的操作。 事件和监听器是相辅相成的,它们的工作原理如下: 事件源:触发事件的来源。例如,按钮是事件源,点击按钮会触发点击事件 事件对象:当事件发生时,事件源会创建一个事件对象,包含有关事件的信息 注册监听器:监听器需要注册到事件源,以便监听特定的事件。注册后,事件源会在事件发生时通知监听器 事件处理:当事件发生时,事件源会调用监听器中的相应方法,传递事件对象,从而执行预定义的操作 Servlet Event Class 事件(Event)是一个类,封装了与特定事件相关的信息。 基本是构造方法和get方法: ServletRequestEvent public class ServletRequestEvent extends EventObject { private static final long serialVersionUID = 1L; private final ServletRequest request; public ServletRequestEvent(ServletContext sc, ServletRequest request) { super(sc); this.request = request; } public ServletRequest getServletRequest() { return this.request; } public ServletContext getServletContext() { return (ServletContext) super.getSource(); } } ServletRequestAttributeEvent public class ServletRequestAttributeEvent extends ServletRequestEvent { private static final long serialVersionUID = 1L; private final String name; private final Object value; public ServletRequestAttributeEvent(ServletContext sc, ServletRequest request, String name, Object value) { super(sc, request); this.name = name; this.value = value; } public String getName() { return this.name; } public Object getValue() { return this.value; } } ServletContextEvent public class ServletContextEvent extends EventObject { private static final long serialVersionUID = 1L; public ServletContextEvent(ServletContext source) { super(source); } public ServletContext getServletContext() { return (ServletContext) super.getSource(); } } ServletContextAttributeEvent public class ServletContextAttributeEvent extends ServletContextEvent { private static final long serialVersionUID = 1L; private final String name; private final Object value; public ServletContextAttributeEvent(ServletContext source, String name, Object value) { super(source); this.name = name; this.value = value; } public String getName() { return this.name; } public Object getValue() { return this.value; } } HttpSessionEvent public class HttpSessionEvent extends EventObject { private static final long serialVersionUID = 1L; public HttpSessionEvent(HttpSession source) { super(source); } public HttpSession getSession() { return (HttpSession) super.getSource(); } } HttpSessionBindingEvent public class HttpSessionBindingEvent extends HttpSessionEvent { private static final long serialVersionUID = 1L; private final String name; private final Object value; public HttpSessionBindingEvent(HttpSession session, String name, Object value) { super(session); this.name = name; this.value = value; } public String getName() { return this.name; } public Object getValue() { return this.value; } } ...

JavaWeb开发基础ServletSession

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Session是什么 在Web应用程序中,Session(会话)是用于在多个请求之间保持用户状态的一种机制。由于HTTP协议是无状态的,每个请求都是独立的,服务器无法直接知道两个请求是否来自同一个用户。Session通过在服务器端存储用户状态信息,并在客户端使用一个唯一的Session ID来标识用户,从而实现状态保持。 Session工作原理如下: 创建Session:当用户第一次访问Web应用程序时,服务器创建一个新的Session,并生成一个唯一的Session ID 发送Session ID:服务器将Session ID发送给客户端,通常通过HTTP响应头中的Set-Cookie字段 存储Session ID:客户端浏览器将Session ID存储在Cookie中,并在后续请求中将其发送回服务器 识别Session:服务器通过接收到的Session ID识别用户的会话,并从服务器端存储中获取相应的Session数据 四种主要技术 Cookies Hidden Form Field URL Rewriting HttpSession 1. Cookies(Cookie) Cookie是存储在客户端浏览器中的小数据片段。它们会随着每个HTTP请求一起发送到服务器,可以用来存储会话标识符。 工作原理 当用户第一次访问网站时,服务器生成一个唯一的会话ID,并将其作为Cookie发送到客户端浏览器 浏览器存储这个Cookie,并在后续请求中将其发送回服务器 服务器使用Cookie中的会话ID来检索用户的会话数据 优点 对用户透明 由浏览器自动管理 可以存储少量数据 缺点 用户可以在浏览器中禁用Cookie 存储容量有限(通常每个Cookie大约4KB) 如果处理不当,可能存在安全问题(例如Cookie盗窃) 示例 import javax.servlet.http.Cookie; // 在Servlet中设置Cookie Cookie sessionCookie = new Cookie("JSESSIONID", session.getId()); sessionCookie.setMaxAge(30 * 60); // 30分钟 response.addCookie(sessionCookie); // 在Servlet中检索Cookie Cookie[] cookies = request.getCookies(); // 从请求获取Cookie if (cookies != null) { for (Cookie cookie : cookies) { if ("JSESSIONID".equals(cookie.getName())) { String sessionId = cookie.getValue(); // 使用会话ID检索会话数据 } } } Cookie有两种类型: ...

JavaWeb开发基础ServletConfig与ServletContext

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 ServletConfig package javax.servlet; import java.util.Enumeration; public interface ServletConfig { String getServletName(); ServletContext getServletContext(); String getInitParameter(String var1); Enumeration<String> getInitParameterNames(); } ServletConfig用于Servlet初始化时从web.xml获取配置信息。主要有以下方法: public String getInitParameter(String name): Returns the parameter value for the specified parameter name. public Enumeration getInitParameterNames(): Returns an enumeration of all the initialization parameter names. public String getServletName(): Returns the name of the servlet. public ServletContext getServletContext(): Returns an object of ServletContext. 示例,web.xml ...

JavaWeb开发基础Servlet请求分发与重定向

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 请求分发 Servlet的RequestDispatcher接口定义: package javax.servlet; import java.io.IOException; public interface RequestDispatcher { String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri"; String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path"; String FORWARD_PATH_INFO = "javax.servlet.forward.path_info"; String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path"; String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string"; String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri"; String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path"; String INCLUDE_PATH_INFO = "javax.servlet.include.path_info"; String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path"; String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string"; String ERROR_EXCEPTION = "javax.servlet.error.exception"; String ERROR_EXCEPTION_TYPE = "javax.servlet.error.exception_type"; String ERROR_MESSAGE = "javax.servlet.error.message"; String ERROR_REQUEST_URI = "javax.servlet.error.request_uri"; String ERROR_SERVLET_NAME = "javax.servlet.error.servlet_name"; String ERROR_STATUS_CODE = "javax.servlet.error.status_code"; void forward(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; void include(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; } 它有2个方法,forward和include: ...

JavaWeb开发基础Servlet生命周期与工作原理

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Servlet生命周期 Servlet的生命周期由Servlet容器(如Tomcat、Jetty等)管理,主要包括以下5个阶段: 加载Servlet类 创建Servlet实例 调用init方法 调用service方法 调用destroy方法 加载(Loading): 当Servlet容器启动或第一次接收到对某个Servlet的请求时,它会加载Servlet类 这个过程只发生一次,除非Servlet被卸载或容器重新启动 实例化(Instantiation): 在加载Servlet类之后,容器会创建一个Servlet实例 这个实例化过程也是一次性的,除非Servlet被卸载或容器重新启动 初始化(Initialization): 容器调用Servlet实例的init()方法进行初始化 init()方法只被调用一次,用于执行一次性的初始化任务,如读取配置参数、初始化资源等 你可以重写init()方法以执行自定义的初始化逻辑 public void init(ServletConfig config) 请求处理(Request Handling): 每当有请求到达时,容器会调用Servlet的service()方法来处理请求 service()方法根据请求的类型(如GET、POST等)调用相应的处理方法(如doGet()、doPost()等) public void service(ServletRequest request, ServletResponse response) 销毁(Destruction): 当容器决定卸载Servlet(如容器关闭或Servlet被重新加载)时,它会调用Servlet的destroy()方法 destroy()方法用于执行清理任务,如关闭资源、保存状态等 destroy()方法只被调用一次 public void destroy() Servlet重新加载 Servlet被重新加载通常发生在以下几种情况下: Servlet类文件被修改: 如果在开发过程中修改了Servlet类文件,Servlet容器可能会检测到这些更改并重新加载Servlet 这通常发生在开发环境中,生产环境中一般不会自动重新加载 容器配置发生变化: 如果修改了Servlet容器的配置文件(如web.xml),容器可能会重新加载相关的Servlet 容器重启: 当Servlet容器重启时,所有的Servlet都会被重新加载 手动重新加载: 某些Servlet容器提供了手动重新加载Servlet的功能,通常通过管理控制台或命令行工具 当Servlet被重新加载时,Servlet容器会执行以下步骤: 销毁现有的Servlet实例: 容器调用现有Servlet实例的destroy()方法,执行清理任务 释放资源,如关闭数据库连接、释放文件句柄等 卸载Servlet类: 容器卸载现有的Servlet类,释放类加载器持有的资源 重新加载Servlet类: 容器重新加载Servlet类文件,创建新的类加载器实例 实例化新的Servlet对象: 容器创建新的Servlet实例 初始化新的Servlet实例: 容器调用新的Servlet实例的init()方法进行初始化 Servlet代码示例 有3种方式使用Servlet: ①实现Servlet接口 import java.io.*; import javax.servlet.*; public class First implements Servlet { ServletConfig config = null; public void init(ServletConfig config) { this.config = config; System.out.println("servlet is initialized"); } public void service(ServletRequest req, ServletResponse res) throws IOException, ServletException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print("<html><body>"); out.print("<b>hello simple servlet</b>"); out.print("</body></html>"); } public void destroy() { System.out.println("servlet is destroyed"); } public ServletConfig getServletConfig() { return config; } public String getServletInfo() { return "copyright 2007-1010"; } } ②继承GenericServlet类 ...

JavaWeb开发基础ServletAPI

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Servlet版本 Oracle将Java EE(Java SE还自己保留)交给开源组织,Eclipse基金会接手。但Oracle不允许开源组织使用Java名号,所以Jakarta EE名称于2018.02.26应运而生。 正是因为组织变化,Servlet被割裂为了2个版本,javax.servlet和jakarta.servlet。 javax.servlet已经停止维护,但它仍然是一个非常有用和重要的技术,特别是在许多现有项目中,学习和使用它将为你提供坚实的Web开发基础。 <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> 如果希望使用Jakarta EE 9或更高版本的Servlet API,则需要切换到javax.servlet。 <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> 本文将基于javax.servlet来介绍Servlet,从Usages来看,它仍然是使用最广泛的。 Servlet API Servlet API主要有2个包,javax.servlet包含了servlet和web container使用的接口和类。javax.servlet.http包含了http相关的接口和类。 javax.servlet接口列表: Servlet ServletRequest ServletResponse RequestDispatcher ServletConfig ServletContext SingleThreadModel Filter FilterConfig FilterChain ServletRequestListener ServletRequestAttributeListener ServletContextListener ServletContextAttributeListener javax.servlet类列表: GenericServlet ServletInputStream ServletOutputStream ServletRequestWrapper ServletResponseWrapper ServletRequestEvent ServletContextEvent ServletRequestAttributeEvent ServletContextAttributeEvent ServletException UnavailableException javax.servlet.http接口列表: HttpServletRequest HttpServletResponse HttpSession HttpSessionListener HttpSessionAttributeListener HttpSessionBindingListener HttpSessionActivationListener HttpSessionContext (deprecated now) javax.servlet.http类列表: ...

JavaWeb开发基础Servlet简介

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Servlet是什么? 现在的Java Web开发,很少直接接触到Servlet。在Spring项目中,Spring Boot基于Spring Framework,简化了Spring应用程序开发,Spring Framework是一个全面的Java应用程序框架,其中包含Spring MVC模块,Spring MVC封装了Servlet,以实现Web功能。Servlet不属于Spirng项目,而是Java EE(后改名为Jakarta EE)的一部分。 Oracle将Java EE(Java SE还自己保留)交给开源组织,Eclipse基金会接手。但Oracle不允许开源组织使用Java名号,所以Jakarta EE名称于2018.02.26应运而生。 Servlet可以有很多种描述: Servlet是一个技术,用来创建Web应用程序 Servlet是一个API,提供了很多接口、类和文档 Servlet是一个接口,必须实现该接口来创建Servlet Servlet是一个类,位于服务端,接收请求,返回响应 Servlet是一个Web组件,用来创建动态Web页面 CGI与Servlet 在Servlet技术出现以前,Web应用程序是通过CGI(Common Gateway Interface),一种脚本语言,来实现的。 但是CGI存在很多缺点: 如果客户端增多,服务端响应会变慢 对于每个请求,CGI都会创建一个进程,进程数有限 依赖C、C++、perl等编程语言 Servlet技术出现以后,解决了很多CGI问题: 性能:每个请求创建一个线程,而不是进程 可移植性:因为使用了Java语言 健壮性:JVM管理Servlet,无需关心内存泄漏、垃圾回收等 安全性:因为使用了Java语言 总的来说,Servlet是Server Applet,服务端小程序。它是单例多线程的,每个Servlet类在Web容器中只有一个实例,每次客户端请求,Web Server都会从线程池中分配一个线程去创建Servlet,每个请求由一个独立的线程处理,这些线程共享同一个Servlet实例,通过HTTP协议接收和响应来自Web Client的请求。 参考资料: https://www.javatpoint.com/servlet-tutorial