7

Spring MVC 3.x ではContentNegotiatingViewResolver、ファイル拡張子を.jsonまたは.xml. Grails にも同等の機能があると思いましたが、見つかりません。

私が読んだすべてのことは、受信した MIME タイプを ( を使用して) キャッチし、すべてのコントローラー メソッドで (または同等の方法で) withFormatJSON 出力を指定する必要があることを示しています (たとえば、Grails で JSON をレンダリングしますか? )。JSON固有のコードをコントローラーに追加する前に、ここで質問したいと思いました...render as JSON

私の質問は次のとおりです: 特定の URL に「.json」ファイル拡張子を追加する (または Accept ヘッダーを変更する) だけで、JSON 出力を自動的に生成するように Grails 2 を構成できますか?

4

3 に答える 3

7

grailsフィルターを使えば簡単にできると思います

これは、鉱山アプリケーションで OAuth API で行ったフィルターです。受け入れヘッダーに基づいて xml、json、および yalm を実行します。

class RenderFilters {

    def grailsApplication

    def filters = {

        multiFormat(controller: '*EndPoint', action: '*', search: true) {

            after = { Map model ->

                def accepts = request.getHeaders('accept')*.toLowerCase()

                def out = model.containsKey('out')?model.out:model

                if(accepts.any{ it.contains('json')  }){
                    render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
                }

                else if(accepts.any{ it.contains('yaml')  }){
                    render(text: Yaml.dump(out), contentType: 'application/x-yaml;', encoding:"UTF-8")
                }

                else if(accepts.any{ it.contains('html')  }){
                    render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
                }

                else if(accepts.any{ it.contains('xml')  }){
                    render(text: out as XML, contentType: 'application/xml', encoding:"UTF-8")
                }

                else {
                    render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
                }
                false
            }

            before = {

                def contentType = request.getHeader('Content-Type')?.toLowerCase()

                if(!contentType) return true

                if(contentType == 'application/json'){
                    params.body = JSON.parse(request.reader)                    
                    }
                if(contentType == 'application/xml'){
                    params.body = XML.parse(request.reader)
                    }
                if(contentType == 'application/x-yaml'){
                    params.body = Yaml.load(request.reader)
                    }

                params.body = new TypeConvertingMap((Map) params.body)              

                true
                }

        }

    }
}
于 2012-08-09T08:26:35.733 に答える
3

この SO の質問に出くわした人のために、Fabiano の回答 (上記) とは異なるため、最終的な Grails (バージョン 2.x) フィルター コードを含めると思いました。

次のフィルターを使用すると、プレーンな HTML コンテンツを Grails で通常どおり処理できるようになり、Grails コンテンツ ネゴシエーション メカニズムを使用しresponse.formatてファイル拡張子を設定したり、ヘッダーを受け入れたりすることができます (conf の設定に応じてgrails.mime.use.accept.header& grails.mime.file.extensions)。また、JSONP コールバック ラッパーのサポートも追加しました。

import grails.converters.JSON
import grails.converters.XML

class RenderFilters {

    def filters = {
        multiFormat(controller: '*', action: '*', find: true) {
            after = { Map model ->
                def out = model?.containsKey('out')?model.out:model

                if (response.format == "json" && params.callback) {
                    render(text: params.callback + "(${out as JSON})" , contentType: 'application/javascript', encoding:"UTF-8")
                    false
                } else if (response.format == "json") {
                    render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
                    false
                } else if (response.format == "xml") {
                    render(text: out as XML, contentType: 'application/xml', encoding:"UTF-8")
                    false
                }
            }
        }
    }
}
于 2012-08-13T04:13:02.953 に答える