SpringMVC 参数校验

来源:互联网 发布:淘宝要求3c认证 编辑:程序博客网 时间:2024/04/29 13:10

参数校验虽说大多在前台通过js完成,但是也应该懂得如何在后端实现参数的简单校验。由于本人目前处于初级阶段,所以文章的深度有限。随着时间推移我会逐渐更新。
参数校验的步骤我就不在赘述,推荐:
参数校验的步骤
我感觉这篇文章,博主其实写的还可以。
我这只说参数校验的另外一种方法,通过继承和引用实现参数校验。
首先是Model参数类:
speaker.java

package com.zhiyou100.video.model;import java.sql.Date;import javax.validation.constraints.Size;import org.springframework.web.multipart.MultipartFile;import com.zhiyou100.video.common.ValidateGroup1;public class Speaker {    private int id;    @Size(min=2,max=5,message="{name.error}",groups={ValidateGroup1.class})    private String speakerName;    private String speakerJob;    private String speakerHeadUrl;    private String speakerDescr;    private MultipartFile icon;    private Date insertTime;    private Date updateTime;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getSpeakerName() {        return speakerName;    }    public void setSpeakerName(String speakerName) {        this.speakerName = speakerName;    }    public String getSpeakerJob() {        return speakerJob;    }    public void setSpeakerJob(String speakerJob) {        this.speakerJob = speakerJob;    }    public String getSpeakerHeadUrl() {        return speakerHeadUrl;    }    public void setSpeakerHeadUrl(String speakerHeadUrl) {        this.speakerHeadUrl = speakerHeadUrl;    }    public String getSpeakerDescr() {        return speakerDescr;    }    public void setSpeakerDescr(String speakerDescr) {        this.speakerDescr = speakerDescr;    }    public Date getInsertTime() {        return insertTime;    }    public void setInsertTime(Date insertTime) {        this.insertTime = insertTime;    }    public Date getUpdateTime() {        return updateTime;    }    public void setUpdateTime(Date updateTime) {        this.updateTime = updateTime;    }    public MultipartFile getIcon() {        return icon;    }    public void setIcon(MultipartFile icon) {        this.icon = icon;    }    @Override    public String toString() {        return "SpeakerModel [id=" + id + ", speakerName=" + speakerName + ", speakerJob=" + speakerJob                + ", speakerHeadUrl=" + speakerHeadUrl + ", speakerDescr=" + speakerDescr + ", insertTime=" + insertTime                + ", updateTime=" + updateTime + "]";    }}

我这里为方便,只写了一种校验:校验输入的speakername的最小为2最大不超过5.我这里让参数校验不通过,传递到了另外一个页面上。
addError.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body>    ${message}</body></html>

如果参数校验不通过会跳转到这个jsp页面上面,给出提示信息。这些信息来源于。
CustomValidationMessage.properties文件

age.error=年龄在1100之间hobby.error=爱好输入不正确'name.error=姓名错误

这个东西,在配置校验框架的时候已经提到。
接着就是进行,校验工作。
我这里是将校验安排在了一个父类BaseController.java,和一个工具类BeanValidators.java里面。
而这样,只需要在controller层调用相应的方法即可
BeanValidators.java

