java bean validator_关于java:使用Spring的Validator界面进行Bean验证中的自定义消息

我正在将Spring Boot 1.3.5与Rest Controllers一起使用,并且一切正常。

我还在官方文档中使用了Spring的验证示例技术(JSR-303 Bean验证API和Spring的验证器接口,我尝试了两者,并且遇到了相同的问题),并且验证工作正常,但是我无法配置自定义消息。

我已经配置了messages.properties文件,并且可以很好地访问此文件上的消息。但是,此验证似乎无法读取或访问通过Spring Boot自动配置的我的消息源(messages.properties)。

我可以直接通过@Autowired从控制器中注入的消息源对象访问消息(代码中有注释)。但是,Spring的验证器接口或JSR-303 Bean验证的绑定结果似乎无法访问MessageSource中加载的messages.properties。我得到的结果是我的错误有代码,但没有默认消息。

这是我的应用程序类:

@SpringBootApplication

@ImportResource({"classpath:security/cas-context.xml","classpath:security/cas-integration.xml",

"classpath:security/security.xml" })

@EnableAutoConfiguration(exclude = VelocityAutoConfiguration.class) // http://stackoverflow.com/questions/32067759/spring-boot-starter-cache-velocity-is-missing

public class Application extends SpringBootServletInitializer {

@Override

protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {

return application.sources(Application.class);

}

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

@Bean

public ServletRegistrationBean cxfServlet() {

return new ServletRegistrationBean(new CXFServlet(),"/services/*");

}

@Bean(name = Bus.DEFAULT_BUS_ID)

public SpringBus springBus() {

return new SpringBus();

}

@Bean

public Nfse nfseService() {

return new NfseImpl();

}

@Bean

public Endpoint endpoint() {

EndpointImpl endpoint = new EndpointImpl(springBus(), nfseService());

endpoint.publish("/nfseSOAP");

return endpoint;

}

}

这是我的豆子:

public class Protocolo {

private Long id;

@NotNull

@Min(1)

@Max(1)

private String protocolo;

private StatusProtocoloEnum status;

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public String getProtocolo() {

return protocolo;

}

public void setProtocolo(String protocolo) {

this.protocolo = protocolo;

}

public StatusProtocoloEnum getStatus() {

return status;

}

public void setStatus(StatusProtocoloEnum status) {

this.status = status;

}

}

这是我的休息控制器:

@RestController

public class ProtocoloController {

@Autowired

private MessageSource messageSource;

@Autowired

private ProtocoloDAO protocoloDAO;

@RequestMapping(value ="/prot", method = RequestMethod.POST)

public void testar(@Valid @RequestBody Protocolo p) {

Authentication auth = SecurityContextHolder.getContext().getAuthentication();

System.out.println(auth.getAuthorities());

System.out.println(messageSource.getMessage("protocolo.tamanho", null, null));

// IN THIS PART I'M ABLE TO PRINT THE MESSAGE IF VALIDATION IS DISABLED

System.out.println(p.getProtocolo());

}

}

因此,此代码可以正常工作,并且由于我使用无效的Protocolo调用该方法而未调用该方法。但是,我的angularJS客户端收到的响应中填充了错误代码,但所有默认消息为空,因为验证未看到加载的messages.properties。

有没有一种方法可以使我的Spring验证接口或JSR-303验证在Spring Boot中合并加载的message.properties(messagesource)?我该如何纠正?如果有必要,我也可以粘贴Spring Validation接口的代码示例。

非常感谢,

塔西奥(Tarcísio)。

测试代码:

@RestController

public class ProtocoloController {

@Autowired

private MessageSource messageSource;

@Autowired

private ProtocoloDAO protocoloDAO;

@RequestMapping(value ="/prot", method = RequestMethod.POST)

public void testar(@Valid @RequestBody Protocolo p, BindingResult bindingResult) {

System.out.println(messageSource.getMessage("Min.protocolo.protocolo", null, null));

if (bindingResult.hasErrors()) {

System.out.println(bindingResult.getFieldError().getDefaultMessage());

System.out.println(bindingResult.getFieldError().getCode());

}

System.out.println(p.getProtocolo());

}

}

编辑:

Spring Boot 1.5.3中的已知错误请参阅https://github.com/spring-projects/spring-boot/issues/8979

