java - एक स्प्रिंग एमवीसी @ResponseBody विधि स्ट्रिंग लौटने में HTTP 400 त्रुटि के साथ कैसे प्रतिक्रिया करें?




spring spring-mvc (6)

अपने रिटर्न प्रकार को ResponseEntity<> बदलें, फिर आप 400 के लिए नीचे उपयोग कर सकते हैं

return new ResponseEntity<>(HttpStatus.BAD_REQUEST);

और सही अनुरोध के लिए

return new ResponseEntity<>(json,HttpStatus.OK);

अद्यतन 1

वसंत 4.1 के बाद ResponseEntity में सहायक तरीके के रूप में उपयोग किया जा सकता है

return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);

तथा

return ResponseEntity.ok(json);

मैं एक साधारण JSON एपीआई के लिए स्प्रिंग एमवीसी का उपयोग कर रहा हूं, जिसमें निम्नलिखित के रूप में @ResponseBody आधारित दृष्टिकोण है। (मेरे पास पहले से ही जेएसओएन का उत्पादन करने वाली एक सेवा परत है।)

@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String match(@PathVariable String matchId) {
    String json = matchService.getMatchJson(matchId);
    if (json == null) {
        // TODO: how to respond with e.g. 400 "bad request"?
    }
    return json;
}

प्रश्न यह है कि, दिए गए परिदृश्य में, एक HTTP 400 त्रुटि के साथ प्रतिक्रिया करने का सबसे सरल, साफ तरीका क्या है ?

मैं दृष्टिकोण के पार आया था जैसे:

return new ResponseEntity(HttpStatus.BAD_REQUEST);

... लेकिन मैं इसका उपयोग यहां नहीं कर सकता क्योंकि मेरी विधि का रिटर्न प्रकार स्ट्रिंग है, प्रतिक्रिया नहीं है।


इस तरह कुछ काम करना चाहिए, मुझे यकीन नहीं है कि एक आसान तरीका है या नहीं:

@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String match(@PathVariable String matchId, @RequestBody String body,
            HttpServletRequest request, HttpServletResponse response) {
    String json = matchService.getMatchJson(matchId);
    if (json == null) {
        response.setStatus( HttpServletResponse.SC_BAD_REQUEST  );
    }
    return json;
}

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

  • एक सामान्य अपवाद बनाएं जो HTTP स्थिति स्वीकार करता है
  • एक नियंत्रक सलाह अपवाद हैंडलर बनाएँ

आइए कोड प्राप्त करें

package com.javaninja.cam.exception;

import org.springframework.http.HttpStatus;


/**
 * The exception used to return a status and a message to the calling system.
 * @author norrisshelton
 */
@SuppressWarnings("ClassWithoutNoArgConstructor")
public class ResourceException extends RuntimeException {

    private HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;

    /**
     * Gets the HTTP status code to be returned to the calling system.
     * @return http status code.  Defaults to HttpStatus.INTERNAL_SERVER_ERROR (500).
     * @see HttpStatus
     */
    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    /**
     * Constructs a new runtime exception with the specified HttpStatus code and detail message.
     * The cause is not initialized, and may subsequently be initialized by a call to {@link #initCause}.
     * @param httpStatus the http status.  The detail message is saved for later retrieval by the {@link
     *                   #getHttpStatus()} method.
     * @param message    the detail message. The detail message is saved for later retrieval by the {@link
     *                   #getMessage()} method.
     * @see HttpStatus
     */
    public ResourceException(HttpStatus httpStatus, String message) {
        super(message);
        this.httpStatus = httpStatus;
    }
}

फिर मैं एक नियंत्रक सलाह वर्ग बनाते हैं

package com.javaninja.cam.spring;


import com.javaninja.cam.exception.ResourceException;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;


/**
 * Exception handler advice class for all SpringMVC controllers.
 * @author norrisshelton
 * @see org.springframework.web.bind.annotation.ControllerAdvice
 */
@org.springframework.web.bind.annotation.ControllerAdvice
public class ControllerAdvice {