package com.zhiyou100.video.util;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import javax.validation.ConstraintViolation;import javax.validation.ConstraintViolationException;import javax.validation.Validator;/** * Validator(Hibernate Validator)工具类. *  * ConstraintViolation中包含propertyPath, message 和invalidValue等信息. * 提供了各种convert方法,适合不同的i18n需求: 1. List<String>, String内容为message 2. * List<String>, String内容为propertyPath + separator + message 3. * Map<propertyPath, message> *  */public class BeanValidators {    /**     * 调用JSR303的validate方法, 验证失败时抛出ConstraintViolationException.     */    @SuppressWarnings({ "unchecked", "rawtypes" })    public static void validateWithException(Validator validator, Object object, Class<?>... groups)            throws ConstraintViolationException {        Set constraintViolations = validator.validate(object, groups);        if (!constraintViolations.isEmpty()) {            throw new ConstraintViolationException(constraintViolations);        }    }    /**     * 辅助方法,     * 转换ConstraintViolationException中的Set<ConstraintViolations>中为List<message>.     */    public static List<String> extractMessage(ConstraintViolationException e) {        return extractMessage(e.getConstraintViolations());    }    /**     * 辅助方法, 转换Set<ConstraintViolation>为List<message>     */    @SuppressWarnings("rawtypes")    public static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {        List<String> errorMessages = new ArrayList<String>();        for (ConstraintViolation violation : constraintViolations) {            errorMessages.add(violation.getMessage());        }        return errorMessages;    }    /**     * 辅助方法,     * 转换ConstraintViolationException中的Set<ConstraintViolations>为Map<property,     * message>.     */    public static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {        return extractPropertyAndMessage(e.getConstraintViolations());    }    /**     * 辅助方法, 转换Set<ConstraintViolation>为Map<property, message>.     */    @SuppressWarnings("rawtypes")    public static Map<String, String> extractPropertyAndMessage(            Set<? extends ConstraintViolation> constraintViolations) {        Map<String, String> errorMessages = new HashMap<String, String>();        for (ConstraintViolation violation : constraintViolations) {            errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());        }        return errorMessages;    }    /**     * 辅助方法,     * 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath     * message>.     */    public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) {        return extractPropertyAndMessageAsList(e.getConstraintViolations(), " ");    }    /**     * 辅助方法, 转换Set<ConstraintViolations>为List<propertyPath message>.     */    @SuppressWarnings("rawtypes")    public static List<String> extractPropertyAndMessageAsList(            Set<? extends ConstraintViolation> constraintViolations) {        return extractPropertyAndMessageAsList(constraintViolations, " ");    }    /**     * 1234 辅助方法,     * 转换ConstraintViolationException中的Set<ConstraintViolations>为List<propertyPath     * +separator+ message>.     */    public static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {        return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator);    }    /**     * 辅助方法, 转换Set<ConstraintViolation>为List<propertyPath +separator+ message>.     */    @SuppressWarnings("rawtypes")    public static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations,            String separator) {        List<String> errorMessages = new ArrayList<String>();        for (ConstraintViolation violation : constraintViolations) {            try {                errorMessages.add(violation.getPropertyPath() + separator                        + new String(violation.getMessage().getBytes("ISO-8859-1"), "UTF-8"));            } catch (UnsupportedEncodingException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        return errorMessages;    }}

BaseController.java

package com.zhiyou100.video.controller;import java.beans.PropertyEditorSupport;import java.sql.Date;import java.sql.Timestamp;import java.util.List;import javax.validation.ConstraintViolationException;import javax.validation.Validator;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.ui.Model;import org.springframework.validation.BindException;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.InitBinder;import com.zhiyou100.video.util.BeanValidators;import com.zhiyou100.video.util.DateUtil;public class BaseController {    /*     * 作业 io nio 今天讲的内容     *      * 明天讲mybatis     *      */    @Autowired    protected Validator validator;    /**     * 初始化数据绑定 1. 将所有传递进来的String进行HTML编码,防止XSS攻击 2. 将字段中Date类型转换为String类型     */    @InitBinder    protected void initBinder(WebDataBinder binder) {        // 任何转换器都不配置 按格式输入(yyyy-MM-dd,yyyy-MM-dd HH:mm:ss)不会报错 否则400        // 转换器配置的两种方式掌握        // 如果配置了参数校验springmvc 参数绑定如果出现异常就不会报400错误了 但是不能正常赋值        /*         * binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {         *          * @Override public void setAsText(String text) {         * setValue(DateUtil.stringToDateyy(text));         *          * }         *          * });         */        binder.registerCustomEditor(Timestamp.class, new PropertyEditorSupport() {            @Override            public void setAsText(String text) {                setValue(new Timestamp(DateUtil.stringToDate(text).getTime()));            }        });    }    /**     * 异常处理     *      * @return     */    @ExceptionHandler({ BindException.class, IllegalStateException.class })    public String bindException() {        return "/error/400";    }    /*     * 权限异常     *      * 业务异常 都可以在这处理     *      *      *      */    /**     * 服务端参数有效性验证     *      * @param object     *            验证的实体对象     * @param groups     *            验证组     * @return 验证成功:返回true;严重失败:将错误信息添加到 message 中     */    protected boolean beanValidator(Model model, Object object, Class<?>... groups) {        try {            BeanValidators.validateWithException(validator, object, groups);        } catch (ConstraintViolationException ex) {            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");            list.add(0, "数据验证失败:");            addMessage(model, list.toArray(new String[] {}));            return false;        }        return true;    }    /**     * 服务端参数有效性验证     *      * @param object     *            验证的实体对象     * @param groups     *            验证组,不传入此参数时,同@Valid注解验证     * @return 验证成功:继续执行;验证失败:抛出异常跳转400页面。     */    protected void beanValidator(Object object, Class<?>... groups) {        BeanValidators.validateWithException(validator, object, groups);    }    /**     * 添加Model消息     *      * @param message     */    protected void addMessage(Model model, String... messages) {        StringBuilder sb = new StringBuilder();        for (String message : messages) {            sb.append(message).append(messages.length > 1 ? "<br/>" : "");        }        model.addAttribute("message", sb.toString());    }}

配置好这两个类,就可以在controller层进行校验操作:
这里写图片描述

if (!this.beanValidator(model, speaker, ValidateGroup1.class)) {            return "/admin/speaker/addError";        }

这个就是核心代码,如果参数为真,那么就执行if里面的return操作,返回到一个jsp页面上显示效果如下:
这里写图片描述
源码我稍后上传GitHub之后,再补个链接出来。有什么问题,或者不对的地方,请指出来,共同进步。

原创粉丝点击