在Spring mvc 中使用alidate 首先需要实现alidate接口写道
@Component
public class ReservationValidator implements Validator {
private static final String COURT_NAME = "courtName";
private static final String DATE = "date";
public boolean supports(Class<?> clazz) {
return Reservation.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, COURT_NAME,
"required.courtName", "Court name is required");
ValidationUtils.rejectIfEmpty(errors, DATE, "required.date",
"Court date is required");
ValidationUtils.rejectIfEmpty(errors, "hour", "required.hour",
"Court hour is required");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "player.name",
"required.playername", "Player name is required");
ValidationUtils.rejectIfEmpty(errors, "sportType",
"required.sportType", "SportType is required");
}
这是一个自定义的alidate实现类。 有了alidate 实现类那么在controller 中有该如何使用呢?这个就很简单了,只要controller 中注入这个validate 就可以直接使用了。
@Controller
@RequestMapping("reservationForm")
@SessionAttributes("reservation")
public class ReservationFormController {
@Autowired
private ReservationService reservationService;
@Autowired
private ReservationValidator reservationValidator;
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, true));
binder.registerCustomEditor(SportType.class,
new PropertyEditorSupport() {
@Override
public void setAsText(String text)
throws IllegalArgumentException {
int sportTypeId = Integer.parseInt(text);
SportType sportType = reservationService
.getSportType(sportTypeId);
setValue(sportType);
}
});
}
/*** @ModelAttribute 注解用于定义全局的模式属性,这种属性对处理方法中返回的任意视图可用 ***/
@ModelAttribute("sportTypes")
public List<SportType> populateSportTypes() {
return reservationService.getAllSportType();
}
@RequestMapping(method = RequestMethod.GET)
public String setupForm(Model model,
@RequestParam("username") String username) {
Reservation reservation = new Reservation();
reservation.setPlayer(new Player(username, null));
model.addAttribute("reservation", reservation);
return "reservationForm";
}
@RequestMapping(method = RequestMethod.POST)
public String submintForm(
@ModelAttribute("reservation") Reservation reservation,
BindingResult result, SessionStatus status, ModelMap model) {
// validate 方法返回后 BindingResult 中就包含了校验过程的结果。
reservationValidator.validate(reservation, result);
// 如果结果中包含错误
if (result.hasErrors()) {
model.addAttribute("reservation", reservation);
return "reservationForm";
}
reservationService.make(reservation);
// 删除session 中的对象
status.setComplete();
return "reservationSuccess";
}
那么如果实在分页控制的controller 中有该如何使用呢?这个就需要将 校验的具体实现分为多个 方法。如:
@Component
public class PeriodicReservationValidator implements Validator {
private static final Logger logger = Logger
.getLogger(PeriodicReservationValidator.class);
private static final String COURT_NAME = "courtName";
public boolean supports(Class<?> clazz) {
return Reservation.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
logger.info("validate,All");
validateCourt(target, errors);
validateTime(target, errors);
validatePlayer(target, errors);
}
public void validateCourt(Object target, Errors errors) {
logger.info("validateCourt");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, COURT_NAME,
"required.courtName", "Court name is required");
}
public void validatePlayer(Object target, Errors errors) {
logger.info("validatePlayer");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "player.name",
"required.playerName", "Player name is required");
}
public void validateTime(Object target, Errors errors) {
logger.info("validateTime");
ValidationUtils.rejectIfEmpty(errors, "fromDate", "required.fromDate",
"Court fromDate is required");
ValidationUtils.rejectIfEmpty(errors, "toDate", "required.toDate",
"Court toDate is required");
ValidationUtils.rejectIfEmpty(errors, "period", "required.period",
"Court period is required");
ValidationUtils.rejectIfEmpty(errors, "hour", "required.hour",
"Court hour is required");
}
package study.spring.mvc.controller;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.util.WebUtils;
import study.spring.mvc.domain.PeriodiceReservation;
import study.spring.mvc.domain.Player;
import study.spring.mvc.service.ReservationService;
import study.spring.mvc.validator.PeriodicReservationValidator;
/**
* 使用@SessionAttributes 注解 为了支持表单的多次提交,并且在提交之间不会失去用户提供的数据。 使用@SessionAttributes
* 注解所赋值可以使用SessionStatus对象删除。
*
* @author Lenovo
*
*/
@Controller
@RequestMapping("periodicReservationForm")
@SessionAttributes("reservation")
public class PeriodReservationFormController {
private static final Logger logger = Logger
.getLogger(PeriodReservationFormController.class);
@Autowired
private ReservationService reservationService;
@Autowired
private PeriodicReservationValidator periodicReservationValidator;
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, true));
}
/*** @ModelAttribute 注解用于定义全局的模式属性,这种属性对处理方法中返回的任意视图可用 ***/
@ModelAttribute("periods")
public Map<Integer, String> periods() {
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "Daliy");
map.put(7, "Weekly");
logger.info(map);
return map;
}
@RequestMapping(method = RequestMethod.GET)
public String setupForm(Model model) {
PeriodiceReservation reservation = new PeriodiceReservation();
reservation.setPlayer(new Player());
model.addAttribute("reservation", reservation);
return "reservationCourtForm";
}
@RequestMapping(method = RequestMethod.POST)
public String submintForm(
@ModelAttribute("reservation") PeriodiceReservation reservation,
HttpServletRequest request, HttpServletResponse response,
@RequestParam("_page") int currentPage, BindingResult result,
SessionStatus status, ModelMap model) {
Map<Integer, String> pageForms = new HashMap<Integer, String>();
logger.info("currentPage:" + currentPage);
pageForms.put(0, "reservationCourtForm");
pageForms.put(1, "reservationTimeForm");
pageForms.put(2, "reservationPlayerForm");
if (request.getParameter("_cancel") != null) {
return pageForms.get(currentPage);
} else if (request.getParameter("_finish") != null) {
logger.info("validate");
periodicReservationValidator.validate(reservation, result);
if (!result.hasErrors()) {
reservationService.makePeriodic(reservation);
status.setComplete();
return "reservationSuccess";
} else {
logger.info("validate fail:" + currentPage);
return pageForms.get(currentPage);
}
} else {
int targetPage = WebUtils.getTargetPage(request, "_target",
currentPage);
if (targetPage < currentPage) {
return pageForms.get(targetPage);
}
switch (currentPage) {
case 0:
periodicReservationValidator.validateCourt(reservation, result);
break;
case 1:
periodicReservationValidator.validateTime(reservation, result);
break;
case 2:
periodicReservationValidator
.validatePlayer(reservation, result);
break;
}
if (!result.hasErrors()) {
return pageForms.get(targetPage);
} else {
return pageForms.get(currentPage);
}
}
}
}
这样就可以在不同的页面使用不同的校验。
通过注解的方式校验示例代码如下:
/**
*银行查询文件中条目模型
*
* @author zhangwei
* @version $Id: RemitInquiryOrder.java, v 0.1 2015年4月23日 下午1:53:08 zhangwei Exp $
*/
public class RemitInquiryOrder extends BasicModel {
/**UUID */
private static final long serialVersionUID = 4502527293700078171L;
/******************银行查询数据******************/
/**银行业务编号**/
@NotNull
@MinLength(value = 2)
@MaxLength(value = 32)
private String outBizNo;
/**查询流水号**/
@NotNull
@MinLength(value = 2)
@MaxLength(value = 32)
private String outInquiryId;
/**清算流水号**/
@NotNull
@RegExp(value = "^\\d{19}")
private String settleSerialNo;
/**币种**/
@NotNull
@RegExp(value = "^[A-Z]{3}$")
private String currency;
/**汇款金额**/
@NotNull
@RegExp(value = "^([1-9]\\d*[.]?)(\\d{0,2})|(0.)(([0-9]?)[1-9])?$")
private String remitAmount;
/**查询查复类型**/
@NotNull
@RegExp(value = "^Q[1,2]\\d{4}$")
private String inquiryType;
/**报文内容**/
@MaxLength(value = 200)
private String detail;
/**过期时间**/
@MaxLength(value = 19)
@RegExp(value = "(\\s{0}|\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2})")
private String expiryDate;
/**备注**/
@MaxLength(value = 50)
private String remark;
//校验对象
validator.validate(remitInquiryOrder, errors);
if (errors.hasErrors()) {
LoggerUtil
.error(logger, "查询明细校验不合法,item={0},errors={1}", item, errors.getFieldErrors());
remitInquiryOrder.setResult(RemitConstants.DATA_FAIL);
remitInquiryOrder.setResultCode(RemitInquiryResultCode.ILLEGAL_ARGUMENT.getCode());
}
<bean id="validator" class="org.springmodules.validation.bean.BeanValidator"
p:configurationLoader-ref="configurationLoader" />
<bean id="configurationLoader"
class="org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader" />