一、拦截器Interceptor
拦截器 Interceptor 多用于登录检查与静态资源放行场景。
拦截器的实现步骤
-
编写一个拦截器实现
HandlerInterceptor
接口@Slf4j public class LoginInterceptor implements HandlerInterceptor { /** * 目标方法执行之前 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); log.info("preHandle拦截的请求路径是{}",requestURI); //登录检查逻辑 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 { log.info("postHandle执行{}",modelAndView); } /** * 页面渲染以后 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("afterCompletion执行异常{}",ex); } }
-
拦截器注册到容器中(实现
WebMvcConfigurer
的addInterceptors()
)@Configuration public class AdminWebConfig implements WebMvcConfigurer{ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor());//拦截器注册到容器中 }
-
指定拦截规则(注:若设置为拦截所有,则静态资源也会被拦截)
@Configuration public class AdminWebConfig implements WebMvcConfigurer{ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor())//拦截器注册到容器中 .addPathPatterns("/**") //所有请求都被拦截包括静态资源 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**", "/js/**","/aa/**"); //放行的请求 }
拦截器的执行原理
-
根据当前请求,找到
HandlerExecutionChain
(可以处理请求的handler以及handler的所有拦截器) -
先来顺序执行所有拦截器的
preHandle()
方法。 如果当前拦截器
preHandle()
返回为true
,则执行下一个拦截器的preHandle()
如果当前拦截器返回为
false
。直接倒序执行所有已经执行了的拦截器的afterCompletion();
。 -
如果任何一个拦截器返回
false
,直接跳出不执行目标方法。 -
所有拦截器都返回
true
,才执行目标方法。 -
倒序执行所有拦截器的
postHandle()
方法。 -
前面的步骤有任何异常都会直接倒序触发
afterCompletion()
。 -
页面成功渲染完成以后,也会倒序触发
afterCompletion()
。
二、文件上传
文件上传可以有单文件与多文件的形式。
文件上传实现事例
页面事例代码:
<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleInputEmail1">邮箱</label>
<input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">名字</label>
<input type="text" name="username" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleInputFile">头像</label>
<input type="file" name="headerImg" id="exampleInputFile">
</div>
<div class="form-group">
<label for="exampleInputFile">生活照</label>
<input type="file" name="photos" multiple>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</div>
<button type="submit" class="btn btn-primary">提交</button>
</form>
控制层代码:(上述页面存放位置:/static/admin/form.html)
@Slf4j
@Controller
public class FormController {
@GetMapping("/form")
public String form_layouts(){
return "admin/form";
}
@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()){
//保存到文件到磁盘某处
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";
}
}
相关配置类与配置项
SpringBoot中的文件上传配置类:
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.MultipartProperties
常用相关配置项:
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB