Сбрасывать плохие запросы - PullRequest
0 голосов
/ 19 октября 2018

У меня есть служба, реализованная с помощью Dropwizard, и мне нужно куда-то сбрасывать неправильные запросы.

Я увидел, что есть возможность настроить сообщение об ошибке, зарегистрировав ExceptionMapper<JerseyViolationException>.Но мне нужно иметь полный запрос (заголовки, тело), ​​а не только ConstraintViolations.

1 Ответ

0 голосов
/ 20 октября 2018

Вы можете ввести ContainerRequest в ExceptionMapper.Вам нужно ввести его как javax.inject.Provider, чтобы его можно было лениво извлечь.В противном случае у вас возникнут проблемы с областями видимости.

@Provider
public class Mapper implements ExceptionMapper<ConstraintViolationException> {

    @Inject
    private javax.inject.Provider<ContainerRequest> requestProvider;

    @Override
    public Response toResponse(ConstraintViolationException ex) {
        ContainerRequest request = requestProvider.get();
    }
}

В ContainerRequest вы можете получить заголовки с getHeaderString() или getHeaders().Если вы хотите получить тело, вам нужно немного взломать, потому что поток сущностей уже прочитан Джерси к тому времени, когда маппер достигнут.Поэтому нам нужно реализовать ContainerRequestFilter для буферизации объекта.

public class EntityBufferingFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
        ContainerRequest request = (ContainerRequest) containerRequestContext;
        request.bufferEntity();
    }
}

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

Как только вы зарегистрируете этот фильтр,Вы можете прочитать тело, используя ContainerRequest#readEntity(Class).Вы используете этот метод так же, как и на стороне клиента с Response#readEntity().Так что для класса, если вы хотите сохранить его универсальным, вы можете использовать String.class или InputStream.class и преобразовать InputStream в строку.

ContainerRequest request = requestProvider.get();
String body = request.readEntity(String.class);
...