    /**
     * Handles ResourceExceptions for the SpringMVC controllers.
     * @param e SpringMVC controller exception.
     * @return http response entity
     * @see ExceptionHandler
     */
    @ExceptionHandler(ResourceException.class)
    public ResponseEntity handleException(ResourceException e) {
        return ResponseEntity.status(e.getHttpStatus()).body(e.getMessage());
    }
}

इसके प्रयेाग के लिए

throw new ResourceException(HttpStatus.BAD_REQUEST, "My message");

http://javaninja.net/2016/06/throwing-exceptions-messages-spring-mvc-controller/


मुझे लगता है कि इस धागे में वास्तव में सबसे आसान, स्वच्छ समाधान है, जो वसंत प्रदान करता है जो JSON मार्शलिंग उपकरण का त्याग नहीं करता है:

https://.com/a/16986372/1278921


मैं थोड़ा कार्यान्वयन बदल दूंगा:

सबसे पहले, मैं एक UnknownMatchException बना देता UnknownMatchException :

@ResponseStatus(HttpStatus.NOT_FOUND)
public class UnknownMatchException extends RuntimeException {
    public UnknownMatchException(String matchId) {
        super("Unknown match: " + matchId);
    }
}

@ResponseStatus के उपयोग पर ध्यान दें, जिसे स्प्रिंग के ResponseStatusExceptionResolver द्वारा पहचाना जाएगा। अगर अपवाद फेंक दिया जाता है, तो यह संबंधित प्रतिक्रिया स्थिति के साथ प्रतिक्रिया देगा। (मैंने स्टेटस कोड को 404 - Not Found में बदलने की स्वतंत्रता भी ली 404 - Not Found कि मुझे इस उपयोग के मामले के लिए और अधिक उपयुक्त लगता है, लेकिन यदि आप चाहें तो आप HttpStatus.BAD_REQUEST चिपके रह सकते हैं।)

इसके बाद, मैं निम्नलिखित हस्ताक्षर MatchService लिए MatchService को बदल MatchService :

interface MatchService {
    public Match findMatch(String matchId);
}

अंत में, मैं नियंत्रक को अद्यतन करता हूं और जेएसओएन क्रमशः स्वचालित रूप से संभालने के लिए स्प्रिंग के MappingJackson2HttpMessageConverter को प्रतिनिधि करता MappingJackson2HttpMessageConverter (यदि आप क्लासपाथ में जैक्सन जोड़ते हैं और या तो @EnableWebMvc या <mvc:annotation-driven /> को अपनी कॉन्फ़िगरेशन में जोड़ते हैं तो इसे डिफ़ॉल्ट रूप से जोड़ा जाता है, देखें संदर्भ दस्तावेज़ ):

@RequestMapping(value = "/matches/{matchId}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Match match(@PathVariable String matchId) {
    // throws an UnknownMatchException if the matchId is not known 
    return matchService.findMatch(matchId);
}

नोट, डोमेन ऑब्जेक्ट्स को ऑब्जेक्ट्स या डीटीओ ऑब्जेक्ट्स से अलग करना बहुत आम है। इसे आसानी से एक छोटा डीटीओ कारखाना जोड़कर हासिल किया जा सकता है जो धारावाहिक JSON ऑब्जेक्ट देता है:

@RequestMapping(value = "/matches/{matchId}", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public MatchDTO match(@PathVariable String matchId) {
    Match match = matchService.findMatch(matchId);
    return MatchDtoFactory.createDTO(match);
}

यहां एक अलग दृष्टिकोण है। @ResponseStatus साथ एनोटेटेड कस्टम Exception बनाएं, जैसे कि निम्न एक।

@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Not Found")
public class NotFoundException extends Exception {

    public NotFoundException() {
    }
}

और जरूरत पड़ने पर इसे फेंक दें।

@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String match(@PathVariable String matchId) {
    String json = matchService.getMatchJson(matchId);
    if (json == null) {
        throw new NotFoundException();
    }
    return json;
}

यहां स्प्रिंग प्रलेखन देखें: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-annotated-exceptions





http-error