(2) 注册异常处理器
1
2 <bean class=“com.test.resolvers.MyHandlerExceptionResolver”/>
异常处理注解
使用注解@ExceptionHandler可以将一个方法指定为异常处理方法, 该注解有一个可选属性value,
可用于指定该注解方法所需要处理的异常类.
定义一个顶层Controller, 处理所有异常, 其他Controller继承该类即可实现异常集中管理.
1 @Controller
2 public class BaseController {
3
4 // 处理NameException异常
5 @ExceptionHandler(NameException.class)
6 public ModelAndView handlerNameException(Exception ex) {
7 ModelAndView mv = new ModelAndView();
8 mv.addObject(“ex”, ex);
9 // 执行一些操作
10 mv.setViewName(“/errors/nameError.jsp”);
11 return mv;
12 }
13
14 }
类型转换器
可以将用户web端提交的数据, 在后台转为需要的数据类型.
自定义类型转换器
若要定义类型转换器, 则需要实现Converter接口, 该Convert接口有两个泛型:
第一个为待转换类型, 第二个为目标类型, 该接口方法convert用于实现转换.
1 public class MyDateConverter implements Converter<String, Date> {
2
3 public Date convert(String source) {
4 SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd”);
5 try {
6 return sdf.parse(source);
7 } catch (ParseException e) {
8 e.printStackTrace();
9 }
10 return null;
11 }
12
13 }
类型转换器定义完毕后, 需要在配置文件中进行注册, 然后注册一个转换服务Bean, 将转换器注入给该Bean,
最后由处理器适配器来使用该转换服务器Bean. 该Bean由ConversionServiceFactory工厂创建, 工厂有Set集合属性,
可以提供多种转换功能的Bean来处理多种数据类型转换.
1
2 <bean id=“myDateConverter” class=“com.test.converters.MyDateConverter”/>
3
4
5 <bean id=“conversionService” class=“org.springframework.context.support.ConversionServiceFactoryBean”>
6 <property name=“converters” ref=“myDateConverter”/>
7 </bean>
8
9
10 <mvc:annotation-driven conversion-service=“conversionService”/>
数据验证
主要是校验客户端发来的数据是否合法, 例如不能为空, 或者长度不符合等等. Spring MVC没有校验功能,
但是支持JSR303-Bean Validation, 可以用实现该规范的Hibernate Validator校验框架.
(1) 配置验证器
1
2 <bean id=“myValidator” class=“org.springframework.validation.beanvalidation.LocalValidatorFactoryBean”>
3 <property name=“providerClass” value=“org.hibernate.validator.HibernateValidator”/>
4 </bean>
(2) 在Bean上添加验证注解
1 public class Student {
2
3 @NotNull(message=“姓名不能为空”)
4 @Size(min=3, max=6, message=“姓名长度应在{min}-{max}个字符”)
5 private String name;
6
7 @Min(value=0, message=“成绩不能小于{value}”)
8 @Max(value=100, message=“成绩不能大于{value}”)
9 private double score;
10
11
12 @NotNull(message=“电话不能为空”)
13 @Pattern(regexp=“^1[34578]\\d{9}$”, message=“手机号格式不正确”)
14 private String mobile;
15
16 …
17 }
(3) 修改Controller
在需要校验的参数前面加上@Validated注解, 同时追加一个BindingResult参数, 用于获取验证异常信息.
1 @Controller
2 @RequestMapping(“/test”)
3 public class MyController {
4
5 @RequestMapping(“/register.do”)
6 public ModelAndView doRegister(@Validated Student student, BindingResult br) {
7
8 ModelAndView mv = new ModelAndView();
9 mv.addObject(“student”, student);
10 mv.setViewName(“/WEB-INF/jsp/welcome.jsp”);
11
12 int errorCount = br.getErrorCount();
13 if(errorCount > 0) {
14 FieldError nameError = br.getFieldError(“name”);
15
16 if (nameError != null) {
17 String nameErrorMSG = nameError.getDefaultMessage();
18 mv.addObject(“nameErrorMSG”, nameErrorMSG);
19 }
20 mv.setViewName(“/index.jsp”);
21 }
22
23 return mv;
24 }
25 }
文件上传与下载
上传
Spring MVC中文件上传需要添加Apache Commons FileUpload相关的jar包,
基于该jar, Spring中提供了MultipartResolver实现类: CommonsMultipartResolver.
注册该Bean到配置文件中
<bean id=“multipartResolver”
class=“org.springframework.web.multipart.commons.CommonsMultipartResolver”>
<property name=“maxUploadSize”>
<value>10485760</value>
</property>
<property name=“defaultEncoding”>
<value>UTF-8</value>
</property>
</bean>
Spring MVC会将上传的文件绑定到MultipartFile对象, 该对象提供获取内容, 文件名等方法.
通过transferTo方法可以将文件存储到磁盘.
1 //上传文件会自动绑定到MultipartFile中
2 @RequestMapping(value=“/upload”,method=RequestMethod.POST)
3 public String upload(HttpServletRequest request,
4 @RequestParam(“description”) String description,
5 @RequestParam(“file”) MultipartFile file) throws Exception {
6
7 System.out.println(description);
8 //如果文件不为空,写入上传路径
9 if(!file.isEmpty()) {
10 //上传文件路径
11 String path = request.getServletContext().getRealPath(“/images/”);
12 //上传文件名
13 String filename = file.getOriginalFilename();
14 File filepath = new File(path,filename);
15 //判断路径是否存在,如果不存在就创建一个
16 if (!filepath.getParentFile().exists()) {
17 filepath.getParentFile().mkdirs();
18 }
19 //将上传文件保存到一个目标文件当中
20 file.transferTo(new File(path + File.separator + filename));
21 return “success”;
22 } else {
23 return “error”;
24 }
25
26 }
下载
下载比较简单, 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 Spring MVC中提供了ResponseEntity类型, 可以很方便的返回HTTPHeaders, HttpStatus.
@RequestMapping(value=“/download”)
public ResponseEntity<byte[]> download(HttpServletRequest request,
@RequestParam(“filename”) String filename,
Model model)throws Exception {
//下载文件路径
String path = request.getServletContext().getRealPath(“/images/”);
File file = new File(path + File.separator + filename);
HttpHeaders headers = new HttpHeaders();
//下载显示的文件名,解决中文名称乱码问题
String downloadFielName = new String(filename.getBytes(“UTF-8”),“iso-8859-1”);
//通知浏览器以attachment(下载方式)打开图片
headers.setContentDispositionFormData(“attachment”, downloadFielName);
//application/octet-stream : 二进制流数据(最常见的文件下载)。
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
拦截器
拦截器注册与使用
Spring MVC中拦截器需要实现HandlerInterceptor接口, 该接口包含三个方法
preHandle(req, res, handler)
在处理器方法之前执行, 返回boolean, 若为true, 则紧接着执行处理器方法, 且会将
afterCompletion()方法放入一个专门的方法栈中等待执行.
postHandler(req, res, handler, ModelAndView)
在处理器方法之后执行, 处理器方法若未执行, 则该方法不执行.
该方法可以修改处理器方法返回的结果, 并可以跳转到其他页面.
M);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
拦截器
拦截器注册与使用
Spring MVC中拦截器需要实现HandlerInterceptor接口, 该接口包含三个方法
preHandle(req, res, handler)
在处理器方法之前执行, 返回boolean, 若为true, 则紧接着执行处理器方法, 且会将
afterCompletion()方法放入一个专门的方法栈中等待执行.
postHandler(req, res, handler, ModelAndView)
在处理器方法之后执行, 处理器方法若未执行, 则该方法不执行.
该方法可以修改处理器方法返回的结果, 并可以跳转到其他页面.