这可能是你见过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以及国际化,在墙里墙外找了很多很久,可能是因为版本的更新迭代,找到的资料基本都用不了了。自己折腾了半天,终于琢磨出来了,特此记录。
1550 0
这可能是你见过hibernate-validator最全国际化方案(上)
|
7月前
|
SQL 缓存 Java
框架分析(9)-Hibernate
框架分析(9)-Hibernate
|
1月前
|
缓存 Java 数据库连接
Hibernate:Java持久层框架的高效应用
通过上述步骤,可以在Java项目中高效应用Hibernate框架,实现对关系数据库的透明持久化管理。Hibernate提供的强大功能和灵活配置,使得开发者能够专注于业务逻辑的实现,而不必过多关注底层数据库操作。
14 1
|
4月前
|
SQL Java 数据库连接
Hibernate 是一款开源 ORM(对象关系映射)框架,封装了 JDBC,允许以面向对象的方式操作数据库,简化了数据访问层的开发。
Hibernate 是一款开源 ORM(对象关系映射)框架,封装了 JDBC,允许以面向对象的方式操作数据库,简化了数据访问层的开发。通过映射机制,它可以自动处理对象与数据库表之间的转换,支持主流数据库,提高了代码的可移植性和可维护性。其核心接口包括 SessionFactory、Session 和 Transaction 等,通过它们可以执行数据库的 CRUD 操作。配置方面,需在项目中引入 Hibernate 及数据库驱动依赖,并创建 `hibernate.cfg.xml` 配置文件来设置数据库连接和 Hibernate 行为参数。
51 1
|
4月前
|
数据库 Java 数据库连接
Struts 2 与 Hibernate 的完美邂逅:如何无缝集成两大框架,轻松玩转高效 CRUD 操作?
【8月更文挑战第31天】本文通过具体示例介绍了如何在 Struts 2 中整合 Hibernate,实现基本的 CRUD 操作。首先创建 Maven 项目并添加相关依赖,接着配置 Hibernate 并定义实体类及其映射文件。然后创建 DAO 接口及实现类处理数据库操作,再通过 Struts 2 的 Action 类处理用户请求。最后配置 `struts.xml` 文件并创建 JSP 页面展示用户列表及编辑表单。此示例展示了如何配置和使用这两个框架,使代码更加模块化和可维护。
107 0
|
5月前
|
SQL Java 数据库连接
Java面试题:简述ORM框架(如Hibernate、MyBatis)的工作原理及其优缺点。
Java面试题:简述ORM框架(如Hibernate、MyBatis)的工作原理及其优缺点。
82 0
|
6月前
|
Java 数据库连接 数据库
探索JPA生态:Hibernate与其他ORM框架的对比分析
【6月更文挑战第25天】**JPA标准下的Hibernate是流行的ORM实现,提供丰富功能如二级缓存和延迟加载,但其学习曲线较陡,性能优化复杂。相比如MyBatis,Hibernate的JPQL更面向对象,MyBatis则接近SQL。选择ORM需考虑项目需求和个人偏好。**
90 0
|
6月前
|
Java 数据库连接
杨老师课堂之JavaEE三大框架Hibernate入门第一课
杨老师课堂之JavaEE三大框架Hibernate入门第一课
32 0
|
7月前
|
SQL Java 数据库连接
Java从入门到精通:3.1.2深入学习Java EE技术——Hibernate与MyBatis等ORM框架的掌握
Java从入门到精通:3.1.2深入学习Java EE技术——Hibernate与MyBatis等ORM框架的掌握
|
7月前
|
SQL Java 关系型数据库
数据库访问:什么是Hibernate框架?
【4月更文挑战第15天】Hibernate是开源ORM框架,将Java对象与数据库表映射,简化对象-关系映射,提升开发效率和性能。它自动化处理数据操作,支持多种数据库,自动生成SQL,提供配置选项和高级特性,减少手动SQL编写,便于切换数据库。
73 2