1.类型转换器
需求:将String类型字符串转换为Employee对象,如:a-b-1-1转换为Employee对象
其中Employee类中的字段:
private Integer id;
private String lastName;
private String email;
private int gender;
private Department department;
Department类中的字段:
private Integer id;
private String departmentName;
步骤如下:
1).定义类型转换器EmployeeConverter
@Component
public class EmployeeConverter implements Converter<String, Employee>{
@Override
public Employee convert(String source) {
if (source != null) {
String[] vals = source.split("-");
if (vals != null && vals.length ==4) {
try {
String lastName = vals[0];
String email = vals[1];
int gender = Integer.parseInt(vals[2]);
int departmentId = Integer.parseInt(vals[3]);
Department department = new Department();
department.setId(departmentId);
Employee employee = new Employee(null, lastName, email, gender, department);
return employee;
} catch (NumberFormatException e) {
return null;
}
}
}
return null;
}
}
2).spring配置文件springmvc.xml中加入如下配置
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"></mvc:annotation-driven>
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="employeeConverter"/>
</set>
</property>
</bean>
3).请求页面
<form action="testConversionServiceConverer" method="post">
<input type="text" name="employee" value="a-b-1-1"/>
<input type="submit" value="submit">
</form>
4).目标方法
@RequestMapping("/testConversionServiceConverer")
public String testConverter(@RequestParam("employee") Employee employee) {
System.out.println(employee);
return "success";
}
2.mvc:annotation-driven
<mvc:annotation-driven />会自动注册
RequestMappingHandlerMapping,
RequestMappingHandlerAdapter和
ExceptionHandlerExceptionResolver三个bean
还提供以下支持:
-支持使用ConversionService实例对表单参数进行类型转换
-支持使用@numberFormat annotation,
@DateTimeFormat注解完成数据类型的格式化
-支持使用@Valid注解对JavaBean实例进行JSR 303 验证
-支持使用@RequestBody和ResponseBody注解
3.@InitBinder
由@InitBinder 标识的方法,可以对WebDataBinder对象进行初始化。WebDataBinder是DataBinder的子类,用于完成有表单字段到JavaBean
属性的绑定
@InitBinder方法不能有返回值,她必须声明为void。
@InitBinder方法的参数通常是WebDataBinder
//不对哪个字段赋值
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("lastName");
}
4.数据格式化
<!--
org.springframework.context.support.ConversionServiceFactoryBean这个类用于配置类型转换
org.springframework.format.support.FormattingConversionServiceFactoryBean这个类既可以格式化数据又可以类型转换
-->
<bean id="conversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="employeeConverter"/>
</set>
</property>
</bean>
在属性上添加注解
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
@NumberFormat(pattern="#,###,###.#")
private Float salary;
5.返回json
由于乱码问题,加上了produces="text/plain;charset=UTF-8",网上也有配置AnnotationMethodHandlerAdapter的(放在mvc:annotation-driven之前)
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
<property name="messageConverters">
<list>
<bean class = "org.springframework.http.converter.StringHttpMessageConverter">
<property name = "supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
但是,不管用!
@ResponseBody
@RequestMapping(value="/getJson", produces="text/plain;charset=UTF-8")
public String getJson(HttpServletResponse respone) {
Employee e = new Employee(101, "张三", "123@qq.com", 1, new Department(1, "开发部"));
String s = JSON.toJSONString(e);
return s;
}
6.文件上传
1).添加文件上传所需的jar包
commons-fileupload-1.3.3.jar
commons-io-2.6.jar
2).springmvc.xml中加入如下配置:
<!-- 配置MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>
3).请求页面
<form action="testFileUpload" method="post" enctype="multipart/form-data">
File:<input type="file" name="file"/>
File2:<input type="file" name="file2"/>
Desc:<input type="text" name="desc"/>
<input type="submit" value="Submit"/>
</form>
4).目标方法
@RequestMapping("/testFileUpload")
public String testFileUpload(@RequestParam("desc") String desc,
@RequestParam("file") MultipartFile file,
@RequestParam("file2") MultipartFile file2) throws IOException {
System.out.println(desc);
System.out.println(file.getOriginalFilename()+" "+file2.getOriginalFilename());
return "success";
}
7.拦截器
1).创建拦截器,
/**
* 拦截器方法执行顺序:pre-目标方法-post-渲染视图-after
*preHandle>handle>postHandle>render>afterCompletion
*/
public class FirstInterceptor implements HandlerInterceptor {
/**
* 该方法在目标方法之前被调用。
* 若返回值是true,则继续调用后续的兰机器和方法
* 若返回false,则不会再调用后续的拦截器和方法
*
* 可以考虑做权限
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println(getClass().getName()+":preHandle");
return true;
}
/**
* 调用目标方法之后,但再渲染视图之前
* 可以对请求域中的是属性或视图做出修改
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println(getClass().getName()+":postHandle");
}
/**
* 渲染视图之后被调用,释放资源
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println(getClass().getName()+":afterCompletion");
}
}
2).配置拦截器
<mvc:interceptors>
<!-- 配置自定义拦截器 -->
<bean class="com.springmvc.interceptor.FirstInterceptor"></bean>
<bean class="com.springmvc.interceptor.SecondInterceptor"></bean>
<!-- 拦截器(不)作用的路径 -->
<mvc:interceptor>
<mvc:mapping path="/emp"/>
<bean class="com.springmvc.interceptor.EmpInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
3).多个拦截器
当多个(两个)拦截器配置时,方法执行顺序为
FirstInterceptor:preHandle
SecondInterceptor:preHandle
执行目标方法。。。
SecondInterceptor:postHandle
FirstInterceptor:postHandle
SecondInterceptor:afterCompletion
FirstInterceptor:afterCompletion
有两个拦截器,第一个拦截器返回false时,
FirstInterceptor:preHandle
有两个拦截器,第一个拦截器返回true,第二个拦截器返回false时。
FirstInterceptor:preHandle
SecondInterceptor:preHandle
FirstInterceptor:afterCompletion
总结:如果一个拦截器的preHandle方法返回false,那么这个拦截器的后续方法,以及整个拦截器组的postHandle方法,以及目标方法将不执行
8.异常处理@ExceptionHandler
/**
* 1.在@ExceptionHandler方法参数中可以加入Exception类型的参数,改参数即对应发生的异常对象
* 2.@ExceptionHandler方法的参数不能传入Map,若希望把异常信息传到页面上,需要使用ModelAndView作为返回值
* 3.@ExceptionHandler方法标记的异常有优先级的问题,
* 4.@ControllerAdvice:如果在当前handler中找不到@ExceptionHandler标记的方法来处理当前方法出现的异常,
* 则将去 @ControllerAdvice标记的类中查找@ExceptionHandler标记的方法来处理异常
*/
@ExceptionHandler
public ModelAndView handleArithmeticException(Exception ex) {
System.out.println(ex);
ModelAndView mv = new ModelAndView("error");
return mv;
}
@RequestMapping("/testExceptionHandlerExceptionResolver")
public String testExceptionHandlerExceptionResolver(@RequestParam("i") int i) {
System.out.println("" + (10 / i));
return "success";
}
网友评论