3、需要国际化并自定义消息体
这种场景需要增加配置类指定国际化文件
private static Validator getValidator(String language) { Locale.setDefault(new Locale(language.contains("zh") ? "zh" : "en")); return Validation.byDefaultProvider().configure() //国际化文件配置 .messageInterpolator(new MyResourceBundleMessageInterpolator(new PlatformResourceBundleLocator("i18n/valid"))) .buildValidatorFactory() .getValidator(); }
java中properties配置文件默认的编码为:ISO-8859-1,是不支持中文的,所以会乱码,需要做转码:
public class MyResourceBundleMessageInterpolator extends ResourceBundleMessageInterpolator { public MyResourceBundleMessageInterpolator(ResourceBundleLocator userResourceBundleLocator) { super(userResourceBundleLocator); } @Override public String interpolate(String message, Context context) { String result = super.interpolate(message, context); try { return new String(result.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8); } catch (Exception e) { return result; } } }
修改实体类message为el表达式类型
public class Person { @NotBlank(message = "{person.name}") private String name; @Range(min = 2, max = 100, message = "{person.age}") private Integer age; }
在resouce下面增加国际化文件
使用Accept-Language来控制语言类型,调用接口效果:
3、SpringBoot工程
由于Jersey和普通SpringMVC不一样,所以不能传统的方式实现国际化, 如果不了解或者项目中没有使用Jersey,可以跳过此章节
实体类:
public class Person { @NotBlank() private String name; @Range(min = 2, max = 100) private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
资源类
@Component @Path("/test") public class TestResource { @Autowired private Validator validate; @POST @Path("/test") @Consumes({APPLICATION_JSON}) @Produces({APPLICATION_JSON}) public String test(Person person, @Context final HttpServletRequest request) { Set<ConstraintViolation<Person>> errorResults = validate.validate(person); if (!errorResults.isEmpty()) { StringJoiner message = new StringJoiner(";"); for (Object result : errorResults) { message.add(((ConstraintViolation) result).getMessage()); } return "{\"result\":\"" + message.toString() + "\"}"; } return "{\"result\":\"ok\"}"; }
1、只需要自定义消息体
这种场景只需要在实体类中修改message即可
public class Person { @NotBlank(message = "姓名不能为空") private String name; @Range(min = 2, max = 100, message = "年龄需要在2~100之间") private Integer age; }
调用接口会就会返回固定的信息:
2、只需要国际化
这种场景时使用hibernate-valid自带的国际化消息,使用Spring的i18n国际化规则
通过header中Accept-Language来控制语言类型。比如en-US,zh-CN
修改实体类
public class Person { @NotBlank() private String name; @Range(min = 2, max = 100) private Integer age; }
调用接口效果:
3、需要国际化并自定义消息体
这种场景需要增加配置类指定国际化文件
@Configuration public class MessageConfig { public MessageSource getMessageSource() throws Exception { ResourceBundleMessageSource rbms = new ResourceBundleMessageSource(); rbms.setDefaultEncoding(StandardCharsets.UTF_8.toString()); //指定国际化文件路径 rbms.setBasenames("i18n/valid"); return rbms; } @Bean public LocalValidatorFactoryBean getValidator() throws Exception { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setValidationMessageSource(getMessageSource()); return validator; } }
修改实体类message为el表达式类型:
public class Person { @NotBlank(message = "{person.name}") private String name; @Range(min = 2, max = 100, message = "{person.age}") private Integer age; }
在resouce下面增加国际化文件, 一定要注意文件编码格式要与配置中一致
通样通过Spring的国际化方式,使用Accept-Language来控制语言类型,调用接口效果:
小结
Hibernate-valid国际化相对来说还是比较麻烦,需要深入到源码才能了解如何配置,连官网都没有文档,难道有什么隐藏bug?哈哈
现在多学一样本事,将来就少说一句求人的话,你我皆加油