ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

第四十九天学习心得

第四十九天学习心得 SpringMVC异常处理、拦截器与SSM整合学习心得体会日期2026年9月22日昨天完成了SpringMVC的基础和进阶内容今天继续深入学习了异常处理、拦截器、日期格式处理最后还完成了一个重要的实战项目——用聚合工程整合SSM框架。今天的知识让我真正体会到了企业级项目开发的完整流程。一、统一异常处理在之前的开发中每个方法都要写try-catch代码又乱又重复。今天学习的RestControllerAdvice注解彻底解决了这个问题。先自定义一个业务异常public class ApiException extends RuntimeException {private AxiosStatus axiosStatus;public ApiException(AxiosStatus axiosStatus) {this.axiosStatus axiosStatus;}public AxiosStatus getAxiosStatus() {return axiosStatus;}}然后创建一个全局异常处理器RestControllerAdvicepublic class MyExceptionHandler {ExceptionHandler(ApiException.class)public AxiosResult handler(ApiException apiException) {return AxiosResult.error(apiException.getAxiosStatus());}ExceptionHandler(ArithmeticException.class)public String handler2(ArithmeticException arithmeticException) {return / by zero;}}这样只要Controller里抛出ApiException就会被自动拦截并转换成统一的JSON响应格式。RestControllerAdvice配合ExceptionHandler可以针对不同类型的异常做不同的处理代码非常清晰。我的理解是这套机制本质上是SpringMVC在Controller方法外层包了一层代理当方法抛出异常时代理捕获异常并交给匹配的异常处理方法。二、拦截器拦截器属于SpringMVC体系会拦截所有匹配的Mapping请求。这和之前的Filter不同Filter属于Servlet规范拦截范围更广而拦截器是SpringMVC提供的更灵活可以精确控制哪些请求被拦截。创建一个拦截器需要实现HandlerInterceptor接口有三个方法preHandleController方法执行之前执行返回true放行返回false拦截。postHandleController方法执行完毕后、视图渲染之前执行。afterCompletion整个请求全部结束、视图渲染完成后执行。课程上展示了两个拦截器来测试执行顺序public class FirstInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println(first preHandle);return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(first postHandle);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println(first afterCompletion);}}然后在配置类中注册Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new FirstInterceptor()).addPathPatterns(/**).excludePathPatterns(/login, /aa/**);registry.addInterceptor(new SecondInterceptor()).addPathPatterns(/**).excludePathPatterns(/login, /aa/**);}多个拦截器的执行顺序是先注册的preHandle先执行后注册的postHandle先执行。有点像栈的结构。拦截器最典型的应用场景就是登录校验在preHandle里判断session中是否有用户信息没有就拦截并跳转到登录页。三、日期格式处理日期格式的处理是Web开发中很常见的需求。SpringMVC提供了多种方式来处理前端传来的日期字符串。普通参数用DateTimeFormat注解PostMapping(add)public void add(String uname, DateTimeFormat(pattern yyyy-MM-dd) Date ctime) {System.out.println(uname);System.out.println(ctime);}实体类参数也一样在属性上加注解Datapublic class User {private Integer id;private String username;DateTimeFormat(pattern yyyy-MM-dd)private Date utime;}但如果前端传的日期格式不固定比如有时候是yyyy-MM-dd有时候是yyyy/MM/dd就需要自定义类型转换器public class StringToDate implements ConverterString, Date {private static final String[] PATTERNS {yyyy-MM-dd HH:mm:ss,yyyy-MM-dd HH:mm,yyyy-MM-dd,yyyy/MM/dd HH:mm:ss,yyyy/MM/dd};Overridepublic Date convert(String source) {if (source null || source.trim().isBlank()) {return null;}for (String pattern : PATTERNS) {SimpleDateFormat sdf new SimpleDateFormat(pattern);try {return sdf.parse(source.trim());} catch (ParseException e) {continue;}}throw new IllegalArgumentException(无法解析日期格式 source);}}然后在配置类中注册Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverter(new StringToDate());registry.addConverter(new StringToDateTime());}对于JSON格式的日期还需要引入jackson-datatype-jsr310依赖让Jackson能够正确处理Java 8的日期类型。四、SSM聚合工程整合今天最重要的内容是整合SSM框架。之前学的Spring、SpringMVC、MyBatis都是单独使用的今天要把它们整合到一个项目里。首先是项目结构用Maven的聚合工程分成四个模块父工程统一管理依赖版本。entity模块存放实体类。mapper模块存放MyBatis的Mapper接口和XML文件。service模块存放业务逻辑代码。web模块存放Controller是war项目。父工程的pom中用dependencyManagement统一管理版本propertiesspring-version6.2.12/spring-versionmybatis-version3.5.19/mybatis-versiondruid-version1.2.28/druid-versionmybatis-spring-version4.1.0/mybatis-spring-version/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework/groupIdartifactIdspring-webmvc/artifactIdversion${spring-version}/version/dependency!-- 其他依赖 --/dependencies/dependencyManagement这样各个子模块引用依赖时就不需要写版本号了统一由父工程管理。各个模块的配置类Mapper模块的配置类负责数据源、SqlSessionFactory和Mapper扫描Configurationpublic class MapperConfig {Beanpublic DataSource dataSource() {DruidDataSource dataSource new DruidDataSource();dataSource.setDriverClassName(com.mysql.cj.jdbc.Driver);dataSource.setUrl(jdbc:mysql:///ssm);dataSource.setUsername(root);dataSource.setPassword(root);return dataSource;}Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean() {SqlSessionFactoryBean factoryBean new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource());return factoryBean;}Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer configurer new MapperScannerConfigurer();configurer.setBasePackage(cn.javasm.mapper);return configurer;}}Service模块的配置类负责包扫描和AOPConfigurationComponentScan(cn.javasm.service)EnableAspectJAutoProxypublic class ServiceConfig {}Web模块的配置类负责Controller扫描和MVC注解开启ConfigurationComponentScan(cn.javasm.controller)EnableWebMvcpublic class ControllerConfig {}最关键的是父子容器的配置。SpringMVC中DispatcherServlet对应一个子容器而ContextLoaderListener对应一个父容器。父容器管理Service和Mapper子容器管理Controller。public class MyWebAppInit extends AbstractAnnotationConfigDispatcherServletInitializer {Overrideprotected Class?[] getRootConfigClasses() {return new Class[]{MapperConfig.class, ServiceConfig.class};}Overrideprotected Class?[] getServletConfigClasses() {return new Class[]{ControllerConfig.class};}Overrideprotected String[] getServletMappings() {return new String[]{/};}}这样Controller可以注入ServiceService可以注入Mapper整个链路就打通了。五、今日总结今天的内容非常充实是SSM框架学习的收官之战。异常处理让代码更干净拦截器让权限控制更优雅日期处理解决了实际开发中的常见问题SSM整合让我看到了企业级项目的完整结构。几点深刻感悟第一统一异常处理是项目规范化的标志。以前每个方法都要try-catch现在只需要定义好异常类型和处理器代码清爽了很多。第二拦截器和过滤器的区别要分清楚。过滤器属于Servlet规范拦截器属于SpringMVC过滤器在DispatcherServlet之前执行拦截器在Controller之前执行。做登录校验用拦截器更合适因为可以精确控制拦截路径。第三聚合工程是企业开发的标配。通过父子工程的依赖管理各模块各司其职代码结构清晰。父容器和子容器的设计也很巧妙Controller层只关心Web逻辑Service和Mapper层由父容器统一管理。第四整合SSM的过程虽然繁琐但理解了每个配置类的作用之后就清晰了。MapperConfig管数据层ServiceConfig管业务层ControllerConfig管Web层各司其职。明天也继续加油
返回列表