2015-10-08 20 views
7

मेरे पास स्प्रिंग-बूट एप्लिकेशन में लिखा गया एक साधारण आरईएसटी नियंत्रक है, लेकिन मुझे यकीन नहीं है कि यह अनुरोध हेडर में सामग्री-प्रकार पैरामीटर के आधार पर JSON या XML को वापस करने के लिए सामग्री वार्ता को कैसे कार्यान्वित किया जाए । क्या कोई मुझे समझा सकता है, मैं गलत क्या कर रहा हूं?स्प्रिंग बूट कंट्रोलर सामग्री वार्ता

नियंत्रक विधि:

@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) 
    public Message getMessageXML(@RequestParam("text") String text) throws Exception { 
    Message message = new Message(); 
    message.setDate(new Date()); 
    message.setName("Test"); 
    message.setAge(99); 
    message.setMessage(text); 

    return message; 
    } 

जब इस विधि (भले ही मैं application/xml या text/xml होने की Content-Type उल्लेख करें) बुला मैं हमेशा JSON मिलता है।

जब मैं अलग-अलग मैपिंग और विभिन्न सामग्री प्रकार के साथ दो विधियों को लागू करता हूं, तो मैं एक्सएमएल से एक्सएमएल प्राप्त करने में सक्षम हूं लेकिन यह काम नहीं करता है अगर मैं एक विधि में दो मीडिया टाइप निर्दिष्ट करता हूं (जैसे प्रदान किया गया उदाहरण)।

मैं चाहते हैं क्या \message endpoint फोन और

  • एक्सएमएल प्राप्त करने के लिए जब GET अनुरोध की सामग्री प्रकार application/xml करने के लिए
  • JSON सेट किया गया है जब सामग्री प्रकार आवेदन है/जेसन

किसी भी मदद की सराहना की जाती है।

संपादित करें: मैं सभी मीडिया प्रकार

@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }, consumes = MediaType.ALL_VALUE) 
    public Message getMessageXML(@RequestParam("text") String text) throws Exception { 
    Message message = new Message(); 
    message.setDate(new Date()); 
    message.setName("Vladimir"); 
    message.setAge(35); 
    message.setMessage(text); 

    return message; 
    } 
+1

आपको मूल्य 'एप्लिकेशन/एक्सएमएल' या किसी भी समर्थित मीडिया प्रकार के साथ' स्वीकार करें 'शीर्षलेख प्रदान करने की आवश्यकता है। – systemfreund

+0

