2015-02-21 7 views
52

मैं एक विधि है कि निम्नलिखित तरीके से टिप्पणी की जाती है है:वसंत @ResponseBody एनोटेशन इस रीस्टफुल एप्लिकेशन उदाहरण में कैसे काम करता है?

/** 
* Provide a list of all accounts. 
*/ 
// TODO 02: Complete this method. Add annotations to respond 
// to GET /accounts and return a List<Account> to be converted. 
// Save your work and restart the server. You should get JSON results when accessing 
// http://localhost:8080/rest-ws/app/accounts 
@RequestMapping(value="/orders", method=RequestMethod.GET) 
public @ResponseBody List<Account> accountSummary() { 
    return accountManager.getAllAccounts(); 
} 

तो मुझे पता है कि यह व्याख्या द्वारा:

@RequestMapping(value="/orders", method=RequestMethod.GET) 

इस विधि प्राप्त HTTP संसाधन द्वारा प्रतिनिधित्व करने के लिए बनाया अनुरोधों को हैंडल यूआरएल /ऑर्डर

यह विधि एक डीएओ ऑब्जेक्ट को कॉल करती है जो सूची देता है।

जहां खाता सिस्टम पर एक उपयोगकर्ता की तरह कुछ का प्रतिनिधित्व करता है और कुछ क्षेत्रों है कि इस उपयोगकर्ता का प्रतिनिधित्व करते हैं,:

public class Account { 

    @Id 
    @Column(name = "ID") 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private Long entityId; 

    @Column(name = "NUMBER") 
    private String number; 

    @Column(name = "NAME") 
    private String name; 

    @OneToMany(cascade=CascadeType.ALL) 
    @JoinColumn(name = "ACCOUNT_ID") 
    private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>(); 

    ............................... 
    ............................... 
    ............................... 
} 

मेरा प्रश्न है: वास्तव में किस प्रकार @ResponseBody एनोटेशन काम करता है?

यह List<Account> ऑब्जेक्ट से पहले स्थित है, इसलिए मुझे लगता है कि यह इस सूची को संदर्भित करता है। पाठ्यक्रम प्रलेखन कहा गया है कि यह व्याख्या करने के लिए कार्य करती है:

सुनिश्चित करना है कि परिणाम एक HTTP संदेश कनवर्टर (एक MVC देखें के बजाय) द्वारा HTTP प्रतिसाद करने के लिए लिखा जाएगा।

और यह भी आधिकारिक स्प्रिंग प्रलेखन पर पढ़ने: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html

ऐसा लगता है कि यह List<Account> वस्तु लेता है और यह Http Response में डालता है। क्या यह सही है या क्या मैं गलतफहमी कर रहा हूं?

पिछले accountSummary() विधि की टिप्पणी में लिखा है:

जब http://localhost:8080/rest-ws/app/accounts

तो वास्तव में इसका क्या मतलब है तक पहुँचने आप JSON परिणाम प्राप्त करना चाहिए? क्या इसका मतलब यह है कि ऑब्जेक्ट accountSummary() विधि द्वारा लौटाया गया ऑब्जेक्ट स्वचालित रूप से JSON प्रारूप में परिवर्तित हो गया है और फिर Http Response पर रखा गया है? और क्या?

यदि यह दावा सत्य है, तो यह निर्दिष्ट किया गया है कि ऑब्जेक्ट स्वचालित रूप से JSON स्वरूप में परिवर्तित हो जाएगा? क्या मानक प्रारूप अपनाया गया है जब @ResponseBody एनोटेशन का उपयोग किया जाता है या यह कहीं और निर्दिष्ट है?

उत्तर

98

सबसे पहले, एनोटेशन List को एनोटेट नहीं करता है। यह विधि को एनोटेट करता है, जैसे RequestMapping करता है। आपका कोड

@RequestMapping(value="/orders", method=RequestMethod.GET) 
@ResponseBody 
public List<Account> accountSummary() { 
    return accountManager.getAllAccounts(); 
} 

के बराबर है अब क्या एनोटेशन मतलब है कि प्रणाली के दिए गए मान HTTP प्रतिक्रिया के शरीर का गठन होगा। बेशक, एक HTTP प्रतिक्रिया में जावा ऑब्जेक्ट्स नहीं हो सकते हैं। इसलिए खातों की यह सूची आरईएसटी अनुप्रयोगों, आमतौर पर जेएसओएन या एक्सएमएल के लिए उपयुक्त प्रारूप में परिवर्तित हो जाती है।

