<h3>注册页面</h3> <form action = "register" method = "post"> <table> <tr> <td><label>登录名</label></td> <td><input type = "text" id = "loginname" name = "loginname"></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>
registerForm.jsp是一个简单的注册页面,其传递一个登录名和一个用户的生日信息;
public clas User implements Serializable{ private String loginname; private Date birthday; public User(){ super(); } public String getLoginname(){ return loginname; } public void setLoginname(){ this.loginname = loginname; } public Date getBirthday(){ return birthday; } public void setBirthday(Date birthday){ this.birthday = birthday; }
下面是控制器
@Controller public class UserController{ private static final Log logger = LogFactory.getLog(UserController.class); @RequestMapping(value = "/{formName}") public String loginForm(@PathVariable String formName){ return formName; } @RequestMapping(value = "/register",method = RequestMethod.POST) public String register(@ModelAttribute User use, Model model){ logger.info(user); model.addAttribute("user",user); return "success"; } }
接下来,开发自定义的转换器,将传递的字符串转换成Date类型;
public class StringToDateConverter implements Converter<String,Date>{ private String datePattern; public void setDatePattern(String datePattern){ this.datePattern = datePattern; } @Override public Date convert(String date){ try{ SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern); return dateFormat.parse(date); }catch(Exception e){ e.printStackTrace(); System.out.println("日期转换失败"); return null; } } }
在springmvc-config.xml中加入自定义字符转换器;
<mvc:annotation-driven conversion-service = "conversionService"/> <bean id = "conversionService" class = "org.springframework.context.support.ConversionServiceFactoryBean"> <property name= "converters"> <list> <bean class = "org.fkit.converter.StringToDateConverter" p:datePattern = "yyyy-MM-dd"/></bean> </list> </property> </bean>
在success.jsp界面中的代码:
<body> 登录名:${requestScope.user.loginname}<br> 生日:<fmt:formaDate value = "${requestScope.user.birthday}" pattern = "yyyy年MM月dd日"/><br> </body>
接下来是@InitBinder自定义编辑转换器;这个编辑器是通过在Controller中注册自定义编辑器来实现的;先让我们来编写一个编辑转换器,然后用@InitBinder来注入到Controller中;
public class DateEditor extends PropertyEditorSupport{ @Override public void setAsText(String text) throws IllegalArgumentException{ SimpleDateFormat dateFormat = new SimpleDateFormaat("yyyy-MM-dd"); try{ Date date = dateFormat.parse(text); setValue(date); }catch(ParseException e){ e.printStackTrace(); } } }
下面是注入转换器的控制器;
@InitBinder public void initBinder(WebDataBinder binder){ binder.registerCustomEditor(Date.class,new DateEditor()); }
接下来是全局自定义编辑转换器;通过实现WebBindingInitiallizer接口来实现;
public class DateBindingInitializer implements WebBindingInitializer{ @Override public void initBinder(WebDataBinder binder,WebRequest request){ binder.registerCustomEditor(Date.class,new DateEditor()); } }
在springmvc-config.xml文件中配置全局的自定义编辑器;
<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name = "webBindingInitializer"> <bean class = "org.fkjava.binding.DateBindingInitializer"/> </property> </bean>
public class DateFormatter implements Formatter<Date>{ private String datePattern; private SimpleDateFormat dateFormat; public DateFOrmatter(String datePattern){ this.datePattern = datePattern; this.dateFormat = new SimpleDateFormat(datePattern); } @Override public String print(Date date,Locale locale){ return dateFormat.format(date); } @Override public Date parse(String source,Locale locale) throws ParseException{ try{ return dateFormat.parse(source); }catch(Exception e){ throw new IllegalArgumentException(); } } }
接下来再springmvc-config.xml中装配自定义格式化转换器;
<mvc:annotation-driven conversion-service = "coversionService"/> <bean id = "conversionService" class = "org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name = "formatters"> <list> <bean class = "org.fkit.formatter.DateFormatter" c:_0 = "yyyy-MM-dd"/> </list> </property> </bean>
接下来,如果要使用org.springframework.format.datetime包中提供的DateFormatter实现类完成字符串到对象的转换,则只需要在配置文件中配置就可以了。
<mvc:annotation-driven conversion-service = "conversionService"/> <bean id = "conversionService" class = "org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name = "formatters"> <list> <bean class = "org.springframework.format.datetime.DateFormatter" p:pattern = "yyyy-MM-dd"/> </list> <property> </bean>
使用FormatterRegistrar注册Formatter;这个是将FormatterRegistrar作为接口来实现,所以在配置是不需要再注册任何Formatter了,而是注册Registrar;
<mvc:annotation-driven conversion-service = "conversionService"/> <bean id = "dateFormatter" class = "org.fkit.formatter.DateFormatter" c:_0 = "yyyy-MM-dd"/> <bean id = "conversionService" class = "org.spirngframework.format.support.FormattingConversionServiceFactoryBean"> <set> <bean class = "org.fkit.formatter.MyFormatterRegistrar" p:dateFormatter-ref = "dateFormatter"/> </set> </property> </bean>
也可以通过注解来实现数据的格式化;
<h3>测试表单数据格式化</h3> <form action = "test" method = "post"> <table> <tr> <td><label>日期类型:</label></td> <td><input type = "text" id = "birthday" name = "brithday"></td> </tr> <tr> <td><label>整数类型:</label></td> <td><input type = "text" id = "total" name = "total"></td> </tr> <tr> <td><label>百分数类型:</label></td> <td><input type = "text" id = "discount" name = "discount"></td> </tr> <tr> <td><label>货币类型:</label></td> <td><input type = "text" id = "money" name = "money"></td> </tr> <tr> <td><input id = "submit" type = "submit" value = "提交"></td> </tr> </table> </form>
这里的注解是用在模型数据中的;
public class User implements Serializable{ @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birthday; @NumberFormat(style = Style.NUMBER,pattern = "#,###") private int total; @NumberFormat(style = Style.PERCENT) private double discount; @NumberFormat(style = Style.CURRENCY) private double money; //省略set/get方法 }
下面是控制器;
@Controller public class FormatterController{ private static final Log logger = LogFactory.getLog(FormatterController.class); @RequestMapping(value = "/{formName}") public String loginForm(@PathVariable String formName){ return formName; } @RequestMapping(value = "/test",method = RequestMethod.POST) public String test( @ModelAttribute User user; Model model){ logger.info(user); model.addAttribute("user",user); return "success"; } }
success.jsp代码
<@ taglib prefix = "form" uri = "http://www.springframework.org/tags/form" %> <h3>测试表单数据格式化</h3> <form:form modelAttribute = "user" method = "post" action = ""> <table> <tr> <td>日期类型:</td> <td><form:input path = "birthday"/></td> </tr> <tr> <td>整数类型:</td> <td><form:input path = "total"/></td> </tr> <tr> <td>百分数类型:</td> <td><form:input path = "discount"/></td> </tr> <tr> <td>货币类型:</td> <td><form:input path = "money"/></td> </tr> </table> </form:form>
而这种自动装配是不需要特别配置的,只要默认的就行;
<mvc:annotation-driven/>
<@ taglib prefix = "form" uri = "http://www.springframework.org/tags/form" %> <html> <head> </head> <body> <form:form modelAttribute = "user" 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><input type = "submit" value = "提交"/></td> </tr> </table> </form:form> </body> </html>
再写一个Validator类来进行校验,称为校验器;
@Repository("userValidator") public class UserValidator implements Validator{ @Override public boolean supports(Class<?> clazz){ return user.class.isAssignableFrom(clazz); } @Override public void validate(Object target,Errors errors){ ValidationUtils.rejectIfEmpty(errors, "loginname", null, "登录名不能为空"); ValidationUtils.rejectIfEmpty(errors, "password", null, "密码不能为空"); User user = (User)target; if(user.getLoginname().length() > 10){ errors.rejectValue("loginname",null,"用户名不能超过10个字符"); } if(user.getPassword() != null && !user.getPassword().equals("") && user.getPassword().length() < 6){ errors.rejectValue("password",null,"密码不能小于6位"); } } }
通过实现Validator接口来实现校验器;然后只需要在控制器中注入校验器即可,采用对象的方式来实现;
@Autowired @Qualifier("UserValidator") private UserValidator userValidator; @RequestMapping(value = "/login",method = RequestMethod.POST) public String login( @ModelAttribute User user, Model model, Errors errors){ logger.info(user); model.addAttribute("user",user); userValidator.validate(user,errors); if(errors.hasErrors()){ return "loginForm"; } return "success"; }
JSR3.0的话就是各种封装好的注解;同样是用在模型数据类中;
public class User 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; @DateTimeFormate(pattern = "yyyy-MM-dd") @Past(message = "生日必须是一个过去的日期") private Date birthDate; }
在控制器中只需要在引入模型数据之前做一下@Valid就可以了
@RequestMapping(value = "/login",method = RequestMethod.POST) public String login( @Valid @ModelAttribute User user, Errors errors, Model model){ logger.info(user); if(errors.hasErrors()) return "regsiterForm"; model.addAttribute("user",user); return "success"; }