Spring MVC 笔记--配置基于JavaConfig

主要使用基于 JavaConfig 方式配置

配置 DispatcherServlet

通过继承抽象类AbstractAnnotationConfigDispatcherServletInitializer来自动配置 DispatcherServlet 和 Spring 应用上下文(不需在 xml 中配置)

public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
​
    // 指定 Spring 应用上下文配置类(主要配置 web 组件的 Bean)
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }
  
    // 相对应的另一个应用上下文配置类(应用中的其他 Bean)
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }
​
    // 将 DispatcherServlet 映射到 "/"
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

其中 WebConfig 主要配置 web 组件相关的 Bean,如控制器、视图解析器以及处理映射器等,内容大致如下

@Configuration // 标志这个类为配置类
@EnableWebMvc // 启用注解驱动的 Spring MVC,同xml配置方式的<mvc:annotation-driven>
@ComponentScan("spitter.web") // 扫描这个包中的 Bean 组件
public class WebConfig extends WebMvcConfigurerAdapter{
​
    /**
     * 配置视图解析器
     */
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }
​
    /**
     * 配置静态资源的处理
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
  
    // 其他 web 相关 Bean 等... 
}

RootConfig 配置除 web 组件外的其他 Bean,内容大致如下

@Configuration
// 配置扫描的包,以及过滤条件
@ComponentScan(basePackages = {"spitter"}, excludeFilters = {
    @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})
public class RootConfig {
    // Bean 等
}

WebConfig 与 RootConfig 配置内容的区别具体可参考如下的 Spring 文档中的图片

不过这个不是强制要分开的,我们也可以把它们配置在一个文件中

添加 Controller 等

可以在相应位置添加对应 Controller 、jsp 文件等

列一个简单的 Controller

@Controller
@RequestMapping("/")
public class HomeController {
    @RequestMapping(method = RequestMethod.GET)
    public String home() {
        return "home";
    }
}

文件结构 

文件整体结构如下:

上面的内容就是一个简单的基于 SpringMVC 的应用,下面来说一下 SpringMVC 的其他功能

数据校验

  1. 添加实现 Java Validation API 的 jar 包,如 Hibernate Validator

  2. 在实体类中对应字段使用相应的注解,如 @NotNull、@Size、@Max、@Min 等

在控制器中的使用

@RequestMapping(value="/", method=RequestMethod.GET)
public String processRegistration(@Valid Spitter spitter, Errors errors) {
    if (errors.hasErrors()) {
        return "errorpage"; // 校验错误,进入错误页面
    }
    // 执行业务操作
    return "successpage";
}

文件上传

如要进行文件上传,需配置 multipart 解析器,可以选择如下其中的一种配置

  • CommonsMultipartResolver : 使用 Jakarta Commons FileUpload 解析 multipart 请求

  • StandardServletMultipartResolver : 依赖于 Servlet 3.0 对 multipart 请求的支持

@Bean
public MultipartResolver multipartResolver() throws IOException {
     // 使用 CommonsMultipartResolver 解析器
     CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
     multipartResolver.setUploadTempDir(new FileSystemResource("aa/bb")); // 文件临时保存目录
     multipartResolver.setMaxUploadSize(2048000); // 上传文件的大小上限
     multipartResolver.setMaxInMemorySize(0); // 当文件达到这个设置大小时,将写入到临时文件路径中
     return multipartResolver;
  
     // 使用 StandardServletMultipartResolver 解析器
     return new StandardServletMultipartResolver();
}

如果选择使用 StandardServletMultipartResolver 解析器,则其中的配置需要在 Servlet 中进行,在这个记录中,就是在之前配置的 SpittrWebAppInitializer 类中添加如下内容(重写 customizeRegistration 方法):

public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
​
    // 省略内容见上面的对应文件 
  
    @Override
    protected void customizeRegistration(Dynamic registration) {
        registration.setMultipartConfig(new MultipartConfigElement("/tmp/spittr/uploadss", 2048000, 4096000, 0));
    }
}

其中 MultipartConfigElement 有四个参数,分别为:

  1. 临时路径的位置

  2. 上传文件的最大容量,以字节为单位(默认无限制)

  3. 整个 multipart 请求的最大容量

  4. ​在上传的过程中,如果文件达到指定大小,将会写入到临时文件路径中(默认值为0)

对应的控制器中,可以使用 MultipartFile 获取文件,进行后续操作

处理异常

将异常映射为状态码: 在异常上面添加注解 @ResponseStatus(value = HttpStatus.NOT_FOUND, reason ="")

编写异常处理方法:

@ExceptionHandler(DuplicateException.class)
public String handleDuplidateException() {
    return "error";
}

这个方法将会拦截所在类中的所有异常,进行处理

如果我们想要一个能处理所有控制器方法中异常的功能,则需要使用控制器通知(@ControllerAdvice)

@ControllerAdvice
public class AppWideExceptionHandler {
    @ExceptionHandler(DuplicateException.class)
    public String handleDuplidateException() {
        return "error";
    }
  
    // ...
}
原文地址:https://www.cnblogs.com/zawier/p/7291883.html