目录
1.拦截器
1.HandlerInterceptor 接口,创建一个类实现HandlerInterceptor接口
2.配置拦截器 --将拦截器注册到容器中
3.拦截器原理和执行顺序
2.文件上传
1.页面表单
2.文件上传代码
3.自动配置原理--文件上传自动配置类
MultipartAutoConfiguration-MultipartProperties
拦截器通常用来检查用户是否登录,未登录则不能访问其他页面
/** * 登录检查 * 1、配置好拦截器要拦截哪些请求 * 2、把这些配置放在容器中 */ public class LoginInterceptor implements HandlerInterceptor { //目标方法执行之前 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //登录检查逻辑 HttpSession session = request.getSession(); Object loginUser = session.getAttribute("loginUser"); if(loginUser != null){ //放行 return true; } //拦截住。未登录。跳转到登录页 request.setAttribute("msg","请先登录"); request.getRequestDispatcher("/").forward(request,response); return false; } //目标方法执行完成以后 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } //页面渲染以后 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
实现HandlerInterceptor接口之后实现其内部的三个方法,分别对应目标方法执行前的操作,执行后的操作和进行页面渲染之后的操作
(实现WebMvcConfigurer中的addInterceptors方法)
注意:/**会拦截所有请求包括静态资源(如css,js文件)
@Configuration public class AdminWebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/**") //所有请求都被拦截包括静态资源 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行的请求 } }
1、根据当前请求,找到HandlerExecutionChain【可以处理请求的handler以及handler的所有 拦截器】
2、先来顺序执行 所有拦截器的 preHandle方法
3、如果任何一个拦截器返回false。直接跳出不执行目标方法
4、所有拦截器都返回True。执行目标方法
5、倒序执行所有拦截器的postHandle方法。
6、前面的步骤有任何异常都会直接倒序触发 afterCompletion
7、页面成功渲染完成以后,也会倒序触发 afterCompletion
<form method="post" action="/upload" enctype="multipart/form-data"> <input type="file" name="file"><br> <input type="submit" value="提交"> </form>
/** * MultipartFile 自动封装上传过来的文件 * @param email * @param username * @param headerImg * @param photos * @return */ @PostMapping("/upload") public String upload(@RequestParam("email") String email, @RequestParam("username") String username, @RequestPart("headerImg") MultipartFile headerImg, @RequestPart("photos") MultipartFile[] photos) throws IOException { log.info("上传的信息:email={},username={},headerImg={},photos={}", email,username,headerImg.getSize(),photos.length); if(!headerImg.isEmpty()){ //保存到文件服务器,OSS服务器 String originalFilename = headerImg.getOriginalFilename(); headerImg.transferTo(new File("H:\\cache\\"+originalFilename)); } if(photos.length > 0){ for (MultipartFile photo : photos) { if(!photo.isEmpty()){ String originalFilename = photo.getOriginalFilename(); photo.transferTo(new File("H:\\cache\\"+originalFilename)); } } } return "main"; }
页面点击上传后文件就会上传到指定地址,注意:文件有默认的最大值限制,如果有特殊需要应在application.properties文件中进行修改
spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=100MB
MultipartAutoConfiguration-MultipartProperties
原理步骤
1、请求进来使用文件上传解析器判断(isMultipart)并封装(resolveMultipart,返回MultipartHttpServletRequest)文件上传请求
2、参数解析器来解析请求中的文件内容封装成MultipartFile
3、将request中文件信息封装为一个Map;MultiValueMap<String, MultipartFile>FileCopyUtils。实现文件流的拷贝