Bean Validation表单校验+Exception异常抛出

  • Bean Validation表单校验Exception异常抛出简介
  • 源码
    • 引入的pomxml依赖
    • 实体类Param
    • 表单验证工具类ParamValidateUtil
    • 异常抛出工具类ParamExceptionUtil
    • 测试代码ParamExceptionTest
    • 测试结果

Bean Validation表单校验+Exception异常抛出简介

  在JavaWeb开发的过程中,我们经常需要处理前台表单页面传递过来的参数信息,通常情况下我们先是校验参数信息的合法性,然后对于不合法的参数信息,我们不仅仅要将该异常信息抛出,同时我们还要在抛出异常信息时定位该出错点,因而下面的程序对于处理上述功能要求来说就变得比较的合适。

  该程序引入的依赖中包括Bean Validation表单验证,lombok插件,最强大的日志log4j2,以及主流的jackson。实现的功能是对于页面表单的信息校验,当信息验证不通过时在日志中抛出该异常信息,方便于后续的项目维护。

源码

引入的pom.xml依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>throw-exception-parentartifactId>
        <groupId>com.lycgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>param-throw-exceptionartifactId>
    <packaging>jarpackaging>

    <name>param-throw-exceptionname>
    <url>http://maven.apache.orgurl>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <configuration>
                    <source>1.8source>
                    <target>1.8target>
                configuration>
            plugin>
        plugins>
    build>

    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    properties>

    <dependencies>
        
        <dependency>
            <groupId>javax.validationgroupId>
            <artifactId>validation-apiartifactId>
            <version>2.0.1.Finalversion>
        dependency>
        <dependency>
            <groupId>org.hibernate.validatorgroupId>
            <artifactId>hibernate-validatorartifactId>
            <version>6.0.7.Finalversion>
        dependency>
        
        
        <dependency>
            <groupId>org.glassfishgroupId>
            <artifactId>javax.elartifactId>
            <version>3.0.1-b08version>
        dependency>
        
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.16.20version>
            <scope>providedscope>
        dependency>
        <dependency>
            <groupId>org.apache.logging.log4jgroupId>
            <artifactId>log4j-slf4j-implartifactId>
            <version>2.10.0version>
        dependency>
        
        <dependency>
            <groupId>org.apache.logging.log4jgroupId>
            <artifactId>log4j-coreartifactId>
            <version>2.10.0version>
        dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.datatypegroupId>
            <artifactId>jackson-datatype-guavaartifactId>
            <version>2.5.3version>
        dependency>
    dependencies>
project>

实体类Param

package com.lyc.exception.entity;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

@Setter
@Getter
@Builder
public class Param {

    @NotNull(message = "id字段不能为空!")
    private Integer id;
    @NotBlank(message = "姓名不能为空!")
    @Size(min = 2,max = 12,message = "姓名介于2-12之间!")
    private String name;
    @NotNull(message = "age字段不能为空!")
    private Integer age;

}

表单验证工具类ParamValidateUtil

package com.lyc.exception.util;

import com.google.common.collect.Maps;
import lombok.NoArgsConstructor;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Set;

@NoArgsConstructor
public class ParamValidateUtil<T>{

    //初始化ValidatorFactory
    private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    private Set> constraintViolations;

    /** * 构造方法 * 利用泛型,传入实体类,进行表单验证。 * @param t */
    public ParamValidateUtil(T t) {
        Validator validator = factory.getValidator();
        this.constraintViolations = validatorParamValite(t,validator);
    }

    /** * 利用泛型,传入实体类表单,传入Validator进行表单验证 * @param t * @param validator * @return */
    private Set> validatorParamValite(T t,Validator validator){
        return validator.validate( t );
    }

    /** * 获取验证的返回信息 * @return */
    public LinkedHashMap getMessage(){
        LinkedHashMap errors = Maps.newLinkedHashMap();
        if(getSize() > 0){
            Iterator> iterator = constraintViolations.iterator();
            while(iterator.hasNext()){
                ConstraintViolation constraintViolation = iterator.next();
                errors.put(constraintViolation.getPropertyPath(),constraintViolation.getMessage());
            }
        }
        return errors;
    }

    /** * 获取错误的信息条数 * @return */
    public int getSize(){
        return constraintViolations.size();
    }

    /** * 判断参数校验是否通过 * @return */
    public boolean checkParam(){
        return getSize() > 0;
    }
}

异常抛出工具类ParamExceptionUtil

package com.lyc.exception.util;

import lombok.NoArgsConstructor;

@NoArgsConstructor
public class ParamExceptionUtil extends RuntimeException {

    public ParamExceptionUtil(String message) {
        super(message);
    }

    public ParamExceptionUtil(String message, Throwable cause) {
        super(message, cause);
    }

    public ParamExceptionUtil(Throwable cause) {
        super(cause);
    }

