您的位置:首页 > 编程语言 > Java开发

springmvc笔记-6-数据转换,格式化,校验

2017-08-02 14:44 681 查看
1.springmvc的数据绑定流程

2.ConversionService转换数据

3.@IntitBinder转换数据

4.WebBindingInitializer转换数据

5.Formatter和FormatterFegister格式化数据

6.AnnotationFormatterFactory格式化数据

7.Spring的Validation校验框架

8.JSR303校验





org.springframework.core.convert.ConversionService是spring类型转换体系的核心接口

org.springframework.core.convert.converter是spring支持的转换器

案例一:

登陆界面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="login" method="post">
<table>
<tr>
<td><label>登录名: </label></td>
<td><input type="text" id="name" name="name" ></td>
</tr>
<tr>
<td><label>密码: </label></td>
<td><input type="text" id="password" name=""password"" ></td>
</tr>
<tr>
<td><label>生日: </label></td>
<td><input type="text" id="birthday" name="birthday" ></td>
</tr>
<tr>
<td><input id="submit" type="submit" value="登录"></td>
</tr>
</table>
</form>
</body>
</html>


实体对象

package com.entity;

import java.io.Serializable;
import java.util.Date;

public class Man implements Serializable{
private String name;
private String password;
private Date birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}


对应的控制器

package com.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.entity.Man;

@Controller
@RequestMapping("convert")
public class ConversionController {
// http://localhost:8080/springmvcNote1/convert/loginForm @RequestMapping("loginForm")
public String test01(){
return "conversion/login";
}

@RequestMapping("login")
public String test02(Model model,@ModelAttribute Man man){
model.addAttribute(man);
return "conversion/success";
}

}


对应的转换器类

package com.core;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;

public class StringToDateConvert implements Converter<String, Date>{
//日期类型模板,可以在xml中配置
private String datePattern;

public void setDatePattern(String datePattern) {
this.datePattern = datePattern;
}

//Converter<S,T>接口的类型转换方法
@Override
public Date convert(String date) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern);
//将日期字符串转换为date
return dateFormat.parse(date);
} catch (Exception e) {
e.printStackTrace();
System.out.println("日期转换为Date失败");
return null;
}
}

}


xml配置

<!-- 装配自定义的类型转换器 -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.core.StringToDateConvert"
p:datePattern="yyyy-MM-dd">
</bean>
</list>
</property>
</bean>


spring中使用了
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>


可以简化springmvc相关配置,自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个bean,这是springmvc为@Controller分发请求所必须的,这个标签还会注册一个默认的ConversionService,即FormattingConversionServiceFactoryBean,以满足大多数类型转换的需求,现在需要注册一个自定义的StringToDateConverter转换类,所以需要覆盖ConversionService在mvc:annotation-driven的实现类,而这一步需要通过<property name=”converters”>这个属性来完成

@IntitBinder:自定义编辑器转换数据

案例二:

与案例一不同的是:

StringToDateConvert——->DateEditor

xml配置换成了在Controller中的方法注解进行注册

package com.core;

import java.beans.PropertyEditorSupport;
import java.text.SimpleDateFormat;
import java.util.Date;

public class InitBinderStringToDate extends PropertyEditorSupport{

@Override
public void setAsText(String text) throws IllegalArgumentException {
//      super.setAsText(text);
System.out.println(text+"===========================================");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = dateFormat.parse(text);
System.out.println(date+"*********************************");
setValue(date);
} catch (Exception e) {
e.printStackTrace();
}
}
}


@InitBinder注解:会在控制器初始化时注册属性编辑器

//在控制器中初始化注册属性编辑器
@InitBinder
public void initBinder(WebDataBinder binder){
//注册自定义编辑器
binder.registerCustomEditor(Date.class, new InitBinderStringToDate());
}


数据格式化:

位于org.springframework.format包下,最终的便是Formatter<T>,之前Converter完成Object与Object之间的转换,Formatter则完成任意Object与String之间的转换,Formatter只能将String类型装换成java的另一种类型对象

案例三:

StringToDateConvert——->DateFormatter

xml配置跟换了

package com.core;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import org.springframework.format.Formatter;

public class DateFormatter implements Formatter<Date>{

private String datePattern;
private SimpleDateFormat sdf;
public  DateFormatter() {
this.datePattern = "yyyy-MM-dd";
this.sdf = new SimpleDateFormat(datePattern);
}

//显示Formatter<T>的T类型对象
@Override
public String print(Date date, Locale locale) {
return sdf.format(date);
}

//解析一个字符串,返回一个Formatter<T>的T类型对象
@Override
public Date parse(String source, Locale locale) throws ParseException {
try {
return sdf.parse(source);
} catch (Exception e) {
e.printStackTrace();
throw new IllegalArgumentException();
}

}

}


xml配置:

<!-- 装配自定义格式化 -->
<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 格式化 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<list>
<bean class="com.core.DateFormatter"/>
</list>
</property>
</bean>


未完待续…..

数据校验:就是和errors标签一样,在尝试的过程中,校验的时候,因为资源文件和校验数据的时候用的是一个实体,竟然和资源文件

fkit_en_US.properties

fkit_zh_CN2.properties其冲突了!!!!,

实体

package com.entity;

import java.io.Serializable;

public class User implements Serializable{
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

}


校验类:

package com.core;

import org.springframework.stereotype.Repository;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import com.entity.User;

