यदि स्प्रिंग MVC कंट्रोलर विधि मान वापस नहीं करती है तो क्या लौटना है?


135

मैं $.getJSON()अपने साधारण स्प्रिंग MVC बैकएंड पर एसिंक्रोनस कॉल करने के लिए jQuery का उपयोग कर रहा हूं । अधिकांश स्प्रिंग कंट्रोलर विधियाँ इस तरह दिखती हैं:

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) {
    return someDAO.getSomeData(widget, type);
}   

मेरे पास चीजें सेट हैं ताकि प्रत्येक नियंत्रक @ResponseBodyJSON के रूप में लौटे , जो क्लाइंट-साइड की अपेक्षा है।

लेकिन क्या होता है जब कोई अनुरोध क्लाइंट-साइड में किसी भी सामग्री को वापस करने के लिए नहीं होता है? क्या मैं ले सकता हूँ:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

यदि नहीं, तो यहां उपयोग करने के लिए उपयुक्त सिंटैक्स क्या है?


मुझे लगता है कि यदि आप कुछ भी वापस नहीं करते हैं, तो कोई सामग्री वापस नहीं भेजी जाएगी?
अरहंत

1
मुझे लगता है कि मैं अभी भी किसी प्रकार का एक POJO लौटाऊंगा, भले ही आपके समाधान के संस्करण 1 में यह सिर्फ एक "सफलता" बूलियन या कुछ समान लपेटता है। तो फिर आप अपने सभी AJAX के तरीकों में किसी समान प्रतिमान है, और कुछ जब यह पता चला है कि आप पर बनाने के लिए आसान है कि मिल गया है कर वापसी कुछ करने की जरूरत!
मिलक

इसके विपरीत कि सुझाव क्या हैं, आपके पहले स्निपेट में जो कुछ भी था, वह पूरी तरह से ठीक है और POSTडेटा को संभालने का सही तरीका है ।
ब्रेट रायन

इस मामले में यह अशक्त होने वाला है। @RestController सार्वजनिक वर्ग RESTControllerExample {@RequestMapping (मान = "/ कर्मचारी", विधि = RequestMethod.GET) सार्वजनिक शून्य getEmployeeNames () {Employeeource.getEmployees (); System.out.println ("मैं कर रहा हूँ"); }}
स्पैन्डे

जवाबों:


256

आप शून्य वापस कर सकते हैं, फिर आपको @ResponseStatus (मान = HttpStatus.OK) के साथ विधि को चिह्नित करना होगा। आपको @ResponseBody की आवश्यकता नहीं है

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

केवल विधियाँ 200 स्टेटस कोड इम्पीच्यिटी लौटाती हैं, अन्य सभी जो आपके पास तीन चीजों में से एक हैं:

  • शून्य लौटें और विधि को चिह्नित करें @ResponseStatus(value = HttpStatus.OK)
  • किसी ऑब्जेक्ट पर लौटें और इसे चिह्नित करें @ResponseBody
  • एक HttpEntityउदाहरण लौटें

2
यदि रनटाइम अपवाद के बीच में होता है, तो HTTP 500 वापस आ जाएगा और 200 नहीं। इसलिए यदि आपका फ्रंट एंड विफलता विफल हो जाता है, तो अपवाद / त्रुटि संदेश सही ढंग से प्रदर्शित होगा।
ली ची कीम

27
वास्तव में, आपको सेट करने की आवश्यकता नहीं है @ResponseStatusऔर नहीं होना चाहिए। बस @ResponseBodyएक voidहैंडलर पर होना काफी ठीक है।
ब्रेट रायन

11
मुझे लगता है कि शून्य विधियों के लिए 200 के बजाय 204 नो कंटेंट को वापस करना बेहतर होगा
raspacorp

1
@raspacorp 200 POST के लिए सही है क्योंकि इसमें बॉडी होने का मतलब नहीं है।
ब्रेट रयान

8
@BrettRyan सिर्फ एक टिप्पणी के रूप में, कम से कम REST API के लिए यह एक आम बात है कि POST का उपयोग उस सामग्री को बनाने के लिए किया जाएगा जिस स्थिति में यह आमतौर पर बनाई गई enity (s), पूर्ण बनाई गई संस्थाओं या लिंक की आईडी लौटाता है पढ़ने के लिए ऑपरेशन। कोई भी सामग्री नहीं के साथ एक 200 की स्थिति वापसी REST API परिप्रेक्ष्य से भ्रमित हो सकती है।
रास्पाकॉर्प

43

आप बस उचित हेडर के साथ एक ResponseEntity वापस कर सकते हैं:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}

