SpringMVC——文件上传、异常处理、拦截器

SpringMVC——文件上传、异常处理、拦截器

1. 异常处理

系统中异常包括两类:预期异常和运行时异常 RuntimeException,前者通过捕获异常从而获取异常信息, 后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。 系统的 dao、service、controller 出现都通过 throws Exception向上抛出,最后由 springmvc 前端 控制器交由异常处理器进行异常处理。

1. 处理方式1

自定义异常处理类,并实现HandlerExceptionResolver接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component
public class SysExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
//获取异常
SysException ex = null;
if(e instanceof SysException){
ex = (SysException) e;
}else{
ex = new SysException("系统正在维护");
}

//创建ModelAndView对象
ModelAndView mv= new ModelAndView();
mv.addObject("errorMsg",e.getMessage());
mv.setViewName("error");
return mv;
}
}

2. 处理方式

使用@ExceptionHandler注解加在方法上,处理异常。

另外,可以在异常处理类上加上@ControllerAdvice,用来处理控制器的全局配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@ResponseBody
@ControllerAdvice
public class CustmomizeExceptionHandler {
@ExceptionHandler(Exception.class)
Object handleControllerException(HttpServletRequest request, Throwable e, Model model) {

String contentType = request.getContentType();

if ("application/json".equals(contentType)) {
//返回json
if (e instanceof CustomizeException) {
return ResultDTO.errorOf((CustomizeException)e);
} else {
return ResultDTO.errorOf(CustomizeErrorCode.SYSTEM_ERROR);
}

} else {
//错误页面详情
if (e instanceof CustomizeException) {
model.addAttribute("message", e.getMessage());
} else {
model.addAttribute("message", CustomizeErrorCode.SYSTEM_ERROR.getMessage());
}
return new ModelAndView("error");

}
}


}

2. 拦截器

拦截器可以对控制器的方法进行预处理或后处理。

preHandler:在controller方法前执行。如果返回true,放行执行控制器方法,否则不放行。

postHandler:在controller方法执行后执行。

afterHandler:前端控制器完全处理完请求后再执行。

编写代码时,需要实现HandlerInterceptor接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class MyInterceptor1 implements HandlerInterceptor {
/**
*
* @param request
* @param response
* @param handler
* @return 如果为true,放行,执行controller方法,否则不放行
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor1执行了");
request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
return true;
}

/**
* controller方法执行后
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor1执行后");
// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
}

/**
* success.jsp页面执行后,该方法执行
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("最后");

}
}

配置拦截器时,可以在xml文件中配置:

1
2
3
4
5
6
7
8
<mvc:interceptors>
<mvc:interceptor>
<!--要拦截的具体方法-->
<mvc:mapping path="/user/*"/>
<!--配置拦截器对象-->
<bean id="myInterceptor1" class="com.billychen.interceptor.MyInterceptor1"></bean>
</mvc:interceptor>
</mvc:interceptors>

也可以在Java配置类中配置

1
2
3
4
5
6
7
8
9
10
11
@Configuration
public class WebConfig implements WebMvcConfigurer {

@Autowired
private SessionInterceptor sessionInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(sessionInterceptor).addPathPatterns("/**");
}
}

3. 文件上传

Spring MVC可以为我们简化文件的上传,使用MultipartFile对象来获得上传的文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RequestMapping("/fileUpload2")
public String fileUpload2(HttpServletRequest request, MultipartFile upload) throws IOException {
System.out.println("file upload2");
//使用fileupload组件完成文件上传
//上传位置
String path = request.getSession().getServletContext().getRealPath("/upload/");
//判断该路径是否存在
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}

String filename = upload.getOriginalFilename();
//把文件名称设置成唯一值
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid + "_" + filename;
//上传文件
upload.transferTo(new File(path, filename));

return "success";
}

xml中需要配置文件解析器

1
2
3
4
5
<!--配置文件解析器-->
<!--id必须为multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"></property>
</bean>

注意:在Spring Boot中已经自动配置文件解析器,如果需要自动配置,可以在配置类中自行配置自定义的文件解析器。