简体   繁体   English

SpringBoot验证bean方法的参数并返回

[英]SpringBoot validation of a bean method parameters and return

I can't make method level validation right. 我无法正确进行方法级验证。 Or I don't understand how it works. 或者我不明白它是如何工作的。

My application class is below. 我的应用程序类别如下。 Very simple. 很简单。 It contains MethodValidationPostProcessor bean definition. 它包含MethodValidationPostProcessor bean定义。 It also runs Greeter service. 它还运行Greeter服务。

@SpringBootApplication
public class App implements CommandLineRunner {
    private final Greeter greeter;

    public App(Greeter greeter) {
        this.greeter = greeter;
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder().main(App.class).sources(App.class).web(false).run(args).close();
    }

    @Bean
    public org.springframework.validation.beanvalidation.MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }

    @Override
    public void run(String... args) throws Exception {
        final Input input = new Input();
        input.setName("j");
        final String messageFromInput = greeter.getMessageFromInput(input);

        final String messageFromString = greeter.getMessageFromString("j");
    }
}

Greeter service below. 迎宾服务如下。 Here I do expect to validate input and output. 我确实希望在这里验证输入和输出。

@Service
@Validated
public class Greeter {
    String getMessageFromInput(@Valid @NotNull Input name) {
        return "[From Input] Greetings! Oh mighty " + name + "!";
    }

    String getMessageFromString(@Size(min = 4) String name) {
        return "[From String] Greetings! Oh mighty " + name + "!";
    }
}

Input DTO is very simple as well. 输入DTO也非常简单。

public class Input {
    @NotEmpty
    @Size(min = 3)
    private String name;

    // Getters, setters and toString ommited.
}

Since the name in both cases, direct String and DTO, is only one letter I expect this setup to throw exception. 由于两种情况下的名称(直接String和DTO)仅是一个字母,我希望此设置会引发异常。 Unfortunately, nothing happens and application completes successfully. 不幸的是,没有任何反应,并且应用程序成功完成。 It works with controller's methods. 它适用于控制器的方法。 But I would like it to work with any bean's methods. 但是我希望它可以与任何bean的方法一起使用。

You are injecting your Greeter bean as a constructor argument into the class annotated with @SpringBootApplication which is a @Configuration class. 您正在将Greeter bean作为构造函数参数注入到@SpringBootApplication注释的类中, @SpringBootApplication@Configuration类。 To satisfy that dependency the Greeter is created very early on in the startup process of the ApplicationContext and as such will remove it as a candidate for proxy creation. 为了满足这种依赖性,将在ApplicationContext的启动过程中尽早创建Greeter ,并因此将其删除作为代理创建的候选对象。

Instead of injecting it as a constructor argument move your CommandLineRunner logic to a @Bean annotated method and simply inject the Greeter as a dependency. 无需将其作为构造函数参数注入,而是将CommandLineRunner逻辑移至带有@Bean注释的方法,只需将Greeter作为依赖项注入即可。 This will delay the creation of the bean and as such make it available for proxying. 这将延迟Bean的创建,因此使其可用于代理。

@Bean
public CommandLineRunner runner(Greeter greeter) {
    return new CommandLineRunner() {

        @Override
        public void run(String... args) throws Exception {
            final Input input = new Input();
            input.setName("j");
            final String messageFromInput = greeter.getMessageFromInput(input);

            final String messageFromString = greeter.getMessageFromString("j");
        }
    };
}

Another thing is that your methods of the Greeter should be, due the the nature of proxies, public . 另一件事是,由于代理的性质,您使用Greeter的方法应该public

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM