2.2 拦截器
用户登陆成功之后,再发送任意请求的时候都应该是有个登录判断的过程(判断session中是否有正确的用户名和密码),这个功能可以在每个controller使用代码进行判断,但是这个过程是重复的会大大增加代码的冗余,于是我们可以将判断功能放在拦截器中,将登陆成功后的所有从页面发送的请求拦截住进行用户判断,成功则放行失败则返回登录。
以上述例子为例讲解拦截器的使用:
第一步: 自定义拦截器(实现HandlerInterceptor接口,重写内置方法在相应的方法内编写判断逻辑)
public class LoginInterceptor implements HandlerInterceptor {
// 在目标方法执行之前执行的方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 实现登录检查的逻辑
HttpSession session = request.getSession();
Object user = session.getAttribute("loginUser");
if (user != 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 {
}
}
第二步: 自定义配置类实现WebMvcConfigurer接口,重写addInterceptors方法将拦截器注册进容器中,并指定拦截规则
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 有个问题就是,拦截器拦截的不只是动态请求,还有静态的页面资源和样式,所以也要将静态资源放行
registry.addInterceptor(new LoginInterceptor())
// 拦截所有的请求
.addPathPatterns("/**")
// 直接放行的请求
.excludePathPatterns("/", "/login", "/css/**", "/fonts/**", "/js/**", "/images/**");
}
}
2.3 文件上传
文件上传需要前后端的协调配合,前端使用一个form表单提交所有的信息,包括单文件上传和多文件上传,后端使用注解获取到表单中的所有值,对他们进行操作
前端表单:
<form role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">
<!--email邮箱-->
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
</div>
<!--userName用户名-->
<div class="form-group">
<label for="exampleInputPassword1">userName</label>
<input type="text" name="userName" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<!--单文件上传 头像-->
<div class="form-group">
<label for="exampleInputFile">headerImg</label>
<input type="file" name="headerImg" id="exampleInputFile">
</div>
<!--多文件上传 生活照-->
<div class="form-group">
<label for="exampleInputFile">image of yourself</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">Submit</button>
</form>
后端controller:
@PostMapping("/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("userName") String userName,
@RequestPart("headerImg")MultipartFile headerImg,
@RequestPart("photos")MultipartFile[] photos) throws IOException {
// 将头像保存到本地磁盘中
if (!headerImg.isEmpty()) {
// 创建相应的文件夹
File file1 = new File("E:\\bootTest\\" + userName + "\\headerImg");
file1.mkdirs();
// 获取图片名 生成存储路径
headerImg.transferTo(new File("E:\\bootTest\\" + userName + "\\headerImg\\" + headerImg.getOriginalFilename()));
}
// 将生活照保存到本地磁盘中
if (photos.length > 0) {
// 创建相应的文件夹
File file1 = new File("E:\\bootTest\\" + userName + "\\photos");
file1.mkdirs();
// 存储图片
for (MultipartFile photo:photos) {
if (!photo.isEmpty()) {
// 获取图片名 生成存储路径
photo.transferTo(new File("E:\\bootTest\\" + userName + "\\photos\\" + photo.getOriginalFilename()));
}
}
}
return "index";
}
文件上传的配置: