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


89

मेरे पास एक तरीका है जो निम्नलिखित तरीके से एनोटेट किया गया है:

/**
* 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)

यह विधि URL / आदेशों द्वारा प्रस्तुत संसाधन के लिए किए गए GET HTTP अनुरोधों को संभालती है ।

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

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

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 संदेश कनवर्टर (एक एमवीसी दृश्य के बजाय) द्वारा 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 / account एक्सेस करते समय आपको JSON परिणाम प्राप्त करना चाहिए

तो वास्तव में इसका क्या मतलब है? क्या इसका मतलब यह है कि विधि List<Account>द्वारा लौटाई गई वस्तु accountSummary()स्वचालित रूप से JSONप्रारूप में परिवर्तित हो जाती है और फिर अंदर डाल दी जाती है Http Response? और क्या?

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

जवाबों:


160

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

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

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

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


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

@ जेबी निज़ेट आप यह बता सकते हैं कि http प्रतिक्रिया में जावा ऑब्जेक्ट क्यों नहीं हो सकते हैं। मैं जावा के लिए एक newbee हूँ।
नावेद अली

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

@ZhaoGang, सामग्री-प्रकार 'एप्लिकेशन / json' को मेरे परीक्षण के मामले में 'application / xml' द्वारा बदल दिया गया है, लेकिन प्रतिक्रिया निकाय कोई परिवर्तन नहीं लगता है, फिर भी json प्रारूप मौजूद है।
पत्तीवान

1
वास्तव में, मेरा मतलब है कि किस वसंत वर्ग में, यह निर्धारित करने का निर्णय कि प्रतिक्रिया कैसे दी जाए? क्या आप मुझे गितुब के स्रोत की ओर संकेत कर सकते हैं, जहां यह निर्णय किया जाता है या वर्ग का नाम? इसके अलावा अगर क्लाइंट एक्सएमएल को स्वीकार कर लेता है तो क्या होगा, लेकिन कोई एक्सएमएल कन्वर्टर स्थापित नहीं होता है?
अनिरु।

65

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

एक छोर आपके पास MVC आर्किटेक्चर है, जो आपके सामान्य वेब ऐप पर आधारित है, जो वेब पेजों का उपयोग करता है, और ब्राउज़र एक पेज के लिए अनुरोध करता है:

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

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

दूसरे छोर पर, आपके पास एक प्रतिष्ठित वास्तुकला है। इस मामले में, कोई दृश्य नहीं है। नियंत्रक केवल मॉडल (या संसाधन प्रतिनिधित्व, अधिक प्रतिष्ठित शर्तों) में वापस भेजता है। क्लाइंट एक जावास्क्रिप्ट एप्लिकेशन, एक जावा सर्वर एप्लीकेशन, कोई भी एप्लिकेशन हो सकता है जिसमें हम अपने REST API को एक्सपोज करते हैं। इस आर्किटेक्चर के साथ, क्लाइंट यह तय करता है कि इस मॉडल का क्या करना है। उदाहरण के लिए ट्विटर ले लो। Web (REST) ​​API के रूप में Twitter, जो हमारे एप्लिकेशन को स्थिति अपडेट के रूप में ऐसी चीज़ों को प्राप्त करने के लिए अपने API का उपयोग करने की अनुमति देता है, ताकि हम उस डेटा को अपने एप्लिकेशन में डालने के लिए उपयोग कर सकें। वह डेटा JSON जैसे किसी प्रारूप में आएगा।

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

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

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

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

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


यदि बिना उपयोग किए, जेनेरिक / डायनेमिक REST कंट्रोलर बनाने के तरीके के बारे में जांच करते समय आपका जवाब मिल गया @Controller/@RestController। मुझे पता चला, कि मुझे किसी भी तरह से रिज़ॉल्वर की परत को हटाने की जरूरत है। यह इतना सरल नहीं है क्योंकि AbstractController वर्ग एक विधि प्रदान करता है जिसे दृश्य नाम वापस करना होगा। मैंने उस बारे में एक प्रश्न पूछा: stackoverflow.com/questions/41016018/… , अगर आपके पास कुछ विचार हैं कि मैं अपनी समस्या को कैसे हल कर सकता हूं, तो कृपया एक टिप्पणी पोस्ट करें।
Nowszy94

1

इसके आगे, वापसी प्रकार द्वारा निर्धारित किया जाता है

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

  2. क्या HttpMessageConverters स्प्रिंग सेट करता है। स्प्रिंग MVC XML के लिए कन्वर्टर्स सेटअप करेगा (JAXB का उपयोग करके) और JSON अगर जैक्सन लाइब्रेरीज़ क्लास क्लास पर हैं।

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.