SpringBoot验证一个bean方法的参数和return
SpringBoot validation of a bean method parameters and return
我无法正确进行方法级别验证。或者我不明白它是如何工作的。
我的申请 class 如下。很简单的。它包含 MethodValidationPostProcessor
bean 定义。它还运行 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");
}
}
下面的迎宾服务。在这里我确实希望验证输入和输出。
@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 + "!";
}
}
输入DTO也很简单
public class Input {
@NotEmpty
@Size(min = 3)
private String name;
// Getters, setters and toString ommited.
}
由于这两种情况下的名称(直接字符串和 DTO)都只有一个字母,我希望此设置会引发异常。不幸的是,没有任何反应,应用程序成功完成。它适用于控制器的方法。但我希望它能与任何 bean 的方法一起使用。
您正在将 Greeter
bean 作为构造函数参数注入 class 并用 @SpringBootApplication
注释,这是一个 @Configuration
class。为了满足这种依赖性,Greeter
是在 ApplicationContext
的启动过程中很早就创建的,因此将删除它作为代理创建的候选者。
与其将其作为构造函数参数注入,不如将您的 CommandLineRunner
逻辑移至 @Bean
注释方法,并简单地将 Greeter
作为依赖项注入。这将延迟 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");
}
};
}
另一件事是,由于代理的性质,Greeter
的方法应该是 public
。
我无法正确进行方法级别验证。或者我不明白它是如何工作的。
我的申请 class 如下。很简单的。它包含 MethodValidationPostProcessor
bean 定义。它还运行 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");
}
}
下面的迎宾服务。在这里我确实希望验证输入和输出。
@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 + "!";
}
}
输入DTO也很简单
public class Input {
@NotEmpty
@Size(min = 3)
private String name;
// Getters, setters and toString ommited.
}
由于这两种情况下的名称(直接字符串和 DTO)都只有一个字母,我希望此设置会引发异常。不幸的是,没有任何反应,应用程序成功完成。它适用于控制器的方法。但我希望它能与任何 bean 的方法一起使用。
您正在将 Greeter
bean 作为构造函数参数注入 class 并用 @SpringBootApplication
注释,这是一个 @Configuration
class。为了满足这种依赖性,Greeter
是在 ApplicationContext
的启动过程中很早就创建的,因此将删除它作为代理创建的候选者。
与其将其作为构造函数参数注入,不如将您的 CommandLineRunner
逻辑移至 @Bean
注释方法,并简单地将 Greeter
作为依赖项注入。这将延迟 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");
}
};
}
另一件事是,由于代理的性质,Greeter
的方法应该是 public
。