Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在控制器方法之前检查参数值格式?_Java_Spring_Spring Mvc_Spring Aop - Fatal编程技术网

Java 如何在控制器方法之前检查参数值格式?

Java 如何在控制器方法之前检查参数值格式?,java,spring,spring-mvc,spring-aop,Java,Spring,Spring Mvc,Spring Aop,在我的控制器中,我有如下方法: public QueryResult<TrsAccount> listExclude(String codeAccount, String searchFilter, String order, int pageNumber, int pageSize){} 因为这在我的应用程序中非常常见,而且不仅仅是这种情况,我需要一种检查参数格式的通用方法。我现在使用的是AOP,其中: @Aspect public class HijackBefore

在我的控制器中,我有如下方法:

public QueryResult<TrsAccount> listExclude(String codeAccount, String searchFilter, String order, int pageNumber,
     int pageSize){}
因为这在我的应用程序中非常常见,而且不仅仅是这种情况,我需要一种检查参数格式的通用方法。我现在使用的是AOP,其中:

@Aspect
public class HijackBeforeMethod {

@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controllerBean() {
}

@Pointcut("execution(* *(..))")
public void methodPointcut() {
}

@Before(value = "controllerBean() && methodPointcut()", argNames = "joinPoint")
public void before(JoinPoint joinPoint) {

  MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  Object[] args = joinPoint.getArgs();
  String[] paramNames = signature.getParameterNames();
  for (int count = 0; count < paramNames.length; count++) {
     String tempParam = paramNames[count];
     Object tempValue = args[count];
     if (tempParam.toLowerCase().equalsIgnoreCase("codeAccount") && Assert.isNotNull(tempValue)
           && Assert.isNotEmpty((String) tempValue)) {
        Assert.TRUE(((String) tempValue).matches("^[0-9]{1,20}$"));
     }
  }
}
}
@方面
公共类劫持方法{
@切入点(“在(@org.springframework.stereotype.Controller*)内)
公共无效控制器bean(){
}
@切入点(“执行(**(..)”)
公共void方法切入点(){
}
@在(value=“controllerBean()&&methodPointcut()”之前,argNames=“joinPoint”)
前公共无效(连接点连接点){
MethodSignature=(MethodSignature)joinPoint.getSignature();
对象[]args=joinPoint.getArgs();
字符串[]paramNames=signature.getParameterNames();
对于(int count=0;count

如您所见,这是一个非常基本且容易出错的代码段。是否有更好的解决方案???

不建议在控制器中使用AOP。更好的方法是,但这可能需要将字符串包装到值对象中,然后相应地对其进行注释

如果您坚持用AOP解决这个问题,

就像前面所说的那样,使用
Bean验证更可取

首先,定义一个从
org.springframework.validation.Validator
扩展而来的类,如下所示:

@Component
public class CodeAccountValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return String.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        if (Assert.isNotNull(target) && Assert.isNotEmpty((String) target)) {
            Assert.TRUE(((String) target).matches("^[0-9]{1,20}$"));
        }
    }
}

用AOP解决这个问题是不应该做的。而是使用对象绑定属性并验证该对象

public class QueryCriteria {
    private String codeAccount;
    private String searchFilter;
    private int pageNumber;
    private int pageSize;
    private String order;
    // Getters / Setters.
}
然后修改控制器方法

public QueryResult<TrsAccount> listExclude(@Valid QueryCriteria criteria, BIndingResult result) { ... }
在控制器方法的
@InitBinder
中注册此验证器

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.setValidator(new QueryCriteriaValidator());
}
当使用JSR-303时,您不需要这个,您可以简单地用
@模式
注释
codecomport
字段

@Pattern(regexp="^[0-9]{1,20}$")
private String codeAccount;
验证与SpringMVC以及使用I18N的错误报告一起工作得很好。因此,不要试图用异常来绕过它,而是使用框架


我建议您阅读和Spring参考指南

我怎样才能用ControllerAdvice做到这一点?谢谢,只是不要。。。使用对象并通过JSR303验证或自定义验证程序验证该对象。有趣,但
CodeAccountValidator
不起作用。参数
codeAccount
可以使用@RequestParam注释吗?可能,但这里没有。这有什么区别吗?请按照@M.Deinum所说的去做,这是一个标准的解决方案。我的需要一些更多的设置,你可以检查。
public QueryCriteriaValidator implements Validator {

    private final Pattern ACCOUNT_EXPR = Pattern.compile("^[0-9]{1,20}$");

    public boolean supports(Class<?> clazz) {
       return QueryCriteria.isAssignable(clazz);
    }

    public void validate(Object target, Errors errors) {
        final QueryCriteria criteria = (QueryCriteria) target;
        if (!ACCOUNT_EXPR.matcher(criteria.getCodeAccount()).matches()) {
            errors.rejectValue("codeAccount", "invalid.format");
        }
    }
}
@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.setValidator(new QueryCriteriaValidator());
}
@Pattern(regexp="^[0-9]{1,20}$")
private String codeAccount;