स्प्रिंग बूट रेस्ट कंट्रोलर विभिन्न HTTP स्टेटस कोड कैसे लौटाएं?


102

मैं एक साधारण रीस्ट एपीआई के लिए स्प्रिंग बूट का उपयोग कर रहा हूं और अगर कुछ विफल हो जाता है तो एक सही HTTP स्थितिकोड वापस करना चाहूंगा।

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
@ResponseBody
@ResponseStatus( HttpStatus.OK )
public RestModel create(@RequestBody String data) {
    // code ommitted..
    // how do i return a correct status code if something fails?
}

स्प्रिंग और स्प्रिंग बूट के लिए नया होने के नाते, मूल प्रश्न यह है कि जब कुछ ठीक होता है या विफल होता है तो मैं अलग स्थिति कोड कैसे लौटाता हूं?

जवाबों:


117

ऐसे कई विकल्प हैं जिनका आप उपयोग कर सकते हैं। काफी अच्छा तरीका है अपवादों और कक्षा को संभालने के लिए उपयोग करना है @ControllerAdvice:

@ControllerAdvice
class GlobalControllerExceptionHandler {
    @ResponseStatus(HttpStatus.CONFLICT)  // 409
    @ExceptionHandler(DataIntegrityViolationException.class)
    public void handleConflict() {
        // Nothing to do
    }
}

इसके अलावा, आप HttpServletResponseनियंत्रक विधि में जा सकते हैं और प्रतिक्रिया कोड निर्धारित कर सकते हैं :

public RestModel create(@RequestBody String data, HttpServletResponse response) {
    // response committed...
    response.setStatus(HttpServletResponse.SC_ACCEPTED);
}

कृपया विवरण के लिए इस महान ब्लॉग पोस्ट को देखें: स्प्रिंग एमवीसी में अपवाद हैंडलिंग


ध्यान दें

स्प्रिंग एमवीसी में @ResponseBodyएनोटेशन का उपयोग करना बेमानी है - यह @RestControllerएनोटेशन में पहले से ही शामिल है ।


बस टिप्पणी के रूप में, मैंने 15 मिनट पहले एक परीक्षण किया था, और '@RestController' के बिना '@ResponseBody' के अनाउंसमेंट के दौरान उनकी पद्धति ने स्ट्रिंग को शरीर के अंदर नहीं बल्कि फॉरवर्डेडुरल के रूप में लौटा दिया। मैं बसंत / वसंत के साथ बहुत
नोब

@Anearion उत्तर में एक टाइपो है - हमें वास्तव में '@RestControllerAdvice' की आवश्यकता है, न कि '@RestController' की।
योलीहो

यह एक टाइपो नहीं है। यह हिस्सा एक नियंत्रक पर प्रश्न और एनोटेशन से संबंधित है
जैकब कुब्रीन्स्की

1
ध्यान दें, ऐसा javax.servlet.http.HttpServletResponseलगता है कि सभी StatusCodes org.springframework.http.HttpStatusनहीं है। तो आप HttpStatus.UNPROCESSABLE_ENTITY.value()int-value को response.setStatus में पास करने के लिए उपयोग कर सकते हैं । इसके अलावा यह पूरी तरह से त्रुटि से निपटने के लिए काम करता है @ExceptionHandler
इगोर

43

ऐसा करने का एक तरीका यह है कि आप रिस्पॉन्स ऑब्जेक्ट को रिटर्न ऑब्जेक्ट के रूप में उपयोग कर सकते हैं।

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)

public ResponseEntity<?> create(@RequestBody String data) {

if(everything_fine)
    return new ResponseEntity<>(RestModel, HttpStatus.OK);
else
    return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);

}

3
वसंत के बाद के संस्करणों में शून्य का उपयोग करने की आवश्यकता नहीं है: नया ResponseEntity <> (HttpStatus.NOT_FOUND)
काँग

4

इस कोड को आज़माएं:

@RequestMapping(value = "/validate", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<ErrorBean> validateUser(@QueryParam("jsonInput") final String jsonInput) {
    int numberHTTPDesired = 400;
    ErrorBean responseBean = new ErrorBean();
    responseBean.setError("ERROR");
    responseBean.setMensaje("Error in validation!");

    return new ResponseEntity<ErrorBean>(responseBean, HttpStatus.valueOf(numberHTTPDesired));
}

जैसा कि यह एक पुराना सवाल है, इसलिए आपको पैकेज और संस्करण जानकारी को जोड़ना चाहिए, जिसे आप संदर्भित करते हैं।
ZF007

क्या आप एक उदाहरण का कार्यान्वयन शामिल कर सकते हैं ErrorBean?
ब्रेंट बर्नबर्न

3

एक अच्छा तरीका है स्प्रिंग के रिस्पांसस्टैटस अपवाद का उपयोग करना

उदाहरण के लिए, एक ResponseEntityया इसी तरह वापस लौटने के बजाय आप ResponseStatusExceptionकंट्रोलर से ए HttpStatusऔर कारण के साथ फेंकते हैं :

throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Cause description here");

या:

throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Cause description here");

यह HTTP स्थिति (जैसे 400 खराब अनुरोध) वाले ग्राहक की प्रतिक्रिया के परिणामस्वरूप होता है जैसे:

{
  "timestamp": "2020-07-09T04:43:04.695+0000",
  "status": 400,
  "error": "Bad Request",
  "message": "Cause description here",
  "path": "/test-api/v1/search"
}

2

यदि आप कस्टम परिभाषित स्थिति कोड वापस करना चाहते हैं, तो आप यहां दिए गए ResponseEntity का उपयोग कर सकते हैं:

@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
public ResponseEntity<?> create(@RequestBody String data) {
    int customHttpStatusValue = 499;
    Foo foo = bar();
    return ResponseEntity.status(customHttpStatusValue).body(foo);
}

CustomHttpStatusValue मानक HTTP स्थिति कोड के भीतर या बाहर कोई भी पूर्णांक हो सकता है।


मुझे यह धाराप्रवाह एपीआई दृष्टिकोण पसंद है।
v.ladynev

0

स्टेटस कोड को वापस करने के लिए अलग-अलग तरीके हैं, 1: रेस्टकंट्रोलर क्लास को बेसरेस्ट क्लास का विस्तार करना चाहिए, बेसरेस्ट क्लास में हम अपवाद को संभाल सकते हैं और अपेक्षित त्रुटि कोड वापस कर सकते हैं। उदाहरण के लिए :

@RestController
@RequestMapping
class RestController extends BaseRest{

}

@ControllerAdvice
public class BaseRest {
@ExceptionHandler({Exception.class,...})
    @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorModel genericError(HttpServletRequest request, 
            HttpServletResponse response, Exception exception) {
        
        ErrorModel error = new ErrorModel();
        resource.addError("error code", exception.getLocalizedMessage());
        return error;
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.