Spring MVC的定制配置需要配置类实现WebMvcConfigurer接口,并在配置类使用@EnableWebMvc注解来开启对Spring MVC的配置支持,这样开发者就可以重写接口方法完成常用的配置。
静态资源配置

    应用的静态资源(CSS、JS、图片)等需要直接访问,这时需要开发者在配置类重写public void addResourceHandlers(ResourceHandlerRegistry registry)接口方法来实现。
/**
 * 配置静态资源
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
   registry.addResourceHandler("/html/**").addResourceLocations("/html/");
   //addResourceHandler指的是对外暴露的访问路径
   //addResourceLocations指的是静态资源存放的位置
}
拦截器配置

    Spring的拦截器(Interceptor)实现对每一个请求处理前后进行相关的业务处理,类似于Servlet的过滤器(Filter)。开发者如需要自定义Spring的拦截器,可以通过以下两个步骤完成:
    1.创建自定义拦截器类
    2.配置拦截器
创建自定义拦截器类

    自定义拦截器类需要实现HandlerInterceptor接口或继承HandlerInterceptorAdapter类,示例代码如下:
public class MyInteceptor implements HandlerInterceptor{
    /**
     * 重写preHandle方法在请求发生前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("preHandle方法在请求发生前执行");
        return true;
    }
    /**
     * 重写postHandle方法在请求完成后执行
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle方法在请求完成后执行");
    }
}
配置拦截器

    在配置类中,需要首先配置拦截器Bean,然后重写addInterceptors方法注册拦截器,示例代码如下:
/**
* 配置拦截器Bean
 */
@Bean
public MyInteceptor myInteceptor() {
    return new MyInteceptor();
}
/**
 * 重写addInterceptors方法注册拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(myInteceptor());
}
文件上传配置

文件上传是一个应用中经常使用的功能,Spring MVC通过配置一个MultipartResolver来上传文件。在Spring MVC的控制器中,可以通过MultipartFile myfile来接收单个文件上传,通过List<MultipartFile> myfiles来接收多个文件上传。
   由于Spring MVC框架的文件上传是基于commons-fileupload组件的文件上传。因此,需要将commons-fileupload组件相关的jar(commons-fileupload.jar和commons-io.jar)拷贝到Spring MVC应用的WEB-INF/lib目录下。

Commons是Apache开放源代码组织中的一个Java子项目,该项目包括文件上传、命令行处理、数据库连接池、XML配置文件处理等模块。fileupload就是其中用来处理基于表单的文件上传的子项目,commons-fileupload组件性能优良,并支持任意大小文件的上传。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/multifile" method="post" enctype="multipart/form-data">  
    选择文件1:<input type="file" name="myfile">  <br>
    文件描述1:<input type="text" name="description"> <br>
    选择文件2:<input type="file" name="myfile">  <br>
    文件描述2:<input type="text" name="description"> <br>
    选择文件3:<input type="file" name="myfile">  <br>
    文件描述3:<input type="text" name="description"> <br>
 <input type="submit" value="提交">   
</form> 
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <table>
        <tr>
            <td>详情</td><td>文件名</td>
        </tr>
        <!-- 同时取两个数组的元素 -->
        <c:forEach items="${multiFileDomain.description}" var="description" varStatus="loop">
            <tr>
                <td>${description}</td>
                <td>${multiFileDomain.myfile[loop.count-1].originalFilename}</td>
            </tr>
        </c:forEach>
        <!-- fileDomain.getMyfile().getOriginalFilename() -->
    </table>
</body>
</html>
package pojo;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public class MultiFileDomain {
    private List<String> description;
    private List<MultipartFile> myfile;
    public List<String> getDescription() {
        return description;
    }
    public void setDescription(List<String> description) {
        this.description = description;
    }
    public List<MultipartFile> getMyfile() {
        return myfile;
    }
    public void setMyfile(List<MultipartFile> myfile) {
        this.myfile = myfile;
    }
}
package config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class WebConfig implements WebApplicationInitializer{
    @Override
    public void onStartup(ServletContext arg0) throws ServletException {
        AnnotationConfigWebApplicationContext ctx 
        = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMVCConfig.class);//注册Spring MVC的Java配置类SpringMVCConfig
        ctx.setServletContext(arg0);//和当前ServletContext关联
        /**
         * 注册Spring MVC的DispatcherServlet
         */
        Dynamic servlet = arg0.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"controller","service"})
public class SpringMVCConfig implements WebMvcConfigurer {
    /**
     * 配置视图解析器
     */
    @Bean
    public InternalResourceViewResolver getViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
    /**
     * 配置静态资源
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/html/**").addResourceLocations("/html/");
        //addResourceHandler指的是对外暴露的访问路径
        //addResourceLocations指的是静态资源存放的位置
    }
    /**
     * MultipartResolver配置
     */
    @Bean
    public MultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        //设置上传文件的最大值,单位为字节
        multipartResolver.setMaxUploadSize(5400000);
        //设置请求的编码格式,默认为iso-8859-1
        multipartResolver.setDefaultEncoding("UTF-8");
        return multipartResolver;
    }
}
package controller;
import java.io.File;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import pojo.MultiFileDomain;
@Controller
public class MutiFilesController {
    // 得到一个用来记录日志的对象,这样打印信息时,能够标记打印的是哪个类的信息
    private static final Log logger = LogFactory.getLog(MutiFilesController.class);
    /**
     * 多文件上传
     */
    @RequestMapping("/multifile")
    public String multiFileUpload(@ModelAttribute MultiFileDomain multiFileDomain, HttpServletRequest request){
        String realpath = request.getServletContext().getRealPath("uploadfiles");  
        //上传到eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/ch2_6/uploadfiles
        File targetDir = new File(realpath); 
        if(!targetDir.exists()){  
            targetDir.mkdirs();  
        } 
        List<MultipartFile> files = multiFileDomain.getMyfile();
        for (int i = 0; i < files.size(); i++) {
            MultipartFile file = files.get(i);
            String fileName = file.getOriginalFilename();
            File targetFile = new File(realpath,fileName);
            //上传 
            try {  
                file.transferTo(targetFile);  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }
        logger.info("成功");
        return "showMulti";
    }
}