प्रारूप की पसंद अनुरोध संदेश कनवर्टर्स पर produces attribute के मान पर, अनुरोध मैपिंग एनोटेशन के मानों पर निर्भर करता है, और जिस सामग्री प्रकार क्लाइंट स्वीकार करता है (जो HTTP अनुरोध शीर्षलेख में उपलब्ध है) पर निर्भर करता है।उदाहरण के लिए, यदि अनुरोध कहता है कि यह एक्सएमएल स्वीकार करता है, लेकिन जेएसओएन नहीं है, और एक संदेश कनवर्टर स्थापित है जो सूची को एक्सएमएल में बदल सकता है, तो एक्सएमएल वापस कर दिया जाएगा।

+1

हाय, हम "स्थापित संदेश कन्वर्टर्स" कैसे सेट अप करते हैं? मैं चाहता हूं कि डिफ़ॉल्ट हमेशा जेसन में परिवर्तित हो जाए। क्या मैं ऐसा करने में सक्षम हूं? – GMsoF

+0

@ जेबी निजेट क्या आप कृपया बता सकते हैं कि http प्रतिक्रिया में जावा ऑब्जेक्ट्स क्यों नहीं हो सकते हैं। मैं जावा के लिए एक नौसिखिया हूँ। –

+2

@ Er.NavedAli http विनिर्देश पढ़ें, http प्रतिक्रिया सामग्री प्रकार उस कानूनी सामग्री को परिभाषित करता है जिसमें http प्रतिक्रिया हो सकती है। इसके लिए कानूनी मान "एप्लिकेशन/ऑक्टेट-स्ट्रीम", "छवि/जेपीईजी", "टेक्स्ट/एचटीएमएल" हो सकते हैं, लेकिन जावा ऑब्जेक्ट्स इसके लिए कानूनी मान नहीं है। – ZhaoGang

33

समझने वाली पहली मूल बात आर्किटेक्चर में अंतर है।

एक सिरा आप MVC वास्तुकला, जो अपने सामान्य वेब अनुप्रयोग पर आधारित है, वेब पेज का उपयोग कर, और ब्राउज़र एक पृष्ठ के लिए अनुरोध करता है:

Browser <---> Controller <---> Model 
       |  | 
       +-View-+ 

ब्राउज़र एक अनुरोध करता है, नियंत्रक (@ कंट्रोलर) मॉडल (@Entity) प्राप्त करता है, और मॉडल से दृश्य (जेएसपी) बनाता है और दृश्य वापस ग्राहक को वापस कर दिया जाता है। यह मूल वेब ऐप आर्किटेक्चर है।

दूसरी तरफ, आपके पास एक शानदार वास्तुकला है। इस मामले में, कोई दृश्य नहीं है। नियंत्रक केवल मॉडल (या संसाधन प्रतिनिधित्व, अधिक विश्वसनीय शब्दों में) वापस भेजता है। ग्राहक एक जावास्क्रिप्ट एप्लिकेशन, जावा सर्वर एप्लिकेशन, कोई भी एप्लिकेशन हो सकता है जिसमें हम अपने आरईएसटी एपीआई का पर्दाफाश करते हैं। इस वास्तुकला के साथ, ग्राहक तय करता है कि इस मॉडल के साथ क्या करना है। उदाहरण के लिए ट्विटर ले लो। ट्विटर के रूप में वेब (आरईएसटी) एपीआई, जो हमारे अनुप्रयोगों को स्टेटस अपडेट जैसी चीजों को प्राप्त करने के लिए अपने एपीआई का उपयोग करने की अनुमति देता है, ताकि हम इसका उपयोग उस एप्लिकेशन को हमारे एप्लिकेशन में रखने के लिए कर सकें। वह डेटा जेएसओएन जैसे कुछ प्रारूप में आएगा।

कहा जा रहा है कि, स्प्रिंग एमवीसी के साथ काम करते समय, इसे सबसे पहले मूल वेब अनुप्रयोग आर्किटेक्चर को संभालने के लिए बनाया गया था। अलग-अलग विधि हस्ताक्षर स्वाद हो सकते हैं जो हमारे तरीकों से देखने के लिए अनुमति देते हैं। विधि ModelAndView लौटा सकती है जहां हम इसे स्पष्ट रूप से बनाते हैं, या ऐसे कई तरीके हैं जहां हम कुछ मनमानी ऑब्जेक्ट को वापस कर सकते हैं जो मॉडल विशेषताओं में सेट हो जाते हैं। लेकिन किसी भी तरह से, अनुरोध-प्रतिक्रिया चक्र के साथ कहीं, एक दृश्य बनाया जाएगा।

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

