嵌入式Tomcat学习-第五天
写在前面
什么是嵌入式 Tomcat?
嵌入式 Tomcat 是将 Apache Tomcat 服务器作为库文件集成到 Java 应用程序中的技术方案。它允许开发者通过编程方式直接启动、配置和管理 Tomcat,无需依赖独立安装的 Tomcat 服务器,适用于构建轻量级、自包含的 Web 应用或微服务。
版本特性(11.0.3)
- Servlet/JSP 规范支持
支持 Servlet 6.0 和 JSP 4.0 规范(基于 Jakarta EE 10 平台)。 - 轻量级嵌入
通过tomcat-embed-core
等依赖包实现核心功能集成,无需完整 Tomcat 安装。 - Java 版本要求
最低要求 Java 17 及以上版本。 - 性能优化
改进的 HTTP/2 支持、连接器性能调优及内存管理优化。
核心优势
- 简化部署
应用与服务器一体化,直接打包为可执行 JAR 文件,适合云原生场景。 - 灵活配置
通过代码动态配置端口、上下文路径、SSL 等参数,无需server.xml
文件。 - 开发便捷
与 Spring Boot、Micronaut 等框架无缝集成,快速构建独立 Web 服务。 - 资源占用低
仅加载必要的组件,启动速度快,适合资源受限环境。
典型应用场景
- 微服务架构中的独立服务节点
- 快速原型开发或测试环境
- 命令行工具集成 Web 接口
- 需要定制化 Web 容器行为的场景
为springmvc配置validator
pom.xml新增validator依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lhstack.tomcat</groupId>
<artifactId>tomcat-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.lmax/disruptor -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.2.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.24.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.24.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-core -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>11.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>11.0.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-websocket -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>11.0.3</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>aliyun</id>
<name>阿里云</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
</project>
spring-mvc.xml配置validator
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 2025-02-22 新增 注册validator bean,设置 providerClass为HibernateValidator实现 -->
<bean name="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
<!-- 设置validator,指向validator bean -->
<mvc:annotation-driven validator="validator" />
<!-- 2025-02-22 新增 设置jsp的视图解析器,对Controller返回的字符串自动组装成/WEB-INF/jsp/字符串.jsp -->
<mvc:view-resolvers>
<mvc:jsp prefix="/WEB-INF/jsp/" suffix=".jsp"/>
</mvc:view-resolvers>
<context:component-scan base-package="com.lhstack.tomcat.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
配置全局异常拦截器
获取参数名,需要修改pom.xml,配置编译保留参数名
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<target>${maven.compiler.target}</target>
<source>${maven.compiler.source}</source>
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
</plugins>
</build>
GlobalExceptionHandlers
package com.lhstack.tomcat.controller;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.HandlerMethodValidationException;
import java.util.Map;
import java.util.stream.Collectors;
@RestControllerAdvice
public class GlobalExceptionHandlers {
@ExceptionHandler(exception = MethodArgumentNotValidException.class)
public Map<String, Object> validatorExceptionHandler(MethodArgumentNotValidException e) {
Map<String, String> errors = e.getBindingResult().getAllErrors().stream()
.collect(Collectors.toMap(ObjectError::getObjectName, ObjectError::getDefaultMessage, (o1, o2) -> o2));
return Map.of("code", "500", "msg", "校验异常", "errors", errors);
}
@ExceptionHandler(exception = HandlerMethodValidationException.class)
public Map<String, Object> exceptionHandler(HandlerMethodValidationException e) {
Map<Object, String> errors = e.getParameterValidationResults().stream()
.collect(Collectors.toMap(item -> item.getMethodParameter().getParameterName(),
item -> item.getResolvableErrors().stream().map(MessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(",")), (o1, o2) -> o2));
return Map.of("code", "500", "msg", "校验异常", "errors", errors);
}
}
编写代码测试
package com.lhstack.tomcat.controller;
import jakarta.validation.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("test")
public class TestController {
private static final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
@GetMapping
public Map<String,String> test(@RequestParam(name = "value") @NotEmpty(message = "value不能为空") String value){
LOGGER.info("test: {}",value);
return Map.of("msg","hello world");
}
}
集成spring-security
pom增加spring-security依赖
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>6.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>6.4.3</version>
</dependency>
配置security
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>index</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">
<security:http entry-point-ref="authenticationEntryPoint">
<security:intercept-url pattern="/**" access="isAuthenticated()"/>
<security:csrf disabled="true"/>
<security:headers disabled="true"/>
<security:form-login authentication-failure-handler-ref="authenticationFailureHandler" authentication-success-handler-ref="authenticationSuccessHandler" />
</security:http>
<bean name="authenticationSuccessHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<constructor-arg name="defaultTargetUrl" value="/"/>
</bean>
<bean name="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<constructor-arg name="defaultFailureUrl" value="/login?error=error"/>
</bean>
<bean name="authenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint" >
<constructor-arg value="/login" />
</bean>
<security:user-service>
<security:user name="admin" authorities="ADMIN" password="{noop}123456"/>
</security:user-service>
</beans>
启动项目并测试
自动重定向到/login
输入错误的密码,自动重定向到/login页面
输入正确的密码
结尾
今天介绍了如何在嵌入式tomcat中增加validator以及全局异常拦截器和spring-security支持,让这个demo的功能逐步完善
嵌入式Tomcat学习-第五天
https://blog.lhstack.xyz/archives/qian-ru-shi-tomcatxue-xi-di-wu-tian