创建初始化类,替换web.xml

  • Servlet3.0环境中,Web容器(Tomcat)会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果找到的话就用它来配置Servlet容器。

  • Spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又会查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。

  • Spring3.2引入了一个便利的WebApplicationInitializer基础实现,名为AbstractAnnotationConfigDispatcherServletInitializer,当我们的类扩展了AbstractAnnotationConfigDispatcherServletInitializer并将其部署到Servlet3.0容器的时候,容器会自动发现它,并用它来配置Servlet上下文。

/**
 * @Author: lisong
 * @CreateTime: 2024-01-31 17:36 星期三
 * @Description: 当前类替换web.xml配置文件
 */
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    //设置spring配置类,替代spring.xml配置文件
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    //设置springmvc配置类,替代springmvc.xml配置文件
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVCConfig.class};
    }

    //设置SpringMVC的前端控制器DispatcherServlet的url-patten
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //设置当前工程的过滤器
    @Override
    protected Filter[] getServletFilters() {
        //创建字符编码过滤器对象
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        //设置字符编码
        characterEncodingFilter.setEncoding("UTF-8");
        //设置请求和响应的编码
        characterEncodingFilter.setForceEncoding(true);

        //创建rest风格请求方式的过滤器对象
        HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
        return new Filter[]{characterEncodingFilter,hiddenHttpMethodFilter};
    }
}

创建Sping配置类,替换Spring的配置文件

@Configurable
@PropertySource("classpath:jdbc.properties")
public class SpringConfig {
    //声明成员属性
    @Value("${jdbc.driver}") //将jdbc.properties中的信息初始化到属性中
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    //配置数据源
    @Bean
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    //配置jdbc模板,将数据源注入到模板中
    @Bean
    public JdbcTemplate jdbcTemplate(DruidDataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
}

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/dbtest1
jdbc.username=root
jdbc.password=123456

创建SpringMVC配置类,替换SpringMVC配置文件

/**
 * @Author: lisong
 * @CreateTime: 2024-01-31 17:40 星期三
 * @Description:该类替换springmvc.xml
 */
@Configurable //标识为配置类
@ComponentScan(basePackages = {"com.evan"})
@EnableWebMvc //开启mvc注解
public class SpringMVCConfig implements WebMvcConfigurer {

    //配置Spring视图模板解析器的相关策略
    @Bean
    public ITemplateResolver templateResolver() {
        //创建spring视图模板解析器对象
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        //设置视图字符集
        templateResolver.setCharacterEncoding("UTF-8");
        //设置视图优先级
        templateResolver.setOrder(1);
        //设置视图模式
        templateResolver.setTemplateMode("HTML5");
        //设置视图前缀
        templateResolver.setPrefix("/WEB-INF/views/");
        //设置视图后缀
        templateResolver.setSuffix(".html");
        return templateResolver;
    }

    //生成Spring的模板引擎,并为模板引擎注入模板解析器
    @Bean
    public TemplateEngine templateEngine(ITemplateResolver iTemplateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(iTemplateResolver);
        return templateEngine;
    }

    //生成Thymeleaf视图解析器,并为视图解析器注入spring的模板引擎
    @Bean
    public ViewResolver thymeleafViewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
        thymeleafViewResolver.setCharacterEncoding("UTF-8");
        thymeleafViewResolver.setOrder(1);
        thymeleafViewResolver.setTemplateEngine(templateEngine);
        return thymeleafViewResolver;
    }

    //配置文件上传解析器
    @Bean
    public CommonsMultipartResolver multipartResolver() {
        return new CommonsMultipartResolver();
    }

    //配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //创建自定义拦截器实现类对象
        FirstInterceptor firstInterceptor = new FirstInterceptor();
        //配置拦截所有请求路径,排除/hello请求
        registry.addInterceptor(firstInterceptor).addPathPatterns("/**")
                .excludePathPatterns("/hello");
    }

    //配置视图控制器
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        //设置视图控制器策略
        registry.addViewController("/").setStatusCode(HttpStatus.OK).setViewName("index");
    }

    //配置默认的servlet处理静态资源
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        //开启默认的servlet静态资源处理
        configurer.enable();
    }

    //配置异常处理器
    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        //创建自定义异常处理器对象
        SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
        //创建属性对象
        Properties properties = new Properties();
        //注入全类名异常,并指定异常逻辑视图
        properties.setProperty("java.lang.ArithmeticException","error");
        //将异常属性注入到异常映射中
        exceptionResolver.setExceptionMappings(properties);
        //将异常信息注入到请求域中,浏览器可以通过请求域获取异常信息
        exceptionResolver.setExceptionAttribute("ex");
        //添加异常解析器
        resolvers.add(exceptionResolver);
    }
}

创建自定义拦截器

@Component
public class FirstInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("FirstInterceptor->preHandle");
        return HandlerInterceptor.super.preHandle(request,response,handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("FirstInterceptor->postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("FirstInterceptor->after");
    }
}

创建视图index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h1>index.html</h1>
<a th:href="@{/test/error}">测试异常处理器</a>
</body>
</html>

创建视图error.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>错误</title>
</head>
<body>
<h1>error.html</h1>
<hr>
<p th:text="${ex}"/>
</body>
</html>
测试
@Controller
public class TestController {

    @GetMapping("/test/error")
    public String testError() {
        System.out.println(10 / 0);
        return "success";
    }
}