jfinal集成hibernate validation

1.引入依赖

		<dependency>
			<groupId>org.hibernate.validator</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>${hibernate-validator.version}</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish</groupId>
			<artifactId>javax.el</artifactId>
			<version>${org.glassfish.version}</version>
			<scope>provided</scope>
		</dependency>

2.定义拦截器

package com.future.common.interceptor;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;

import com.future.common.exception.BadRequestException;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
/**
 * controller参数拦截器
 * @author ThinkPad
 *
 */
public class RequestParasValidator implements Interceptor {
	private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

	@Override
	public void intercept(Invocation inv) {
		ExecutableValidator validatorParam = validator.forExecutables();
		/*
		 *在方法执行之前会对参数值进行校验 
		 */
		Set<ConstraintViolation<Object>> constraintViolationSet = validatorParam.validateParameters(inv.getController(), inv.getMethod(), inv.getArgs());
		if(constraintViolationSet.size()>0){
			ConstraintViolation<Object> constraintViolations  = constraintViolationSet.stream().findFirst().get();
			throw new BadRequestException(constraintViolations.getMessage());
		}
		inv.invoke();
	}

}

3.配置拦截器

	@Override
	public void configInterceptor(Interceptors me) {
		// 异常处理拦截器
		
		me.addGlobalActionInterceptor(new RequestParasValidator());
	}

4.校验

	@Before(Tx.class)
	public void passwordChange(@NotNull(message="用户信息为空!")String userid, @NotNull(message="旧密码为空!")String passwordold, @NotNull(message="新密码为空!")String passwordnew){
		this.sysUserService.passWordChange(userid, passwordold, passwordnew);
		renderSuccess();
		
	}

5.查看结果

{
    "result": null,
    "_success": false,
    "_message": "用户信息为空!",
    "code": "400"
}

注意:需要开启了action参数注入才行

Json入参校验

1.controller封装方法

	/**
	 * 从request中获取json,校验hibernate validator 注解
	 * @param type
	 * @return
	 */
	protected <T> T getJsonBody(Class<T> type) {
		return getJsonBody(type, true);
	}
	/**
	 * 获取jsonbody
	 * @param type
	 * @param validate
	 * @return
	 */
	protected <T> T getJsonBody(Class<T> type, boolean validate) {
		String jsonStr = HttpKit.readData(getRequest());
		T result = null;
		try{
			result = JsonKit.parse(jsonStr, type);
		}catch (Exception e) {
			throw new BadRequestException("Bad Request");
		}
		if(result !=null && validate){
			ValidationUtil.checkValidation(result);
		}
		return result;
	}	

工具类方法

package com.future.common.utils;

import java.util.Set;

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

import com.future.common.exception.BadRequestException;

public class ValidationUtil {
	private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
	public static void checkValidation(Object object){
		Set<ConstraintViolation<Object>> set = validator.validate(object);
        // 校验错误信息返回
		if(set.size()>0){
			ConstraintViolation<Object> constraintViolations  = set.stream().findFirst().get();
			throw new BadRequestException(constraintViolations.getMessage());
		}
        
	}
}	

异常类

package com.future.common.exception;

public class BadRequestException extends RuntimeException{
	/**
	 * 用于返回给用户请求的参数不符合要求
	 */
	private static final long serialVersionUID = 1L;

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

异常处理类

package com.future.common.interceptor;

import com.future.common.bean.Result;
import com.future.common.exception.AppException;
import com.future.common.exception.AuthenticationException;
import com.future.common.exception.BadRequestException;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.kit.PropKit;

import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AppExceptionInterceptor implements Interceptor {

	@Override
	public void intercept(Invocation inv) {
		Boolean devMode = PropKit.getBoolean("devMode");
		Controller controller = inv.getController();
		Result result = new Result();
		result.set_success(true);
		try {
			inv.invoke();
		} catch (AppException e) {
			result.set_success(false);
			if (devMode) {
				e.printStackTrace();
			}
			result.set_message(e.getMessage());
			result.setCode("200");
			controller.renderJson(result);
		//认证异常
		}catch(AuthenticationException e){
			result.set_success(false);
			if (devMode) {
				e.printStackTrace();
			}
			result.set_message(e.getMessage());
			result.setCode("401");
			controller.renderJson(result);
		}catch(BadRequestException e){
			result.set_success(false);
			if (devMode) {
				e.printStackTrace();
			}
			log.error("请求异常", e);
			result.set_message(e.getMessage());
			result.setCode("400");
			controller.renderJson(result);
		}catch (Exception e) {
			result.set_success(false);
			if (devMode) {
				e.printStackTrace();
			}
			log.error("内部异常", e);
			result.set_message(e.getMessage());
			result.setCode("500");
			controller.renderJson(result);
		}
	}
}


关注我的公众号,免费获取Java + Jfinal学习视频

image.png


评论区

快乐的蹦豆子

2018-12-24 17:30

集成了hibernate validation之后感觉比写validator更快了一些,起码少写了很多类

JFinal

2018-12-24 17:34

@快乐的蹦豆子 你那里这么多扩展,不早拿出来?

快乐的蹦豆子

2018-12-24 17:37

@JFinal 好的,有空我都搞上来。

JFinal

2018-12-24 17:39

逍遥一生

2018-12-25 13:09

可以对入参是对象类型的进行校验吗

快乐的蹦豆子

2018-12-25 13:43

@逍遥一生 如果传入的不是json格式,而是用form 提交的,也可以校验
public void getToken(@Valid @Param("") SysUser user) {}
注意这个user只能是普通的bean,如果是model是不可以的哦

快乐的蹦豆子

2018-12-25 13:47

其实原理就是jfinal把参数准备好了,我只是调用一些hibernate的方法,进行校验而已

逍遥一生

2018-12-25 16:05

@快乐的蹦豆子 嗯 了解 感谢分享

zhangtianxiao

2019-05-31 19:42

控制器上有bean/model, 字段的校验顺序怎么做呢, 官方只提供了groups, 这个东东很麻烦

快乐的蹦豆子

2019-06-01 14:40

@zhangtianxiao 这个得仔细看看hibernate validation的校验了,我这也是无序的,有序的一般都在前端做了,后端是以防万一的,对顺序要求没那么高