    protected ParamExceptionUtil(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

测试代码ParamExceptionTest

package com.lyc.exception;

import com.lyc.exception.entity.Param;
import com.lyc.exception.util.ParamExceptionUtil;
import com.lyc.exception.util.ParamValidateUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Test;

import java.util.LinkedHashMap;

@Slf4j
public class ParamExceptionTest {

    /**
     * 校验正确的结果
     */
    @Test
    public void testSuccessfull(){
        Param param = Param.builder()
                .id(1)
                .name("zhangsan")
                .age(21)
                .build();

        ParamValidateUtil paramParamValidateUtil = new ParamValidateUtil(param);
        int count = paramParamValidateUtil.getSize();
        Assert.assertEquals(0,count);
        log.info("错误信息条数为:{}",count);
        LinkedHashMap errors = paramParamValidateUtil.getMessage();
        errors.forEach((k,v) -> log.info("打印的错误信息内容为:{},{}",k.toString(),v.toString())); } /** * 校验Name错误的结果 */ @Test public void testParamNameError(){ Param param = Param.builder() .id(1) .name("z") .age(21) .build(); ParamValidateUtil<Param> paramParamValidateUtil = new ParamValidateUtil(param); int count = paramParamValidateUtil.getSize(); log.info("错误信息条数为:{}",count); LinkedHashMap errors = paramParamValidateUtil.getMessage(); errors.forEach((k,v) -> log.info("打印的错误信息内容为:{},{}",k.toString(),v.toString())); if(paramParamValidateUtil.checkParam()){ throw new ParamExceptionUtil("testParamNameError()->姓名参数校验失败!"); } } /** * 校验age错误的结果。 */ @Test public void testParamAgeError(){ Param param = Param.builder() .id(1) .name("zhangsan") .age(null) .build(); ParamValidateUtil<Param> paramParamValidateUtil = new ParamValidateUtil(param); int count = paramParamValidateUtil.getSize(); log.info("错误信息条数为:{}",count); LinkedHashMap errors = paramParamValidateUtil.getMessage(); errors.forEach((k,v) -> log.info("打印的错误信息内容为:{},{}",k.toString(),v.toString())); if(paramParamValidateUtil.checkParam()){ throw new ParamExceptionUtil("testParamAgeError()->年龄参数校验失败!"); } } /** * 校验空表单 */ @Test public void testParamAllError(){ Param param = Param.builder() .id(null) .name(null) .age(null) .build(); ParamValidateUtil<Param> paramParamValidateUtil = new ParamValidateUtil(param); int count = paramParamValidateUtil.getSize(); log.info("错误信息条数为:{}",count); LinkedHashMap errors = paramParamValidateUtil.getMessage(); errors.forEach((k,v) -> log.info("打印的错误信息内容为:{},{}",k.toString(),v.toString())); if(paramParamValidateUtil.checkParam()){ throw new ParamExceptionUtil("testParamAllError()->全部参数校验失败!"); } } }

测试结果

  我们以测试中的最后一个方法testParamAllError()为例来进行说明,由于该方法中,我们所创建的实体类中所有的参数均为null,因而它会产生三条错误信息。

  我们在Param实体类中将所有的参数信息全部赋值为null,然后初始化ParamValidateUtil类。该类中有一个泛型的构造方法,通过传入一个实体类,我们将可以完成其初始化操作,之后我们将其错误信息条数打印到控制台中。

  接下来我们就获取错误信息的内容,通过paramParamValidateUtil.getMessage()方法,返回一个LinkedHashMap数组,我们通过java8中的lambda表达式,将该LinkedHashMap数组中的信息一一输出到控制台中。

  最后就是异常信息抛出,我们采用throw的方式将该异常信息抛出到日志中,同时我建议在抛出异常信息前,我们在所抛出的信息中添加抛出该信息的方法名以及故障原因,这样显示出来的异常信息中,将不仅仅包含类名,还包含调用该方法的方法名以及相应的错误异常信息。

  下面是其在控制台中打印出来的异常信息:

2018-02-05 15:56:51  INFO main org.hibernate.validator.internal.util.Version.(Version.java:21) - HV000001: Hibernate Validator 6.0.7.Final
2018-02-05 15:56:51  INFO main com.lyc.exception.ParamExceptionTest.testParamAllError(ParamExceptionTest.java:91) - 错误信息条数为:3
2018-02-05 15:56:51  INFO main com.lyc.exception.ParamExceptionTest.lambda$testParamAllError$3(ParamExceptionTest.java:93) - 打印的错误信息内容为:id,id字段不能为空!
2018-02-05 15:56:51  INFO main com.lyc.exception.ParamExceptionTest.lambda$testParamAllError$3(ParamExceptionTest.java:93) - 打印的错误信息内容为:age,age字段不能为空!
2018-02-05 15:56:51  INFO main com.lyc.exception.ParamExceptionTest.lambda$testParamAllError$3(ParamExceptionTest.java:93) - 打印的错误信息内容为:name,姓名不能为空!

com.lyc.exception.util.ParamExceptionUtil: testParamAllError()->全部参数校验失败!

    at com.lyc.exception.ParamExceptionTest.testParamAllError(ParamExceptionTest.java:95)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    ...

项目源码:throw-exception-parent

你可能感兴趣的:(Java)