"सामग्री-प्रकार" शीर्षलेख परिभाषित करता है कि आप किस प्रकार की सामग्री भेज रहे हैं - जिसे आप प्राप्त नहीं करना चाहते हैं (यही वह है जिसे "स्वीकार करें" शीर्षलेख है। इसलिए GET अनुरोध के लिए "सामग्री-प्रकार" शीर्षलेख का उपयोग करना ' टी समझ में नहीं आता है, क्योंकि इसमें कोई भी (बॉडी) सामग्री नहीं हो सकती है। तो आपके मामले में आपको अपने अनुरोध के लिए "स्वीकार करें" शीर्षलेख का उपयोग करना चाहिए और "सामग्री-प्रकार" शीर्षलेख को उस सामग्री के प्रकार का नाम देने के लिए जवाब देना चाहिए जो कि है वास्तव में भेजें। –

उत्तर

9

स्वीकार करने के लिए मेरी नियंत्रक अद्यतन आप के बारे में सामग्री प्रकार अनुभाग के लिए 6.

वेतन ध्यान बिंदु पर ब्लॉग पोस्ट @RequestMapping with Produces and Consumes में कुछ संकेत मिल सकता है और हेडर स्वीकार करें:

साथ @RequestMapping का उत्पादन और खपत: हम हैडर सामग्री प्रकार का उपयोग करें और आर पता लगाने के लिए स्वीकार कर सकते हैं समकक्ष सामग्री और माइम संदेश क्या है जो प्रतिक्रिया में चाहता है। स्पष्टता के लिए, @RequestMapping वेरिएबल्स का उत्पादन और उपभोग करता है जहां हम अनुरोध सामग्री-प्रकार निर्दिष्ट कर सकते हैं कि किस विधि के लिए लागू किया जाएगा और प्रतिक्रिया सामग्री प्रकार। उदाहरण के लिए:

@RequestMapping(value="/method6", produces={"application/json","application/xml"}, consumes="text/html") 
@ResponseBody 
public String method6(){ 
    return "method6"; 
} 

विधि से ऊपर ही साथ पाठ/html के रूप में सामग्री प्रकार संदेश खपत करते हैं और प्रकार आवेदन/json और application/xml संदेशों का उत्पादन करने में सक्षम है सकते हैं।

तुम भी आप आने वाले संदेश प्रकार का पता लगाना और उत्पादन इसी संदेश

17

आप ContentNegotiationConfigurer

उपयोग कर सकते हैं (यह भी @ResponseBody एनोटेशन expoliting) की अनुमति देता है (ResponseEntity वस्तु का प्रयोग करके) this अलग दृष्टिकोण की कोशिश कर सकते

सबसे पहले, आप अपने विन्यास कक्षा में configureContentNegotiation विधि ओवरराइड करना चाहिए:

@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
    configurer.favorPathExtension(false). 
      favorParameter(true). 
      defaultContentType(MediaType.APPLICATION_JSON). 
      mediaType("xml", MediaType.APPLICATION_XML); 
    } 
} 

favorParameter(true) - पैरामीटर पर पथ अभिव्यक्तियों का समर्थन करने या हेडर स्वीकार करने में सक्षम बनाता है।

defaultContentType(MediaType.APPLICATION_JSON) - डिफ़ॉल्ट सामग्री प्रकार सेट करता है। इसका मतलब यह है कि यदि आप पथ अभिव्यक्ति नहीं पारित करते हैं तो वसंत जेएसओएन को प्रतिक्रिया के रूप में उत्पन्न करेगा।

mediaType("xml", MediaType.APPLICATION_XML) - एक्सएमएल के लिए पथ अभिव्यक्ति कुंजी सेट करता है।

अब अगर आप की तरह अपने नियंत्रक की घोषणा:

@Controller 
class AccountController { 

    @RequestMapping(value="/accounts", method=RequestMethod.GET) 
    @ResponseStatus(HttpStatus.OK) 
    public @ResponseBody List<Account> list(Model model, Principal principal) { 
     return accountManager.getAccounts(principal)); 
    } 
} 

और localhost:8080/app/accounts.json की तरह यह कुछ कहते हैं, तो वसंत प्रतिक्रिया के रूप में JSON उत्पन्न होगा। इसलिए यदि आप localhost:8080/app/accounts.xml पर कॉल करते हैं तो आपको XML प्रतिक्रिया

प्राप्त होगा आप इस here के बारे में अधिक जानकारी प्राप्त कर सकते हैं।

+2

डिफ़ॉल्ट सामग्री पर बस थोड़ा सा फुटनोट टाइप करें: [ब्राउज़र एक्सएमएल पसंद करते हैं जो स्वीकार करने वाले हेडर भेजते हैं] (https://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring- mvc.html) बाईपासिंग (मान लीजिए कि आप इसका उपयोग नहीं कर रहे हैं) स्वीकृति हेडर सामग्री के आपके ओवरराइड में किया जा सकता है बातचीत: 'configr.ignoreAcceptHeader (true)' –

+1

मुझे लगता है कि यहां एक मामूली गलती है - जिस तरह सेकंट्रोलर को काम करने का दावा करें, आपको पक्षपाती के बजाए पक्षपाथ एक्सटेंशन को सही होने के लिए सेट करना चाहिए। – user31415

+0

यह विशिष्ट यूआरआई के लिए किया जा सकता है? –