SpringMVC入门终结篇
Posted 大忽悠爱忽悠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC入门终结篇相关的知识,希望对你有一定的参考价值。
SpringMVC入门第四部分
- 自定义类型对象和请求参数的数据绑定流程
- 自定义类型转换器
- annotation-driven介绍
- mvc:annotation-driven和mvc:default对动态和静态资源的影响
- 数据格式化之日期格式化
- 数据校验:只做前端校验是不安全的,在重要的数据一定要加上后端校验
- 普通表单将请求信息放在请求域中去页面获取
- 自定义国际化错误消息的显示,Hibernate Validator已经实现了默认的国际化错误消息显示格式
- 步骤1:编写国际化文件,起名要规范,放在conf资源文件夹下面
- 步骤2:编写国际化配置资源文件
- 步骤3:让SpringMVC管理国际化资源文件
- 可以通过注解上的message属性来指定错误消息,如果配置了国际化,先走国际化中配置的
- SpringMVC支持ajax
- 导入jquery的依赖
- 导入JackSon的依赖
- @JsonIgnore 输出数据的时候,不将当前数据发送给前端
- @JsonFormat与@DateTimeFormat注解的配合使用
- jQuery的each()函数补充知识点
- @ResponseBody注解将服务器端将对象以json对象形式返回,前端收到数据,显示在页面上
- @ReuqestBody获取请求体----只有Post请求才有请求体
- 将请求体中的数据直接封装为自定义类型对象---@RequestBody
- 在参数位置写HttpEntity< String>,比@RequestBody更强,可以拿到请所有请求头和请求体数据
- @ResponseBody加在方法上---》本质是将返回的数据直接塞在请求体重
- 设置方法返回类型为: ResponseEntity< T >:泛型是响应体数据的类型,可以自定义响应
- SpringMVC中提供的文件下载---较为鸡肋--->ResponseEntity方式
- SpringMVC的文件上传
- 拦截器
- 国际化
- 异常处理
- @ExceptionHandler()注解使用演示
- 里面参数可以填数组,每一个参数代表当前处理异常的方法能够处理的异常类型,返回值可以跳转到定制的错误页面
- 注意事项:
- 如果有多个@ExceptionHandler都能处理一个异常,那么精确优先
- @ControllerAdvice注解----》表明当前类是集中处理异常的类,可以全局处理异常
- 全局异常处理与本类异常处理同时存在,那么本类异常处理优先,不论精确与否
- @ResponseStatus标注在自定义异常上,返回一个服务器错误页面,省去做错误页面
- @ResponseStatus注解工作的前提是,上面没有@ExceptionHandler标注的异常处理方法能处理该异常,否则走@ExceptionHandler标注的异常处理方法
- Spring默认的异常如果没人处理,就使用默认的处理方法来进行处理---->DefaultHandlerExceptionResolver
- 基于SpringMVC.xml配置的异常处理方式-----在处理异常的顺序上,优先级最低
- SpringMVC运行流程总结
- SpringMVC和Spring整合
自定义类型对象和请求参数的数据绑定流程
自定义类型转换器
自定义类型转换器,实现String----->employee对象的转换和封装
<form action="${ctp}/quickAdd">
<%--将员工所有信息都写上,自动封装对象--%>
<input type="text" name="empInfo" value="大忽悠-总裁办-@123-1"/>
<input type="submit" value="快速添加员工"/>
</form>
快速添加员工的方法:
@RequestMapping("quickAdd")
//获取请求参数empInfo
//employee=request.getParame("empInfo")---->大忽悠-总裁办-@123-1
public String quickAdd(@RequestParam("empInfo") Employee employee)
{
employeeDao.save(employee);
return "redirect:/emps";
}
ConversionService是一个接口,里面通过一个Converter转换器进行工作
步骤1:实现Converter接口,写一个自定义类型转换器
/*
* 两个泛型S,T
* S:source
* T:target
* 把s转换为t
* */
//自定义类型转换器
public class MyConverter implements Converter<String, Employee> {
//自定义转换规则
public Employee convert(String source) {
System.out.println("要转换的字符串:"+source);
Employee employee=new Employee();
if(source.contains("-"))
{
//大忽悠-总裁办-@123-1
String[] ret=source.split("-");
employee.setName(ret[0]);
employee.setDepartment(ret[1]);
employee.setEamil(ret[2]);
employee.setGender(Integer.parseInt(ret[3]));
}
return employee;
}
}
步骤2:Converter是ConversionService中的一个组件,我们需要把Converter放入到ConversionService中
步骤3:将WebDataBinder中的ConversionService设置成我们这个加了自定义类型ConversionService
步骤4:让SpringMVC使用我们的ConversionService
配置文件中实现步骤1:配置出ConversionService
converters在源码中是一个set集合
<!--告诉SpringMVC别用默认的ConversionService,
而是使用自定义的ConversionService
,里面有我们自定义的converter-->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<!--在converters转换器中添加我们自定义的类型转换器-->
<property name="converters">
<set>
<bean class="com.Converter.MyConverter"/>
</set>
</property>
</bean>
<!--使用我们自己的配置的类型转换组件-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
总结三步
annotation-driven介绍
mvc:annotation-driven和mvc:default对动态和静态资源的影响
当mvc:annotation-driven和mvc:default-servlet-handler都没配置时,只有动态资源能够访问,静态资源访问不了
常见动态资源: @RequestMapping映射的资源,.jsp
常见的静态资源: .html , .js , .img
只加mvc:default-servlet-handler,那么静态资源能访问,动态资源不能访问
只配置mvc:annotation-driven,那么只能访问动态资源,不能访问静态资源
mvc:default-servlet-handler和mvc:annotation-driven都配置后,那么静态资源和动态资源都可以访问了
数据格式化之日期格式化
ConversionServiceFactoryBean创建的ConversionService组件是没有格式化器存在的
解决方法1:不使用自定义类型的转换器
解决方法2:将自定义类型转换器注册到FormattingConversionServiceFactoryBean,这样就有格式化功能了
以后写自定义数据类型转换器的时候,就使用FormattingConversionServiceFactoryBean来注册自定义类型转换器,这样就既具有类型转换,又具有格式化功能
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!--在converters转换器中添加我们自定义的类型转换器-->
<property name="converters">
<set>
<bean class="com.Converter.MyConverter"/>
</set>
</property>
</bean>
<!--使用我们自己的配置的类型转换组件-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
后端规定提交的日期格式,不对就报错
//规定提交的日期格式
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
后端规定提交的数字格式
@NumberFormat(pattern = "#,###,###.##")//类似这样的数字格式: 1,000,000.98
private double salary;
数据校验:只做前端校验是不安全的,在重要的数据一定要加上后端校验
SpingMVC可以使用JSR303来做数据校验
Hibernate Validator是第三方框架实现了JSR303规范
实现步骤:
1.maven管理引入springmvc注解数据校验所需jar包:
<!-- maven管理引入springmvc注解数据校验所需jar包:-->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
</dependency>
2.只需要给javaBean的属性上加上校验注解
@NotEmpty
@Length(min=6,max=8)//至少6个字符,最多8个字符
private String name;
private String department;
@Email
private String eamil;
3.在SpringMVC封装对象的时候,告诉SpringMVC这个javaBean对象需要校验----@Valid注解
//只接收Post请求
@RequestMapping(value = "/emp",method = RequestMethod.POST)
//@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
public String addEmp(@Valid Employee employee)//这里会自动赋值
{
System.out.println("要添加的员工信息:"+employee);
employeeDao.save(employee);
//返回列表页面,直接重定向到查询所有员工的请求
return "redirect:/emps";
}
4.如何知道校验结果,给需要校验的javaBean后面紧跟一个BindingResult,这个BindingResult就是封装前一个bean的校验结果
//只接收Post请求
@RequestMapping(value = "/emp",method = RequestMethod.POST)
//@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
public String addEmp(@Valid Employee employee,BindingResult res)//这里会自动赋值
{
System.out.println("要添加的员工信息:"+employee);
employeeDao.save(employee);
//返回列表页面,直接重定向到查询所有员工的请求
return "redirect:/emps";
}
5.根据不同的校验结果决定怎么做
//只接收Post请求
@RequestMapping(value = "/emp",method = RequestMethod.POST)
//@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
public String addEmp(@Valid Employee employee,BindingResult res)//这里会自动赋值
{
System.out.println("要添加的员工信息:"+employee);
//获取是否有校验错误
boolean hasErrors = res.hasErrors();
if(hasErrors)
{
System.out.println("有校验错误");
return "addPage";
}
else
{
employeeDao.save(employee);
//返回列表页面,直接重定向到查询所有员工的请求
return "redirect:/emps";
}
}
6.将错误信息回显在页面上
<%pageContext.setAttribute("ctp",request.getContextPath());%>
<form:form modelAttribute="employee" action="${ctp}/emp" method="post">
<%--显示错误信息,有默认的错误信息,也可也自己写显示的错误西信息--%>
员工id:<form:input path="id"/><form:errors path="id"></form:errors><br/>
姓名:<form:input path="name"/><form:errors path="name"></form:errors><br/>
邮箱:<form:input path="eamil"/><form:errors path="eamil"></form:errors><br/>
性别:<br/>
男:<form:radiobutton path="gender" value="1"/>
女:<form:radiobutton path="gender" value="0"/>
请选择员工所在的部门:
<form:select path="department" items="${departments}"/>
<br/>
<input type="submit" value="提交">
</form:form>
普通表单将请求信息放在请求域中去页面获取
通过BindingResult的res对象的 getFieldErrors方法,可以获得当前属性值出现的全部错误,然后通过一个Model对象存储错误信息,放到隐含模型中
//只接收Post请求
@RequestMapping(value = "/emp",method = RequestMethod.POST)
//@Valid注解,告诉SpringMVC,封装这个javabean对象时,按照这个对象里面变量规定的校验规则进行校验
public String addEmp(@Valid Employee employee,BindingResult res,Model model)//这里会自动赋值
{
System.out.println("要添加的员工信息:"+employee);
//获取是否有校验错误
boolean hasErrors = res.hasErrors();
Map<String,String> errorMap=new HashMap<String, String>();
if(hasErrors)
{
List<FieldError> fieldErrors = res.getFieldErrors();
for(FieldError fieldError:fieldErrors)
{
System.out.println("错误消息提示:"+fieldError.getDefaultMessage());
System.out.println("错误的字段:"+fieldError.getField());
System.out.println(fieldError);
System.out.println("----------------------------------------");
errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
}
model.addAttribute("errorInfo",errorMap);
System.out.println("有校验错误");
return "addPage";
}
else
{
employeeDao.save以上是关于SpringMVC入门终结篇的主要内容,如果未能解决你的问题,请参考以下文章
SpringMVC入门系列篇3:@RequestMapping & @RequestHeader & @CookieValue详解与REST风格请求