Spring Boot Rest Controller Farklı HTTP durum kodları nasıl döndürülür?


104

Spring Boot'u basit bir REST API için kullanıyorum ve bir şey başarısız olursa doğru bir HTTP durum kodu döndürmek istiyorum.

@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?
}

Spring ve Spring Boot'ta yeni olduğum için temel soru, bir şeyler yolunda gittiğinde veya başarısız olduğunda farklı durum kodlarını nasıl döndürebilirim?

Yanıtlar:


120

Kullanabileceğiniz birkaç seçenek var. Oldukça iyi bir yol, işleme için istisnaları ve sınıfı kullanmaktır @ControllerAdvice:

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

Ayrıca HttpServletResponsedenetleyici yöntemine geçebilir ve yalnızca yanıt kodunu ayarlayabilirsiniz:

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

Ayrıntılar için lütfen bu harika blog gönderisine bakın: Spring MVC'de İstisna Yönetimi


NOT

Spring MVC'de @ResponseBodyaçıklama kullanmak gereksizdir - zaten @RestControlleraçıklamaya dahil edilmiştir .


Yorum olarak, 15 dakika önce bir test yaptım ve yönteminin üzerinde '@ResponseBody' ek açıklaması olmayan bir '@RestController', dizeyi gövdenin içine değil ForwardedURL olarak döndürdü. Spring / springboot ile oldukça
acemiyim

@Anearion Yanıtta bir yazım hatası var - '@RestController' değil, '@RestControllerAdvice' gerekiyor.
yoliho

Bu bir yazım hatası değil. Bu bölüm bir denetleyici üzerinde soruya ve ek açıklamalar ile ilgilidir
Jakub Kubrynski

1
Unutmayın, javax.servlet.http.HttpServletResponsetüm Durum Kodlarına sahip değil gibi görünüyor org.springframework.http.HttpStatus. Böylece HttpStatus.UNPROCESSABLE_ENTITY.value(), int değerini response.setStatus'a iletmek için kullanabilirsiniz . Ayrıca bu, kullanımda hata işleme için mükemmel çalışır @ExceptionHandler.
Igor

43

Bunu yapmanın yollarından biri, ResponseEntity'yi dönüş nesnesi olarak kullanabilmenizdir.

@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
İlkbahar'ın sonraki sürümlerinde boş değeri kullanmaya gerek yok: new ResponseEntity <> (HttpStatus.NOT_FOUND)
Kong

4

Bu kodu deneyin:

@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));
}

Bu oldukça eski bir soru olduğundan, başvurduğunuz paket ve sürüm bilgilerini eklemelisiniz.
ZF007

Örnek bir uygulama ekleyebilir misiniz ErrorBean?
Brent Bradburn

4

Spring'in ResponseStatusException'ını kullanmanın güzel bir yolu

Bir ResponseEntityveya benzerini iade etmek yerine ResponseStatusException, denetleyiciden bir HttpStatusve neden ile basitçe atarsınız, örneğin:

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

veya:

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

Bu, istemciye HTTP durumunu içeren bir yanıtla sonuçlanır (ör. 400 Kötü istek) ve aşağıdaki gibi bir gövdeyle:

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

Bir REST istemcisi tarafından basit, temiz ve tüketilebilir.
Alecz

3

Özel tanımlı bir durum kodu döndürmek istemeniz durumunda, ResponseEntity'yi aşağıdaki gibi kullanabilirsiniz:

@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, standart HTTP Durum Kodlarının içindeki veya dışındaki herhangi bir tam sayı olabilir.


Bu akıcı API yaklaşımını seviyorum.
v.ladynev

0

Durum kodunu döndürmenin farklı yolları vardır, 1: RestController sınıfı BaseRest sınıfını genişletmelidir, BaseRest sınıfında istisnayı ele alabilir ve beklenen hata kodlarını döndürebiliriz. Örneğin :

@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;
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.