किसी को भी उसी समस्या में भाग लें जो मैंने किया था, यह वसंत के पुराने संस्करण (4.1.1) पर काम नहीं करता था मुझे 500 त्रुटियां मिलेंगी। मैं 4.2.0 करने के लिए उन्नत और इस महान काम करता है
सॉस

यही कारण है कि खाली 200 वापस करने का मेरा पसंदीदा तरीका है। चूंकि स्प्रिंग 4.1 इसके बजाय बिल्डर पैटर्न का उपयोग करता है: ResponseEntity.ok ()। build ();
ग्रीनटर्ल

3
हालांकि संकलन करने के लिए लगता है, यह निम्नलिखित चेतावनी देता हैResponseEntity is a raw type. References to generic type ResponseEntity<T> should be parameterized
गोंजालो

8

आप "ResponseEntity" ऑब्जेक्ट वापस कर सकते हैं। रिस्पांस ऑब्जेक्ट (जिसमें रिस्पांस बॉडी और HTTP स्टेटस कोड होता है) और प्रतिक्रिया ऑब्जेक्ट से बाहर जानकारी प्राप्त करने के समय "रेस्पोंसएंटिटी" ऑब्जेक्ट का उपयोग करना बहुत सुविधाजनक होता है।

GetHeaders (), getBody (), getContentType (), getStatusCode () आदि जैसे तरीके ResponseEntity ऑब्जेक्ट को पढ़ने के काम को बहुत आसान बनाता है।

आपको 204 (कोई सामग्री) के http स्थिति कोड के साथ ResponseEntity ऑब्जेक्ट का उपयोग करना चाहिए, जो विशेष रूप से यह निर्दिष्ट करने के लिए है कि अनुरोध को ठीक से संसाधित किया गया है और प्रतिक्रिया निकाय जानबूझकर रिक्त है। सही जानकारी देने के लिए उपयुक्त स्थिति कोड का उपयोग करना बहुत महत्वपूर्ण है, खासकर यदि आप एक एपीआई बना रहे हैं जिसका उपयोग कई ग्राहक अनुप्रयोगों द्वारा किया जा रहा है।


3
सेटिंग @ResponseStatus(HttpStatus.NO_CONTENT)हल XML Parsing Error: no root element foundमें ब्राउज़र मेरे लिए
aliopi

3

हाँ, आप voidरिटर्न प्रकार के साथ @ResponseBody का उपयोग कर सकते हैं :

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

1
तो वापसी का प्रकार क्या होगा .. क्या यह HTTP स्थिति कोड है?
5

@techBeginner इस मामले में 200 (ठीक है)।
लकाटोस ग्युला

2

शून्य वापस करने में कुछ भी गलत नहीं है @ResponseBodyऔर आपको POSTअनुरोधों के लिए जाना चाहिए ।

HTTP हैंडल कोड्स का उपयोग अपवाद हैंडलर रूटीन के भीतर त्रुटियों को परिभाषित करने के लिए करें क्योंकि अन्य लोग सफलता की स्थिति का उल्लेख कर रहे हैं। एक सामान्य विधि जैसा कि आपके पास एक प्रतिक्रिया कोड होगा, 200जिसमें से आप जो चाहते हैं, कोई अपवाद हैंडलर उसके बाद एक त्रुटि ऑब्जेक्ट और एक अलग कोड (यानी 500) वापस कर सकता है ।


1

लेकिन जैसे-जैसे आपका सिस्टम आकार और कार्यक्षमता में बढ़ता है ... मुझे लगता है कि हमेशा एक लौटाना एक बुरा विचार नहीं है। अधिक वास्तुशिल्प / "बड़े पैमाने पर डिजाइन" मामला है।

आप हमेशा एक JSON को दो ज्ञात क्षेत्रों: कोड और डेटा के साथ बनाए रखने के बारे में सोच सकते हैं। जहां कोड एक संख्यात्मक कोड होता है जो ऑपरेशन की सफलता को निर्दिष्ट करता है और डेटा अनुरोधित ऑपरेशन / सेवा से संबंधित कोई भी डेटा है।

आइए, जब हम एक सेवा प्रदाता के बैकएंड का उपयोग करते हैं, तो किसी भी सेवा को यह देखने के लिए जांचा जा सकता है कि क्या उसने अच्छा काम किया है।

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


0

यहाँ उदाहरण कोड है जो मैंने एक अतुल्यकालिक विधि के लिए किया था

@RequestMapping(value = "/import", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{
    accountingSystemHandler.importData(file, assignChargeCodes);
}

आपको अपनी पद्धति से किसी भी चीज़ को वापस करने की आवश्यकता नहीं है, आपको इस एनोटेशन का उपयोग करने की आवश्यकता है ताकि आपकी विधि हर मामले में ठीक हो जाए

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