@Repository
public class MyValidation implements Validator{

// 该校验器能够对clazz类型的对象进行校验。
@Override
public boolean supports(Class<?> clazz) {
// User指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。
return User.class.isAssignableFrom(clazz);
}

// 对目标类target进行校验,并将校验错误记录在errors当中
@Override
public void validate(Object target, Errors errors) {
/**
使用ValidationUtils中的一个静态方法rejectIfEmpty()来对loginname属性进行校验,
假若'loginname'属性是 null 或者空字符串的话,就拒绝验证通过 。
*/
ValidationUtils.rejectIfEmpty(errors, "name", null, "登录名不能为空");
ValidationUtils.rejectIfEmpty(errors, "password", null, "密码不能为空");
User user = (User)target;
if(user.getName().length() > 10){
// 使用Errors的rejectValue方法验证
errors.rejectValue("name", null, "用户名不能超过10个字符");
}
if(user.getPassword() != null
&& !user.getPassword().equals("")
&& user.getPassword().length() < 6){
errors.rejectValue("password", null, "密码不能小于6位");
}
}

}


控制器类:

package com.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.core.MyValidation;
import com.entity.User;

@Controller
@RequestMapping("validation")
public class VadationController {
@Autowired
private MyValidation mv;

@RequestMapping("loginForm")
public String test01(Model model){
User user = new User();
model.addAttribute("user",user);
return "validation/loginValidation";
}

@RequestMapping(value="loginOk",method=RequestMethod.POST)
public String login(
@ModelAttribute User user,
Model model,
Errors errors) {
model.addAttribute("user", user);
// 调用mv的验证方法
mv.validate(user, errors);
// 如果验证不通过跳转到login视图
if(errors.hasErrors()){
return "validation/loginValidation";
}
return "validation/loginValidationOK";
}
}


登陆页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form:form method="post" modelAttribute="user" action="loginOk">
<tr>
<td>姓名</td>
<td><form:input path="name"/></td>
<td><form:errors path="name"></form:errors></td>
</tr>
<tr><br/>
<td>密码</td>
<td><form:input path="password"/></td>
<td><form:errors path="password"></form:errors></td>
</tr><br/>
<tr>
<td><input type="submit" value="提交"/></td>
</tr>
</form:form>
</body>
</html>


JSR 303校验:

可以通过链接https://jcp.org/en/jsr/detail?id=303,了解JSR 303详细内容







1、需要的jar包

classmate-1.0.0.jar

hibernate-validator-5.1.3.Final.jar

hibernate-validator-annotation-processor-5.1.3.Final.jar

hibernate-validator-cdi-5.1.3.Final.jar

jboss-logging-3.1.3.GA.jar

validation-api-1.1.0.Final.jar

案例:

访问http://localhost:8080/springmvcNote1/jsr303/loginForm

进入:loginForm方法,转到login.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix= "form" uri= "http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试JSR 303</title>
</head>
<body>
<h3>注册页面</h3>
<form:form modelAttribute="jsrUser" method="post" action="login" >
<table>
<tr>
<td>登录名:</td>
<td><form:input path="loginname"/></td>
<td><form:errors path="loginname" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>密码:</td>
<td><form:input path="password"/></td>
<td><form:errors path="password" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>用户名:</td>
<td><form:input path="username"/></td>
<td><form:errors path="username" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>年龄:</td>
<td><form:input path="age"/></td>
<td><form:errors path="age" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>邮箱:</td>
<td><form:input path="email"/></td>
<td><form:errors path="email" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>生日:</td>
<td><form:input path="birthDate"/></td>
<td><form:errors path="birthDate" cssStyle= "color:red"/></td>
</tr>
<tr>
<td>电话:</td>
<td><form:input path="phone"/></td>
<td><form:errors path="phone" cssStyle= "color:red"/></td>
</tr>
<tr>
<td><input type="submit" value="提交"/></td>
</tr>
</table>
</form:form>
</body>
</html>


点击提交,进入login方法

// 数据校验使用@Valid,后面跟着Errors对象保存校验信息
@RequestMapping(value="/login",method=RequestMethod.POST)
public String login(
@Valid @ModelAttribute  JsrUser jsrUser,
Errors  errors,
Model model) {
if(errors.hasErrors()){
return "jsr/login";
}
model.addAttribute("jsrUser", jsrUser);
return "jsr/success";
}


判断是否有错误

登陆成功界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试JSR 303</title>
</head>
<body>
<h3>测试JSR 303</h3>
登录名:${requestScope.jsrUser.loginname }<br>
密码:${requestScope.jsrUser.password }<br>
用户名:${requestScope.jsrUser.username }<br>
年龄:${requestScope.jsrUser.age }<br>
邮箱:${requestScope.jsrUser.email }<br>
生日:${requestScope.jsrUser.birthDate}<br>
电话:${requestScope.jsrUser.phone }<br>
</body>
</html>


对应的实体代码

package com.entity;

import java.io.Serializable;
import java.util.Date;

import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.Range;
import org.springframework.format.annotation.DateTimeFormat;

public class JsrUser implements Serializable{
@NotBlank(message="登陆名不能为空")
private String loginname;
@NotBlank(message="密码不能为空")
@Length(min=6,max=8,message="密码长度必须在6到8位之间")
private String password;
@NotBlank(message="用户名不能为空")
private String username;
@Range(min=15,max=60,message="年龄必须在15岁到60岁之间")
private int age;
@Email(message="必须是合法的邮箱地址")
private String email;
@DateTimeFormat(pattern="yyyy-MM-dd")
@Past(message="生日必须是一个过去的日期")
private Date birthDate;
@Pattern(regexp="[1][3,8][3,6,9][0-9]{8}",message="无效电话号码")
private String phone;

public String getLoginname() {
return loginname;
}
public void setLoginname(String loginname) {
this.loginname = loginname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