Подтвердить что ты не робот

Как вернуть сообщение об ошибке в spring mvc @Controller

Я использую такие методы

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<UserWithPhoto> getUser(@RequestHeader(value="Access-key") String accessKey,
                                     @RequestHeader(value="Secret-key") String secretKey){
    try{
        return new ResponseEntity<UserWithPhoto>((UserWithPhoto)this.userService.chkCredentials(accessKey, secretKey, timestamp),
                new HttpHeaders(),
                HttpStatus.CREATED);
    }
    catch(ChekingCredentialsFailedException e){
        e.printStackTrace();
        return new ResponseEntity<UserWithPhoto>(null,new HttpHeaders(),HttpStatus.FORBIDDEN);
    }
}

И я хочу вернуть некоторое текстовое сообщение, когда возникает исключение, но теперь я просто возвращаю статус и нулевой объект. Можно ли это сделать?

4b9b3361

Ответ 1

Как Sotirios Delimanolis уже указано в комментариях, есть два варианта:

Возврат ResponseEntity с сообщением об ошибке

Измените свой метод следующим образом:

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity getUser(@RequestHeader(value="Access-key") String accessKey,
                              @RequestHeader(value="Secret-key") String secretKey) {
    try {
        // see note 1
        return ResponseEntity
            .status(HttpStatus.CREATED)                 
            .body(this.userService.chkCredentials(accessKey, secretKey, timestamp));
    }
    catch(ChekingCredentialsFailedException e) {
        e.printStackTrace(); // see note 2
        return ResponseEntity
            .status(HttpStatus.FORBIDDEN)
            .body("Error Message");
    }
}

Примечание 1: Вам не нужно использовать конструктор ResponseEntity, но я считаю, что это помогает с сохранением кода. Он также помогает запоминать, какие данные должны включать ответ для определенного кода состояния HTTP. Например, ответ с кодом состояния 201 должен содержать ссылку на вновь созданный ресурс в заголовке Location (см. Определения кода состояния), Вот почему Spring предлагает удобный метод сборки ResponseEntity.created(URI).

Примечание 2: Не используйте printStackTrace(), вместо этого используйте регистратор.

Предоставьте @ExceptionHandler

Удалите блок try-catch из вашего метода и дайте ему исключение. Затем создайте еще один метод в классе, аннотированный с помощью @ControllerAdvice следующим образом:

@ControllerAdvice
public class ExceptionHandlerAdvice {

    @ExceptionHandler(ChekingCredentialsFailedException.class)
    public ResponseEntity handleException(ChekingCredentialsFailedException e) {
        // log exception
        return ResponseEntity
                .status(HttpStatus.FORBIDDEN)
                .body("Error Message");
    }        
}

Обратите внимание, что методы, аннотированные с помощью @ExceptionHandler, имеют очень гибкие подписи. Подробнее см. Javadoc.

Ответ 2

Вот альтернатива. Создайте общее исключение, которое принимает код состояния и сообщение. Затем создайте обработчик исключений. Используйте обработчик исключений для извлечения информации из исключения и возврата к вызывающей стороне службы.

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

public class ResourceException extends RuntimeException {

    private HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

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

Затем используйте обработчик исключений для извлечения информации и возврата ее вызывающему абоненту службы.

@ControllerAdvice
public class ExceptionHandlerAdvice { 

    @ExceptionHandler(ResourceException.class)
    public ResponseEntity handleException(ResourceException e) {
        // log exception 
        return ResponseEntity.status(e.getHttpStatus()).body(e.getMessage());
    }         
} 

Затем создайте исключение, когда вам нужно.

throw new ResourceException(HttpStatus.NOT_FOUND, "We were unable to find the specified resource.");