【问题标题】:Auto-convert snake case to camel case in Grails REST API?在 Grails REST API 中自动将蛇案例转换为骆驼案例?
【发布时间】:2016-07-04 18:09:26
【问题描述】:

在 Grails REST API 项目中,默认情况下,Grails 读取属性并以驼峰形式呈现属性 (camelCase)。然而,在许多流行的 REST API 中,参数的名称在蛇形情况下是标准化的 (snake_case)。我怎样才能最有效地在 Grails 中启用这种自动转换?

例如,在请求正文中,我想接受蛇形输入。

{
  "first_name": "John"
}

在响应正文中,我想发送蛇案例输出。

{
  "last_name": "Doe"
}

但我希望按照 Grails 中的 Groovy 约定,使用驼峰式大小写和 Groovy 的自动生成的 getter 和 setter 来简化我的域类。

class User {
    String firstName
    String lastName
}

而且我想避免更改我的 MongoDB 架构,其中 99% 的字段都使用 camelCase 命名。但是我确实看到至少in the MongoDB docs,首选是使用snake_case 命名MongoDB 字段。

【问题讨论】:

    标签: mongodb rest grails


    【解决方案1】:

    您可以使用https://github.com/google/gson 序列化/反序列化您的类,并设置字段命名策略:

    Gson gson = new GsonBuilder() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .create()

    这意味着您应该将请求/响应正文作为文本获取,而不是依赖 Grails 提供的自动 json 反序列化。

    另一个选项(至少对于您的响应)是注册自定义 JSON 编组器。您可以在 bootstrap.groovy 中执行此操作。在下面的示例代码中,我实现了一个标记接口,以便可以显式指定应该序列化为蛇形案例的对象。

    interface SnakeCase {
    }
    

    要导出为蛇形案例的域对象实现此接口

    class Person implements SnakeCase {
    
        String surname
        String firstName
        String middleNames
        String someOtherField
    
        static constraints = {
        }
    }
    

    然后在 bootstrap.groovy 中注册一个自定义 JSON 编组器

    class BootStrap {
    
        def grailsApplication
    
        def init = { servletContext ->
    
            JSON.registerObjectMarshaller(SnakeCase, { SnakeCase o ->
    
                def result = [:]
                if (grailsApplication.isDomainClass(o.class)) {
                    o.domainClass.persistentProperties.each { GrailsDomainClassProperty p ->
                       def name = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, p.name)
                        result[name] = o[p.name]
                    }
                } else {
                    o.properties.each {
                        def name = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, it.key as String)
                    result[name] = it.value
                    }
                }
    
                return result
    
            })
        }
    
        def destroy = {
        }
    }
    

    请注意,grails 域类和常规 POGO 类之间存在区别。您还可以添加黑/白名单机制,以更好地控制哪些属性被序列化。此示例使用 Guava CaseFormat 实用程序来执行实际的蛇形外壳

    注册此编组器后,只需在控制器方法中使用 JSON 格式化程序即可

    def ajaxListPeople() {
    
        def list = Person.list();
    
        render(list as JSON)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-30
      • 1970-01-01
      • 2022-06-11
      • 2020-02-10
      • 2020-05-03
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      相关资源
      最近更新 更多