2016-07-04 26 views
0

在Grails REST API項目中,默認情況下,Grails會讀取屬性並呈現屬性(假設爲駝峯大小寫)(camelCase)。但是,在許多流行的REST API中,參數的名稱是在蛇情況下標準化的(snake_case)。如何在Grails中最有效地啓用此自動轉換?在Grails REST API中將蛇情況自動轉換爲駱駝情況?

例如,在請求正文中,我想接受蛇情況輸入。

{ 
    "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字段。

回答

0

您可以使用https://github.com/google/gson序列化/反序列化類,並設置字段命名策略:

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

這意味着你應該把你的請求/響應機構爲文本,而不是依靠Grails提供的automagic 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類之間。您還可以添加黑/白名單機制,以更好地控制哪些屬性被序列化。本例使用番石榴CaseFormat實用程序來執行實際的蛇殼

一旦編組已被註冊,它只是一個在你的控制器方法使用JSON格式的事

def ajaxListPeople() { 

    def list = Person.list(); 

    render(list as JSON) 
} 
相關問題