这可能是你见过hibernate-validator最全国际化方案(下)

简介: 为了实现hibernate-validator国际化差点要了老命,最近在研究hibernate-validator以及国际化,在墙里墙外找了很多很久,可能是因为版本的更新迭代,找到的资料基本都用不了了。自己折腾了半天,终于琢磨出来了,特此记录。

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下面增加国际化文件

image.png


使用Accept-Language来控制语言类型,调用接口效果:


image.png


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;
}

调用接口会就会返回固定的信息:

image.png


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;
}


调用接口效果:


image.png


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下面增加国际化文件, 一定要注意文件编码格式要与配置中一致


image.png


通样通过Spring的国际化方式,使用Accept-Language来控制语言类型,调用接口效果:


image.png

小结


Hibernate-valid国际化相对来说还是比较麻烦,需要深入到源码才能了解如何配置,连官网都没有文档,难道有什么隐藏bug?哈哈

现在多学一样本事,将来就少说一句求人的话,你我皆加油

相关文章
|
开发框架 Java 数据库连接
这可能是你见过hibernate-validator最全国际化方案(上)
为了实现hibernate-validator国际化差点要了老命,最近在研究hibernate-validator以及国际化,在墙里墙外找了很多很久,可能是因为版本的更新迭代,找到的资料基本都用不了了。自己折腾了半天,终于琢磨出来了,特此记录。
1216 0
这可能是你见过hibernate-validator最全国际化方案(上)
|
6天前
|
SQL 缓存 Java
框架分析(9)-Hibernate
框架分析(9)-Hibernate
|
6天前
|
SQL 缓存 Java
Java一分钟之-Hibernate:ORM框架实践
【5月更文挑战第15天】Hibernate是Java的ORM框架,简化数据库操作。本文列举并解决了一些常见问题: 1. 配置SessionFactory,检查数据库连接和JDBC驱动。 2. 实体类需标记主键,属性映射应匹配数据库列。 3. 使用事务管理Session,记得关闭。 4. CRUD操作时注意对象状态和查询结果转换。 5. 使用正确HQL语法,防止SQL注入。 6. 根据需求配置缓存。 7. 懒加载需在事务内处理,避免`LazyInitializationException`。理解和避免这些问题能提升开发效率。
25 0
|
6天前
|
SQL Java 数据库连接
Java从入门到精通:3.1.2深入学习Java EE技术——Hibernate与MyBatis等ORM框架的掌握
Java从入门到精通:3.1.2深入学习Java EE技术——Hibernate与MyBatis等ORM框架的掌握
|
6天前
|
SQL Java 关系型数据库
数据库访问:什么是Hibernate框架?
【4月更文挑战第15天】Hibernate是开源ORM框架,将Java对象与数据库表映射,简化对象-关系映射,提升开发效率和性能。它自动化处理数据操作,支持多种数据库,自动生成SQL,提供配置选项和高级特性,减少手动SQL编写,便于切换数据库。
26 2
|
10月前
|
SQL XML 存储
Hibernate框架【五】——基本映射——多对多映射
Hibernate框架【五】——基本映射——多对多映射
135 0
|
8月前
|
Java 数据库连接
简述使用Hibernate框架的几个步骤
简述使用Hibernate框架的几个步骤
41 0
|
9月前
|
SQL Java 关系型数据库
Hibernate框架概述
Hibernate框架概述
81 0
|
10月前
|
SQL 缓存 Oracle
Hibernate框架【一】——HIbernate框架介绍
Hibernate框架【一】——HIbernate框架介绍
183 0
|
10月前
|
SQL XML Java
Hibernate框架【四】——基本映射——多对一和一对多映射
Hibernate框架【四】——基本映射——多对一和一对多映射
109 0