JAX-RS / Джерси, как настроить обработку ошибок?

Конкретное правило для пересылки запросов в такой шаблон выглядит довольно просто:

RewriteEngine on
RewriteRule ^/?(\d+/\d+/.*)$ /foo/$1 [END]
RewriteRule ^/?(.*)$ /bar/$1 [END]

Если вы хотите быть действительно точным в отношении точного формата, то это может быть ближе:

RewriteEngine on
RewriteRule ^/?(\d\d\d\d/\d\d/.*)$ /foo/$1 [END]
RewriteRule ^/?(.*)$ /bar/$1 [END]
[ 119] Оба варианта будут внутренне переписаны /2019/01/article-title - /foo/2019/01/article-title. Я предполагаю , что вы действительно хотите достичь. Все запросы к URL , не соответствующие этому первоначальному правилу, будут переписаны на /bar/....

210
задан Paul Bellora 21 August 2013 в 08:09
поделиться

5 ответов

Существует несколько подходов для настройки поведения обработки ошибок с JAX-RS. Вот три из более легких путей.

первый подход должен создать Класс исключений, который расширяет WebApplicationException.

Пример:

public class NotAuthorizedException extends WebApplicationException {
     public NotAuthorizedException(String message) {
         super(Response.status(Response.Status.UNAUTHORIZED)
             .entity(message).type(MediaType.TEXT_PLAIN).build());
     }
}

И бросить это недавно создают Исключение Вы просто:

@Path("accounts/{accountId}/")
    public Item getItem(@PathParam("accountId") String accountId) {
       // An unauthorized user tries to enter
       throw new NotAuthorizedException("You Don't Have Permission");
}

Уведомление, Вы не должны объявлять исключение в пункте бросков, потому что WebApplicationException является исключением на этапе выполнения. Это возвратит 401 ответ клиенту.

второй и более легкий подход должен просто создать экземпляр WebApplicationException непосредственно в Вашем коде. Этот подход работает, пока Вы не должны реализовывать свое собственное приложение Исключения.

Пример:

@Path("accounts/{accountId}/")
public Item getItem(@PathParam("accountId") String accountId) {
   // An unauthorized user tries to enter
   throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}

Этот код также возвращает 401 клиенту.

, Конечно, это - просто простой пример. Можно сделать Исключение намного более сложным при необходимости, и можно генерировать то, что когда-либо код ответа HTTP Вы должны.

Еще один подход должен обернуть существующее Исключение, возможно, ObjectNotFoundException с маленьким классом обертки, который реализует интерфейс ExceptionMapper, аннотируемый @Provider аннотацией. Это говорит времени выполнения JAX-RS, что, если обернутое Исключение повышено, возвратите код ответа, определенный в ExceptionMapper.

269
ответ дан ezain 23 November 2019 в 04:35
поделиться

Одно очевидное решение: возьмите в Строке, преобразуйте до настоящего времени себя. Тем путем можно определить формат, Вы хотите, ловите исключения и или повторно бросаете или настраиваете отправляемую ошибку. Для парсинга должен хорошо работать SimpleDateFormat.

я уверен, что существуют способы сцепить обработчики для типов данных также, но возможно немного простого кода все, в чем Вы нуждаетесь в этом случае.

11
ответ дан StaxMan 23 November 2019 в 04:35
поделиться

Мне также нравится StaxMan, вероятно, реализовал бы тот QueryParam как Строку, затем обработал бы преобразование, повторно бросив по мере необходимости.

Локаль, определенное поведение является желаемым и ожидаемым поведением, при использовании следующего для возврата 400 ПЛОХИХ ошибок ЗАПРОСА:

throw new WebApplicationException(Response.Status.BAD_REQUEST);

Посмотрите JavaDoc для javax.ws.rs.core. Ответ. Состояние для большего количества опций.

7
ответ дан Community 23 November 2019 в 04:35
поделиться

Я сталкивался с той же проблемой.

я хотел зафиксировать все ошибки в центральном месте и преобразовать их.

следующее является кодом для того, как я обработал его.

Создают следующий класс, который реализует ExceptionMapper, и добавьте @Provider аннотация на этот класс. Это обработает все исключения.

Переопределение toResponse метод и возврат объект Ответа заполняется со специализированными данными.

//ExceptionMapperProvider.java
/**
 * exception thrown by restful endpoints will be caught and transformed here
 * so that client gets a proper error message
 */
@Provider
public class ExceptionMapperProvider implements ExceptionMapper<Throwable> {
    private final ErrorTransformer errorTransformer = new ErrorTransformer();

    public ExceptionMapperProvider() {

    }

    @Override
    public Response toResponse(Throwable throwable) {
        //transforming the error using the custom logic of ErrorTransformer 
        final ServiceError errorResponse = errorTransformer.getErrorResponse(throwable);
        final ResponseBuilder responseBuilder = Response.status(errorResponse.getStatus());

        if (errorResponse.getBody().isPresent()) {
            responseBuilder.type(MediaType.APPLICATION_JSON_TYPE);
            responseBuilder.entity(errorResponse.getBody().get());
        }

        for (Map.Entry<String, String> header : errorResponse.getHeaders().entrySet()) {
            responseBuilder.header(header.getKey(), header.getValue());
        }

        return responseBuilder.build();
    }
}

// ErrorTransformer.java
/**
 * Error transformation logic
 */
public class ErrorTransformer {
    public ServiceError getErrorResponse(Throwable throwable) {
        ServiceError serviceError = new ServiceError();
        //add you logic here
        serviceError.setStatus(getStatus(throwable));
        serviceError.setBody(getBody(throwable));
        serviceError.setHeaders(getHeaders(throwable));

    }
    private String getStatus(Throwable throwable) {
        //your logic
    }
    private Optional<String> getBody(Throwable throwable) {
        //your logic
    }
    private Map<String, String> getHeaders(Throwable throwable) {
        //your logic
    }
}

//ServiceError.java
/**
 * error data holder
 */
public class ServiceError {
    private int status;
    private Map<String, String> headers;
    private Optional<String> body;
    //setters and getters
}
0
ответ дан 23 November 2019 в 04:35
поделиться

Вы также можете написать многоразовый класс для переменных с аннотациями QueryParam

public class DateParam {
  private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

  private Calendar date;

  public DateParam(String in) throws WebApplicationException {
    try {
      date = Calendar.getInstance();
      date.setTime(format.parse(in));
    }
    catch (ParseException exception) {
      throw new WebApplicationException(400);
    }
  }
  public Calendar getDate() {
    return date;
  }
  public String format() {
    return format.format(value.getTime());
  }
}

, а затем использовать его следующим образом:

private @QueryParam("from") DateParam startDateParam;
private @QueryParam("to") DateParam endDateParam;
// ...
startDateParam.getDate();

Хотя обработка ошибок в этом случае тривиальна (выдача ответа 400), использование этого класса позволяет исключить обработку параметров в целом, которая может включать ведение журнала и т. д.

26
ответ дан 23 November 2019 в 04:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: