itjavashuai 2018-01-04
一、JSR303数据校验
b/s系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的,本节主要学习springmvc实现控制层添加校验。
Spring3支持JSR-303验证框架,JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator(与Hibernate ORM 没有关系),JSR 303 用于对Java Bean 中的字段的值进行验证。
步骤如下:
加入jar包*
2.配置validator
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
classpath:CustomValidationMessages
3.将validator加入处理器适配器
注解方式:
配置方式(自学):
class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
4.添加验证规则
public class User{
private Integer id;
@Size(min=1,max=30,message="{mess1}")
private String username;
@NotEmpty(message="{mess2}")
private String password;
}
5.错误消息文件
CustomValidationMessages.properites
mess1=用户名称在1到30个字符之间
mess2=密码不能为空
6.捕获错误
@RequestMapping("/editUserSubmit")
public String editUserSubmit(@Validated @ModelAttribute("user") User user,BindingResult result,
Model model)throws Exception {
//验证是否存在校验错误
if (result.hasErrors()) {
List errors = result.getAllErrors();
for(ObjectError objectError:errors){
System.out.println(objectError.getCode());
System.out.println(objectError.getDefaultMessage());
}
//跳到相应页面
return "user/editUser";
}
}
注意:添加@Validated表示在对user参数绑定时进行校验,校验信息写入BindingResult中,在要校验的pojo后边添加BingdingResult, 一个BindingResult对应一个pojo,且BingdingResult放在pojo的后边。
7.页面显示错误信息
${error.defaultMessage }
说明:
表示如果user参数绑定校验错误下边显示错误信息。
上边的方法也可以改为:
在controller方法中将error通过model放在request域,在页面上显示错误信息:
controller方法:
if(bindingResult.hasErrors()){
model.addAttribute("errors", bindingResult);
}
页面:
${error.defaultMessage }
二.JSR303数据校验分组校验
如果两处校验使用同一个User类则可以设定校验分组,通过分组校验可以对每处的校验个性化。
步骤如下:
1.定义分组:
分组就是一个标识,这里定义一个接口:
public interface ValidGroup1 {
}
public interface ValidGroup2 {
}
2.指定分组校验
public class User {
private Integer id;
//这里指定分组ValidGroup1,此@Size校验只适用ValidGroup1校验
@Size(min=1,max=30,message="{mess1}",groups={ValidGroup1.class})
private String username;
@NotEmpty(message="{mess2}",groups={ValidGroup2.class})
private String password;
}
3.使用分组
// 修改提交
@RequestMapping("/userAdd")
public String userAdd(@Validated(value={ValidGroup1.class}) @ModelAttribute("user") User user,BindingResult result,Model model) throws Exception {
}
在@Validated中添加value={ValidGroup1.class}表示商品修改使用了ValidGroup1分组校验规则,也可以指定多个分组中间用逗号分隔,
@Validated(value={ValidGroup1.class,ValidGroup2.class })
附:校验注解
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
三.数据回显
概念:
表单提交失败需要再回到表单页面重新填写,原来提交的数据需要重新在页面上显示。
简单类型回显
对于简单数据类型,如:Integer、String、Float等使用Model将传入的参数再放到request域实现显示。
如下:
@RequestMapping(value="/editUser",method={RequestMethod.GET})
public String editItems(Model model,Integer id)throws Exception{
//传入的id重新放到request域
model.addAttribute("id", id);
}
POJO类型回显
springmvc默认支持pojo数据回显,springmvc自动将形参中的pojo重新放回request域中,request的key为pojo的类名(首字母小写),如下:
controller方法:
@RequestMapping("/editUser")
public String editItemSubmit(Integer id,User user)throws Exception{
}
springmvc自动将user放回request,相当于调用下边的代码:
model.addAttribute("user", user);
如果key不是pojo的类名(首字母小写),可以使用@ModelAttribute完成数据回显。
@ModelAttribute作用如下:
绑定请求参数到pojo并且暴露为模型数据传到视图页面 ,此方法可实现数据回显效果。
// 修改提交
@RequestMapping("/editUser")
public String editItemSubmit(Model model,@ModelAttribute("user") User user)
}
如果不用@ModelAttribute也可以使用model.addAttribute("user", user)完成数据回显。
将方法返回值暴露为模型数据传到视图页面
@ModelAttribute("itemtypes")
public Map getItemTypes(){
Map map= new HashMap();
map.put("101", "数码");
map.put("102", "母婴");
return map;
}
页面取值
${obj.value }
四.异常处理
概念:
springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。
异常处理思路
系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。
系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:
3.自定义异常处理
为了区别不同的异常通常根据异常类型自定义异常类,这里我们创建一个自定义系统异常,如果controller、service、dao抛出此类异常说明是系统预期处理的异常信息。
public class CustomException extends Exception {
/** serialVersionUID*/
private static final long serialVersionUID = -5212079010855161498L;
public CustomException(String message){
super(message);
this.message = message;
}
//异常信息
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
常处理器
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
ex.printStackTrace();
CustomException customException = null;
//如果抛出的是系统自定义异常则直接转换
if(ex instanceof CustomException){
customException = (CustomException)ex;
}else{
//如果抛出的不是系统自定义异常则重新构造一个未知错误异常。
customException = new CustomException("未知错误,请与系统管理 员联系!");
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", customException.getMessage());
modelAndView.setViewName("error");
return modelAndView;
}
}
5.错误页面
您的操作出现错误如下:
${message }
异常处理器配置
在springmvc.xml中添加:
测试
修改用户信息,id输入错误提示用户信息不存在。
修改controller方法“editUser”,调用service查询User信息,如果User信息为空则抛出异常:
// 调用service查询用户信息
User user = userService.findById(id);
if(user== null){
throw new CustomException("用户信息不存在!");
}
五.文件上传
步骤如下:
配置解析器
5242880
添加jar包
CommonsMultipartResolver解析器依赖commons-fileupload和commons-io,加入如下jar包:
图片上传操作
@RequestMapping("/upload")
public String editItemSubmit(User user, MultipartFile pictureFile)throws Exception{
//原始文件名称
String pictureFile_name = pictureFile.getOriginalFilename();
//新文件名称
String newFileName = UUID.randomUUID().toString()+pictureFile_name.substring(pictureFile_name.lastIndexOf("."));
//上传图片
File uploadPic = new java.io.File("F:/develop/upload/temp/"+newFileName);
if(!uploadPic.exists()){
uploadPic.mkdirs();
}
//向磁盘写文件
pictureFile.transferTo(uploadPic);
.....
4.页面添加
form添加enctype="multipart/form-data":
图片:
六.JSON处理
@RequestBody
作用:
@RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容转 换为json、xml等格式的数据并绑定到controller方法的参数上。
本例子应用:
@RequestBody注解实现接收http请求的json数据,将json字符串(不是json对像)转换为java对象
@ResponseBody
作用:
该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据如:json,xml等,通过Response响应给客户端
本例子应用:
@ResponseBody注解实现将controller方法返回对象转换为json响应给客户端
请求JSON,响应JSON
Springmvc默认用MappingJacksonHttpMessageConverter对json数据进行转换,需要加入jackson的包,如下:
配置json转换器
在注解适配器中加入messageConverters
注意:如果使用 则不用定义上边的内容。
5.controller编写
// 用户注册提交json信息,响应json信息
@RequestMapping("/requestJson")
public @ResponseBody User userRegister(@RequestBody User user) throws Exception {
System.out.println(user);
//业务略
return user;
}
页面编写
//请求json响应json
function request_json(){
$.ajax({
type:"post",
url:"${pageContext.request.contextPath }/requestJson.action",
contentType:"application/json;charset=utf-8",
data:'{"name":"admin","password":"123456"}',
success:function(data){
alert(data);
}
});
}
测试结果(略)
请求key/value,响应json实现
表单默认请求application/x-www-form-urlencoded格式的数据即key/value,通常有post和get两种方法,响应json数据是为了方便客户端处理,实现如下:
控制器编写:
// 提交普通form表单数据,响应json
@RequestMapping("/responseJson")
public @ResponseBody User responseJson(User user) throws Exception {
System.out.println(user);
return user;
}
页面编写:
function formsubmit(){
var user = " name=admin&password=123456";
$.ajax(
{
type:'post',//这里改为get也可以正常执行
url:'${pageContext.request.contextPath}/requestJson.action',
//ContentType没指定将默认为:application/x-www-form-urlencoded
data:user,
success:function(data){
alert(data.username);
}
}
)
}
从上边的js代码看出,已去掉ContentType的定义,ContentType默认为:application/x-www-form-urlencoded格式。
实际开发中常用8的方法,请求key/value数据,响应json结果,方便客户端对结果进行解析。
七.自定义拦截器
定义
Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。
拦截器定义
实现HandlerInterceptor接口,如下:
Public class HandlerInterceptor1 implements HandlerInterceptor{
/**
* controller执行前调用此方法
* 返回true表示继续执行,返回false中止执行
* 这里可以加入登录校验、权限拦截等
*/
@Override
Public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
Return false;
}
/**
* controller执行后但未返回视图前调用此方法
* 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
*/
@Override
Public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
/**
* controller执行后且视图返回后调用此方法
* 这里可得到执行controller时的异常信息
* 这里可记录操作日志,资源清理等
*/
@Override
Public void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler, Exception ex) throws Exception {
// TODO Auto-generated method stub
}
}
配置拦截器
针对某种mapping配置拦截器
针对所有mapping配置全局拦截器
拦截器的应用
用户身份验证:
Public class LoginInterceptor implements HandlerInterceptor{
@Override
Public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
//如果是登录页面则放行
if(request.getRequestURI().indexOf("login.action")>=0){
return true;
}
HttpSession session = request.getSession();
//如果用户已登录也放行
if(session.getAttribute("user")!=null){
return true;
}
//用户没有登录跳转到登录页面
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
return false;
}
用户登录controller
//登陆提交
//username:用户账号,password:密码
@RequestMapping("/login")
public String loginsubmit(HttpSession session,String username,String password)throws Exception{
//向session记录用户身份信息
session.setAttribute("activeUser", username);
return "redirect:xxx.action";
}
//退出
@RequestMapping("/logout")
public String logout(HttpSession session)throws Exception{
//session过期
session.invalidate();
return "redirect:yyy.action";
}
八.SSM整合
整合目标:控制层采用springmvc、持久层使用mybatis实现,服务层spring
创建WEB工程
添加SSM需要的jar包
在src下,引入配置文件
applicationContext.xml
springmvc.xml
mybatis-config.xml
db.properties文件
其中 applicationContext.xml的配置如下:
xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance"](http://www.w3.org/2001/XMLSchema-instance%22);;; xmlns:mvc="[http://www.springframework.org/schema/mvc"](http://www.springframework.org/schema/mvc%22);;;
xmlns:context="[http://www.springframework.org/schema/context"](http://www.springframework.org/schema/context%22);;;
xmlns:aop="[http://www.springframework.org/schema/aop"](http://www.springframework.org/schema/aop%22);;; xmlns:tx="[http://www.springframework.org/schema/tx"](http://www.springframework.org/schema/tx%22);;;
xsi:schemaLocation="
">
pointcut="execution(* cn.itcast.springmvc.service.impl.*.*(..))"/>
其中 mybatis-config.xml配置如下:
PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Config 3.0//EN"
"[http://mybatis.org/dtd/mybatis-3-config.dtd";>](http://mybatis.org/dtd/mybatis-3-config.dtd%22;%3E);;
其中 springmvc.xml配置如下:
xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance"](http://www.w3.org/2001/XMLSchema-instance%22);; xmlns:mvc="[http://www.springframework.org/schema/mvc"](http://www.springframework.org/schema/mvc%22);;
xmlns:context="[http://www.springframework.org/schema/context"](http://www.springframework.org/schema/context%22);;
xmlns:aop="[http://www.springframework.org/schema/aop"](http://www.springframework.org/schema/aop%22);; xmlns:tx="[http://www.springframework.org/schema/tx"](http://www.springframework.org/schema/tx%22);;
xsi:schemaLocation="
">
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
value="org.springframework.web.servlet.view.JstlView" />
其中web.xml配置如下:
xmlns="[http://java.sun.com/xml/ns/javaee"](http://java.sun.com/xml/ns/javaee%22);; xmlns:web="[http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"](http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd%22);;
xsi:schemaLocation="[http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"](http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd%22);;
id="WebApp_ID" version="2.5">
springmvc
contextConfigLocation
classpath:applicationContext.xml,classpath:springmvc-*.xml
org.springframework.web.context.ContextLoaderListener
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring/springmvc.xml
1
springmvc
*.action
4.整合完毕,测试
以上就是关于Java培训之springMVC高级应用的详细介绍,最后如果想要了解更多关于Java相关技术问题的小伙伴可以关注扣丁学堂,扣丁学堂不仅有专业的老师和与时俱进的课程体系,还有大量的Java视频教程供学员观看学习,对Java还有什么疑问的小伙伴可以联系扣丁学堂的咨询老师询问哦。Java技术交流群:670348138。
@RequestBody注解实现接收http请求的json数据,将json数据转换为java对象进行绑定。加上@ResponseBody注解,就不会走视图解析器,不会返回页面,目前返回的json数据。