规则引擎
依赖
1 2 3 4 5 6
| <dependency> <groupId>com.googlecode.aviator</groupId> <artifactId>aviator</artifactId> <version>5.3.3</version> </dependency>
|
封装成 bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| package com.nwa.config;
import com.googlecode.aviator.AviatorEvaluator; import lombok.Data; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Component; import com.googlecode.aviator.Expression;
import java.io.IOException; import java.util.Map;
@Component @Data public class RuleAv{ private Expression exp; public RuleAv() { try { String scriptPath = new ClassPathResource("script/photoController.av").getPath(); exp = AviatorEvaluator.getInstance().compileScript(scriptPath); } catch (IOException e) { System.out.println("Error loading script file: " + e.getMessage()); } }
}
|
注入
1 2 3 4 5 6 7 8 9
| @Resource private RuleAv ruleAv;
Map<String, Object> context=new HashMap<>(); context.put("acc",acc); Boolean flag =(Boolean) ruleAv.getExp().execute(context); if (!flag) { return R.error("格式有误!"); }
|
脚本位置放在项目 src\main\resources 下面新建文件夹 script,文件名 photoController.av
1 2 3
| let regex = /^[a-zA-Z]{5,10}$/; println(regex); return (acc = ~regex);
|
demo—-测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| package com.nwa.other;
import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.Expression; import org.junit.Test; import org.springframework.core.io.ClassPathResource;
import java.io.IOException; import java.util.HashMap; import java.util.Map;
public class RuleDemo { @Test public void testHello() throws Exception {
ClassPathResource resource = new ClassPathResource("script/rule.av"); String scriptPath = resource.getPath(); Expression exp = AviatorEvaluator.getInstance().compileScript(scriptPath); exp.execute();
String script2 = "println(\"Hello, AviatorScript!\");"; Expression exp2 = AviatorEvaluator.getInstance().compile(script2); exp2.execute();
String expression = "a-(b-c) > 100"; Expression compiledExp = AviatorEvaluator.compile(expression);
double a = 100.3, b = 45, c = -199.100; Map<String, Object> context = new HashMap<>(); context.put("a", a); context.put("b", b); context.put("c", c);
Boolean result = (Boolean) compiledExp.execute(context); System.out.println(result); }
@Test public void demo2() throws IOException {
Expression exp = AviatorEvaluator.getInstance().compileScript(new ClassPathResource("script/rule.av").getPath()); Map<String, Object> context = new HashMap<>(); context.put("amount", 1000); context.put("rating", 2); String result = (String) exp.execute(context); System.out.println(result);
}
@Test public void fun88() throws IOException { Expression exp = AviatorEvaluator.getInstance().compileScript(new ClassPathResource("script/rule.av").getPath()); Map<String, Object> context = new HashMap<>(); context.put("acc", "lucky"); Boolean result = (Boolean) exp.execute(context); System.out.println(result); } }
|
Spring Validation
https://blog.51cto.com/u_15964717/6093652
如果 spring-boot 版本小于 2.3.x,spring-boot-starter-web 会自动传入 hibernate-validator 依赖;
如果 spring-boot 版本大于 2.3.x,则需要手动引入依赖:
1 2 3 4 5
| <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.18.Final</version> </dependency>
|
参数异常即中断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.nwa.config;
import org.hibernate.validator.HibernateValidator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory;
@Configuration public class WebParamValidateConfig { @Bean public Validator validator() { ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) .configure() .failFast(true) .buildValidatorFactory(); return validatorFactory.getValidator(); }
@Bean public MethodValidationPostProcessor methodValidationPostProcessor() { MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor(); methodValidationPostProcessor.setValidator(validator()); return methodValidationPostProcessor; } }
|
自定义异常处理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
| package com.nwa.common.exception;
import com.nwa.common.untils.Constant; import com.nwa.common.untils.R; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DuplicateKeyException; import org.springframework.validation.BindException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.validation.ConstraintViolationException;
@RestControllerAdvice @EnableWebMvc @Slf4j public class RRExceptionHandler { @ExceptionHandler(LukcyException.class) public R handleRRException(LukcyException e) { R r = new R(); r.put("code", e.getCode()); r.put("msg", e.getMessage()); return r; }
@ExceptionHandler(NoHandlerFoundException.class) public R noHandlerFoundException(Exception e) { log.error("路径不存在,请检查接口是否正确," + e.getMessage()); return R.error(404, "路径不存在,请检查接口是否正确"); }
@ExceptionHandler(DuplicateKeyException.class) public R duplicateKeyException(DuplicateKeyException e) { log.error("数据库中已存在该记录" + e.getMessage()); return R.error(400, "数据库中已存在该记录"); }
@ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public R methodArgumentNotValidException(MethodArgumentNotValidException e) { log.error(e.getBindingResult().getFieldError().getDefaultMessage()); return R.error(Constant.VALIDATOR_ERROR, e.getBindingResult().getFieldError().getDefaultMessage()); }
@ExceptionHandler(BindException.class) @ResponseBody public R BindExceptionHandler(BindException e) { log.error(e.getBindingResult().getFieldError().getDefaultMessage()); return R.error(Constant.VALIDATOR_ERROR, e.getBindingResult().getFieldError().getDefaultMessage()); }
@ExceptionHandler(ConstraintViolationException.class) @ResponseBody public R ConstraintViolationExceptionHandler(ConstraintViolationException e) { log.error(e.getMessage()); return R.error(Constant.VALIDATOR_ERROR, e.getMessage()); }
@ExceptionHandler(Exception.class) public R handleException(Exception e) { log.error(e.getMessage()); return R.error(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package com.nwa.common.exception;
public class LukcyException extends RuntimeException { private static final long serialVersionUID = 1L;
private String msg; private int code = 400;
public LukcyException(String msg) { super(msg); this.msg = msg; }
public LukcyException(String msg, Throwable e) { super(msg, e); this.msg = msg; }
public LukcyException(String msg, int code) { super(msg); this.msg = msg; this.code = code; }
public LukcyException(String msg, int code, Throwable e) { super(msg, e); this.msg = msg; this.code = code; }
public String getMsg() { return msg; }
public void setMsg(String msg) { this.msg = msg; }
public int getCode() { return code; }
public void setCode(int code) { this.code = code; }
}
|
返回类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package com.nwa.common.untils;
import java.util.HashMap; import java.util.Map;
public class R extends HashMap<String, Object> { private static final long serialVersionUID = 1L;
public R() { put("code", 200); put("msg", "数据返回成功!"); }
public static R error() { return error(500, "未知异常,请联系管理员"); }
public static R error(String msg) { return error(400, msg); }
public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; }
public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; }
public static R ok(Map<String, Object> map) { R r = new R(); r.putAll(map); return r; }
public static R ok() { return new R(); }
public R put(String key, Object value) { super.put(key, value); return this; } }
|
分组
1 2 3 4
| @NotEmpty(message = "添加课程名称不能为空",groups={ValidationGroups.Inster.class}) @NotEmpty(message = "修改课程名称不能为空",groups={ValidationGroups.Update.class}) @ApiModelProperty(value = "课程名称", required = true) private String name;
|
1 2 3 4 5 6 7 8 9
| public class ValidationGroups {
public interface Inster{}; public interface Update{}; public interface Delete{};
}
|
调用在Controller方法上,选择方式
1
| @Validated(ValidationGroups.Inster.class)
|