2015-05-15 9 views
12

के साथ प्रतिक्रिया करता है मैं एक Grails REST नियंत्रक लिखने की कोशिश कर रहा हूं जिसे हमेशा JSON के साथ जवाब देना चाहिए। नियंत्रक नीचे दिखाया गया है:Grails REST नियंत्रक गलत सामग्री प्रकार

class TimelineController { 

    static allowedMethods = [index: "GET"] 
    static responseFormats = ['json'] 

    TimelineService timelineService 

    def index(TimeLineCommand command) { 
     List<TimelineItem> timeline = timelineService.currentUserTimeline(command) 
     respond timeline 
    } 
} 

मैं respond तरीका है जिसके Grails 'बाकी समर्थन का हिस्सा है का उपयोग कर रहा है, तो सामग्री बातचीत पता लगाने की प्रतिक्रिया किस प्रकार प्रस्तुत करना करने के लिए प्रयोग किया जाता है। इस विशेष मामले में मैं JSON चुना जाना उम्मीद होती है क्योंकि नियंत्रक निर्दिष्ट करता

static responseFormats = ['json'] 

इसके अलावा मैं लिखा है (और पंजीकृत वसंत के साथ) निम्नलिखित रेंडरर JSON कि List<TimelineItem>

के लिए दिया जाता है का स्वरूप अनुकूलित करने के लिए
class TimelineRenderer implements ContainerRenderer<List, TimelineItem> { 

    @Override 
    Class<List> getTargetType() { 
     List 
    } 

    @Override 
    Class<TimelineItem> getComponentType() { 
     TimelineItem 
    } 

    @Override 
    void render(List timeline, RenderContext context) { 

     context.contentType = MimeType.JSON.name 
     def builder = new JsonBuilder() 

     builder.call(
      [items: timeline.collect { TimelineItem timelineItem -> 

       def domainInstance = timelineItem.item 

       return [ 
         date: timelineItem.date, 
         type: domainInstance.class.simpleName, 
         item: [ 
           id : domainInstance.id, 
           value: domainInstance.toString() 
         ] 
       ] 
      }] 
     ) 

     builder.writeTo(context.writer) 
    } 

    @Override 
    MimeType[] getMimeTypes() { 
     [MimeType.JSON] as MimeType[] 
    } 
} 

मैं कुछ कार्यात्मक परीक्षण लिखा है, और देख सकते हैं कि ऐसा होने पर मेरा रेंडरर शुरू हो जाती है, हल हो गई सामग्री प्रकार text/html है, इसलिए नियंत्रक एक 404 देता है क्योंकि यह उम्मीद नाम के साथ एक जीएसपी नहीं मिल रहा।

मैं दृढ़ता से संदेह समस्या एक कस्टम रेंडरर के उपयोग से संबंधित है, क्योंकि मैं एक और लगभग समान नियंत्रक जो एक कस्टम रेंडरर का उपयोग नहीं करता है और इसे सही ढंग से सामग्री प्रकार हल करता है।

+1

'स्वीकार करें' हेडर सेट 'एप्लिकेशन/जेसन'' है? – dmahapatro

+0

@dmahapatro मैं सामग्री संकल्प के लिए 'स्वीकार करें' शीर्षलेख का उपयोग नहीं करना चाहता, मैं ** हमेशा ** JSON वापस करना चाहता हूं। मैंने सोचा कि नियंत्रक को 'स्थिर प्रतिक्रिया Formats = ['json'] 'जोड़ना चाहिए यह –

+0

यह सुनिश्चित करना चाहिए कि आप वास्तव में' प्रतिक्रिया 'का उपयोग क्यों करना चाहते हैं? जब आप विभिन्न माइम प्रकारों का उपयोग नहीं करते हैं, तो आप 'प्रतिक्रिया' विधि से छुटकारा पा सकते हैं, और 'myList को JSON' के रूप में प्रस्तुत करना' का उपयोग कर सकते हैं? –

उत्तर

0
  1. Config.groovy में, grails.mime.types निर्दिष्ट करने की आवश्यकता है। विवरण यहां पाया जा सकता है: Grails 2.3.11 Content Negotiation। कम से कम आप Config.groovy में एक निम्न होना चाहिए:

    grails.mime.types = [ 
        json: ['application/json', 'text/json'] 
    ] 
    
  2. आपको कस्टमाइज़ JSON के साथ जवाब चाहते हैं, render someMap as JSON सिफारिश की है।

  3. आपकी 404 समस्या के बारे में, आपको अपने नियंत्रक कार्रवाई में response.setContentType('application/json') करना होगा। Grails 'डिफ़ॉल्ट प्रतिक्रिया प्रारूप HTML है, ताकि सामग्री टाइप निर्दिष्ट नहीं होने पर यह gsp फ़ाइल को प्रस्तुत करने के लिए देखेगा।

+0

1. मेरे पास पहले से ही यह है 'Config.groovy' –

+0

2. यदि मैं कुछ मैप प्रस्तुत करता हूं के रूप में JSON' तो डिफ़ॉल्ट JSON प्रतिपादन इस्तेमाल किया जाएगा, यानी 'TimelineRenderer' लागू किया जा नहीं होगा –

+0

3. मैं सामग्री प्रकार शीर्ष लेख निर्धारित करने की आवश्यकता नहीं होनी चाहिए, Grails 'सामग्री संकल्प JSON का चयन करना चाहिए' पर स्थिर responseFormats = आधारित [' जेसन '] ' –

6

ऐसा लगता है कि एक खाली (कम से कम) index.gsp

तहत
grails-app/views/timeline/ 

बनाने के लिए रेंडरर काम करने के लिए किया है। मैं सफलतापूर्वक वापस सामग्री प्रकार वापस प्राप्त कर रहा हूं application/json

यह व्यवहार मुझे बहुत परेशान करता है और मैं अभी भी इसमें देख रहा हूं। यह एक जिरा मुद्दे के लायक है। यदि आपको आवश्यकता है तो मैं अपने डमी ऐप को जिथब पर धक्का दे सकता हूं।

अद्यतन:
अंक (लिंक के साथ नमूने के लिए एप्लिकेशन) GitHub में बनाया।
https://github.com/grails/grails-core/issues/716

+0

हां, अगर आप अपने डमी ऐप को गिटहब पर दबा सकते हैं और/या एक जेरा बढ़ा सकते हैं जो बहुत उपयोगी होगा। खुद को कुछ शोध करने के बाद, मुझे संदेह हो रहा है कि एक प्रकार के लिए कंटेनर रेंडरर संभव नहीं है, जब तक कि आपके पास उस प्रकार के लिए एक व्यक्तिगत रेंडरर न हो। हालांकि, दस्तावेज़ इसका उल्लेख नहीं करते हैं, और मुझे कोई तर्कसंगत कारण नहीं दिख रहा है कि यह मामला क्यों होना चाहिए, इसलिए मैं मानता हूं कि यह एक जिरा के लायक है। –

+0

अनुप्रयोग क्या सवाल में चित्रित किया जा रहा है के समान है। यहां गितब में समस्या है। https://github.com/grails/grails-core/issues/716 JIRA मुद्दा और डेमो एप्लिकेशन पर – dmahapatro

+1

अच्छा काम, मैं इस मुद्दे के लिए एक टिप्पणी जोड़ दिया है –

संबंधित मुद्दे