从1.5.3开始的Spring Boot中,您需要执行此操作

@Configuration

public class ValidationMessageConfig {

@Bean

public LocalValidatorFactoryBean mvcValidator(MessageSource messageSource) {

LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();

factory.setValidationMessageSource(messageSource);

return factory;

}

}

然后它将起作用。

在1.5.2版及之前的版本中,可以扩展WebMVcConfigurerAdapter

@Configuration

public class ProfileMvcConfig extends WebMvcConfigurerAdapter {

private MessageSource messageSource;

@Autowired

public ProfileMvcConfig(MessageSource messageSource) {

this.messageSource = messageSource;

}

/**

* This method is overridden due to use the {@link MessageSource message source} in bean validation.

*

* @return  A Validator using the {@link MessageSource message source} in bean validation.

*/

@Override

public Validator getValidator() {

LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();

factory.setValidationMessageSource(messageSource);

return factory;

}

}

另请参阅文档

这终于解决了我的问题。但是,即使我使用的是Spring boot 1.5.6.RELEASE,我也必须扩展WebMvcConfigurationSupport

我在Spring验证中的自定义消息中解决了此问题,请阅读答案的最后一部分。

也请检查此示例。

我使用了带有自定义注释的自定义验证器。我需要在自定义验证器中更改代码。

公共类PersonValidator实现ConstraintValidator {

@Override

public boolean isValid(final Person person, final ConstraintValidatorContext context) {

if (somethingIsInvalid()) {

context.disableDefaultConstraintViolation();

context.buildConstraintViolationWithTemplate("Something is invalid.").addConstraintViolation();

return false;

}

return true;

}

}

您应该在属性文件中具有以下值:

Min.protocolo.protocolo=Minimum value must be {1}

然后在控制器中,您可以通过从messageSource对象调用getMessage函数来获取消息

测试代码:

@RequestMapping(value ="/prot", method = RequestMethod.POST)

public void testar(@Valid @RequestBody Protocolo p, BindingResult bindingResult) {

if (bindingResult.hasErrors()) {

bindingResult.getFieldErrors().forEach(fieldError ->

System.out.println(messageSource.getMessage(fieldError, Locale.getDefault()))

);

}

System.out.println(p.getProtocolo());

}

在Spring Boot中,applicaton MessageSource配置了MessageSourceAutoConfiguration,您不需要对其自动布线。对于jsr303,请在messages.properties文件中创建正确的键值对。对于" protocolo"字段,属性文件中应具有以下值。

NotNull.protocolo.protocolo=Field cannot be left blank

Min.protocolo.protocolo=Minimum value must be {1}

您还可以在代码中检查来自属性文件的消息,如下所示。

public void testar(@Valid @RequestBody Protocolo p,BindingResult bindingResult) {

if(bindingResult.hasErrors()) {

System.out.println(bindingResult.getFieldError().getDefaultMessage());

}

}

我已经尝试过了,但是没有用。我做自动接线只是为了测试是否可以通过自动接线的消息源直接从控制器获取消息,并且这是可能的。仅通过JSR303执行的验证,我无法获得该消息。我会在客户端收到您发布的确切密钥:Min.protocolo.protocolo。但是,该消息为null,尽管已在messages.properties中指定了该消息。我的确缺少一些将验证JSR303或spring验证接口与spring boot配置的消息源连接的配置。

我编辑了答案,并为bindingResult添加了一些代码。可以请您检查一下吗?

非常感谢 !我用您建议的代码编辑了帖子。我还保留了自动连接的消息源只是为了进行测试。结果是,打印有由springboot生成的消息源并在控制器中自动布线的消息正是我在message.properties中自定义的消息:Min.protocolo.protocolo = my test。但是,在绑定结果中打印的消息是spring -JSR @Min的默认消息,尽管代码消息(我也在测试中使用默认消息打印出)也与通过自动连接消息源成功打印出的代码消息相同。

@abaghel我正在使用Spring Boot 1.5.2,并且有相同的问题,即获取有效的错误代码,但默认消息未被覆盖。有什么解决办法吗?

@abaghel这不起作用。我问了同样的问题,并尝试了所有组合。您可以发布工作代码来证明这一点吗? stackoverflow.com/questions/49499891/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值