当前位置: 首页 > 知识库问答 >
问题:

Java约束验证不适用于参数[重复]

缪成天
2023-03-14

我希望对spring服务的参数使用java bean验证注释。考虑以下服务:

public interface MyService {

    void methodA();


    void methodB(@NotBlank String param)
}
@Validated
public class MyServiceImpl implements MyService {

    @Override
    public void methodA() {
        String param = "";
        methodB(param)
    }

    @Override
    public void methodB(@NotBlank String param) {
        // some logic
    }
}
@Autowired
MyService myService;

myService.methodB("");

共有1个答案

臧梓
2023-03-14

除了其他答案和您知道AOP代理存在的事实之外,让我指出Spring文档中的相关章节,其中提到了您遇到的AOP代理的自调用问题:

public class Main {

    public static void main(String[] args) {
        ProxyFactory factory = new ProxyFactory(new SimplePojo());
        factory.addInterface(Pojo.class);
        factory.addAdvice(new RetryAdvice());

        Pojo pojo = (Pojo) factory.getProxy();
        // this is a method call on the proxy!
        pojo.foo();
    }
}

fun main() {
    val factory = ProxyFactory(SimplePojo())
    factory.addInterface(Pojo::class.java)
    factory.addAdvice(RetryAdvice())

    val pojo = factory.proxy as Pojo
    // this is a method call on the proxy!
    pojo.foo()
}

这里需要理解的关键是,main类的main(..)方法中的客户端代码有一个对代理的引用。这意味着对该对象引用的方法调用就是对代理的调用。因此,代理可以委托给与该特定方法调用相关的所有拦截器(通知)。但是,一旦调用最终到达目标对象(SimplePojo,在本例中是引用),它可能对自身进行的任何方法调用,例如this.bar()this.foo(),都将针对this引用而不是代理调用。这具有重要的含义。这意味着自调用不会导致与方法调用相关联的通知有机会执行。

--https://docs.spring.io/spring/docs/5.2.3.release/spring-framework-reference/core.html#AOP-remonition-AOP-proxies

在下一段中,我们提出了两个解决方案(或者实际上是三个,但是在这个特定的情况下切换到AspectJ可能会很麻烦):

好吧,那该怎么办?最好的方法(术语“best”在这里使用得很松散)是重构代码,这样就不会发生自调用。这确实需要你做一些工作,但这是最好的,侵入性最小的方法。下一种方法绝对是可怕的,我们不愿指出它,正是因为它是如此可怕。您可以将类中的逻辑完全绑定到Spring AOP,如下例所示:

public class SimplePojo implements Pojo {

    public void foo() {
        // this works, but... gah!
        ((Pojo) AopContext.currentProxy()).bar();
    }

    public void bar() {
        // some logic...
    }
}

class SimplePojo : Pojo {

    fun foo() {
        // this works, but... gah!
        (AopContext.currentProxy() as Pojo).bar()
    }

    fun bar() {
        // some logic...
    }
}

这完全将您的代码与Spring AOP结合起来,并使类本身意识到它是在AOP上下文中使用的,这与AOP背道而驰。在创建代理时,它还需要一些额外的配置,如下例所示:

public class Main {

    public static void main(String[] args) {
        ProxyFactory factory = new ProxyFactory(new SimplePojo());
        factory.addInterface(Pojo.class);
        factory.addAdvice(new RetryAdvice());
        factory.setExposeProxy(true);

        Pojo pojo = (Pojo) factory.getProxy();
        // this is a method call on the proxy!
        pojo.foo();
    }
}

fun main() {
    val factory = ProxyFactory(SimplePojo())
    factory.addInterface(Pojo::class.java)
    factory.addAdvice(RetryAdvice())
    factory.isExposeProxy = true

    val pojo = factory.proxy as Pojo
    // this is a method call on the proxy!
    pojo.foo()
}

最后,必须注意,AspectJ没有这种自调用问题,因为它不是一个基于代理的AOP框架。

--https://docs.spring.io/spring/docs/5.2.3.release/spring-framework-reference/core.html#AOP-remonition-AOP-proxies

 类似资料:
  • 我目前正在尝试使用HiberNate Validator实现一些方法约束验证。我已经定义了 方法的参数约束 方法的返回值约束 构造函数的参数约束 构造函数的返回值约束 使用ExecutableValidator接口的手动验证(如Hibernate Validator文档中所述)非常适合1。-4. 与Spring的集成基本上是用@Validated注释bean。当我试图用@Validated在Spr

  • 每个人 因此,我有一个SpringBoot应用程序,它带有一个控制器,该控制器有几种方法,将以下POJO作为参数: 对于其中一个控制器endpoint,我想应用额外的验证逻辑,因此在我添加了以下内容: 是我想要应用的约束注释。 我的问题是,只有在中定义的检查成功通过时,才会调用此附加约束。如果为空,约束将被忽略,客户端将收到不完整的验证结果。我错过了什么?

  • 我计划使用API中的 波姆。xml 位置检查。JAVA 位置验证器。JAVA 位置JAVA 机器人。JAVA 一个pp.java 这里的问题是,上的

  • 我有一个用Java验证注释注释的模型对象。 根据业务需求,将填充文件名或小时字段,以验证我编写的自定义验证器“CriteriaValidator”。 上面的模型作为方法的输入参数传入,该方法也用@Valid和@ValidCriteria注释。 我的问题是方法中的2个注释。我必须添加@Valid才能检查类中注释的约束。我的自定义验证器仅检查两个字段之一的存在:文件名或小时。 我的问题是,如何使用单个

  • 我有一个bean验证,根据: 在我的小面我有: 当我有这个时,它可以正常工作,只是将显示所有字段ID的所有消息。我想为每个字段指定,如下所示: 然而,当我添加for=“km”选项时,不会显示任何验证消息。我错过了什么还是一个错误? 顺致敬意,

  • 我有一个像下面这样的模型对象,带有自定义约束验证器。自定义验证器检查是否填充了fileName或小时。 有一种方法将此作为输入,它验证所有以下条件 > 条件不为空(通过默认验证器) criteria.id不为空(通过默认验证器) criteria.name不为空(通过默认验证器) 标准文件名或小时不为空(通过自定义验证器) 空评估(@NotNull@有效标准标准){} 现在,当我为这个模型类编写单