@RequestMapping(..., produces = MediaType.APPLICATION_JSON_VALUE) 

सामग्री प्रकार सेट करने के लिए उपयोग करता है, लेकिन शायद JSON डिफ़ॉल्ट है। मुझे उद्धृत न करें, लेकिन अगर आपको JSON मिल रहा है, और आपने produces निर्दिष्ट नहीं किया है, तो हो सकता है कि यह डिफ़ॉल्ट हो। जेएसओएन एकमात्र प्रारूप नहीं है। उदाहरण के लिए, उपर्युक्त एक्सएमएल में आसानी से भेजा जा सकता है, लेकिन आपको producesMediaType.APPLICATION_XML_VALUE पर होना चाहिए और मुझे विश्वास है कि आपको JAXB के लिए HttpMessageConverter कॉन्फ़िगर करने की आवश्यकता है। JSON MappingJacksonHttpMessageConverter कॉन्फ़िगर करने के लिए, जब हमारे पास क्लासपाथ पर जैक्सन है।

मुझे Content Negotiation के बारे में जानने के लिए कुछ समय लगेगा। यह आरईएसटी का एक बहुत ही महत्वपूर्ण हिस्सा है। यह आपको विभिन्न प्रतिक्रिया प्रारूपों और उन्हें अपने तरीकों से मानचित्रित करने के तरीके के बारे में जानने में मदद करेगा।

+0

अगर आपका जवाब पाया, जबकि कैसे एक सामान्य/गतिशील बाकी नियंत्रक बनाने के लिए, का उपयोग करते हुए '@ नियंत्रक/@ RestController' बिना पर जांच। मैंने पाया, कि मुझे किसी भी तरह से दृश्य रिज़ॉलर परत को छोड़ने की जरूरत है। यह इतना आसान नहीं है क्योंकि सार नियंत्रक वर्ग एक विधि प्रदान करता है जिसे दृश्य नाम वापस करना होगा। मैंने इसके बारे में एक प्रश्न पूछा: http://stackoverflow.com/questions/41016018/custom-controller-without-view-name, अगर आपके पास कुछ समस्याएं हैं कि मैं अपनी समस्या का समाधान कैसे कर सकता हूं, तो कृपया एक टिप्पणी पोस्ट करें। – nowszy94

1

यह करने के लिए इसके अलावा, वापसी प्रकार से

  1. निर्धारित किया जाता है क्या HTTP अनुरोध यह चाहती है - अपने हैडर स्वीकार में। प्रारंभिक अनुरोध को देखने का प्रयास करें कि यह देखने के लिए कि क्या स्वीकार्य सेट है।

  2. क्या HttpMessageConverters वसंत सेट अप करता है। स्प्रिंग एमवीसी एक्सएमएल (जेएक्सबी का उपयोग करके) और जेएसओएन के लिए कनवर्टर्स सेट करेगा यदि जैक्सन लाइब्रेरी क्लासपाथ पर हैं।

यदि कोई विकल्प है तो यह एक चुनता है - इस उदाहरण में, यह JSON होता है।

यह पाठ्यक्रम नोट्स में शामिल है। संदेश कन्वर्टर्स और सामग्री बातचीत पर नोट्स की तलाश करें।

2

जेबी Nizet से उल्लेख किया है,

@RequestMapping(value="/orders", method=RequestMethod.GET) 
@ResponseBody 
public List<Account> accountSummary() { 
    return accountManager.getAllAccounts(); 
} 

और

@RequestMapping(value="/orders", method=RequestMethod.GET) 
public @ResponseBody List<Account> accountSummary() { 
    return accountManager.getAllAccounts(); 
} 

दोनों एक ही हैं। जैसा कि @ResponseBody विधि को सूची में नहीं बताता है। @GMsoF- यहां सूचीबद्ध संदेश कन्वर्टर्स का उपयोग निम्नानुसार किया जा सकता है।

@RequestMapping(value="/orders", method=RequestMethod.GET , produces={"application/json","application/xml"}) 
@ResponseBody 
public List<Account> accountSummary() { 
    return accountManager.getAllAccounts(); 
} 

धन्यवाद :)

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