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

来源:互联网 发布:js使用aes加密 编辑:程序博客网 时间:2024/05/22 05:27

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;@Repositorypublic 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;    }}
原创粉丝点击