Мы запускаем DropWizard и пытаемся отключить регистрацию URL-адресов, которые вызывают появление ответов 404.
У нас есть универсальный преобразователь исключений, который получает NotFoundException
. К сожалению, это исключение не содержит контекста того, какой URL-адрес вызвал его создание.
Пример приложения здесь: https://github.com/pauldambra/not.found.example
Мы используем ExceptionMapper
public class NotFoundLogger implements ExceptionMapper<NotFoundException> {
ExampleLogger logger = new ExampleLogger();
@Override
public Response toResponse(final NotFoundException exception) {
logger.error(urlFrom(exception), exception);
return Response.status(404).build();
}
private String urlFrom(final NotFoundException exception) {
return "why is this not a property on the exception?!";
}
private class ExampleLogger {
void error(final String notFoundUrl, final NotFoundException exception) {
System.out.println("someone tried to load " + notFoundUrl);
System.out.println(exception.getMessage());
}
}
}
Если мы посмотрим на журналы приложений, когда кто-то запрашивает URL-адрес, который приложение не обслуживает, мы увидим, что приложение может регистрировать, что оно возвращает 404 для пути, но наш пользовательский регистратор не имеет доступа к URL-адресу.
someone tried to load why is this not a property on the exception?!
HTTP 404 Not Found
127.0.0.1 - - [08/May/2019:09:53:47 +0000] "GET /ping/pong HTTP/1.1" 404
Является ли ExceptionMapper
неправильным способом сделать это?
Или используйте UriInfo
за stackoverflow.com/a/43610403/775715
О, этот контекстный механизм выглядит многообещающе! Хотя я ненавижу эту необнаружимую магию! (почему это не просто перегрузка метода: D)
Оказывается, есть два пути
один использует сопоставитель исключений:
public class NotFoundLogger implements ExceptionMapper<NotFoundException> {
// magically inject a thing
// remember that magic is for evil wizards
@Context
private HttpServletRequest request;
private ExampleLogger logger = new ExampleLogger();
@Override
public Response toResponse(final NotFoundException exception) {
final StringBuffer absolutePath = HttpUtils.getRequestURL(request);
logger.error("exception mapper: " + absolutePath, exception);
return Response.status(404).build();
}
}
Это работает, но не очень заметно.
Вы также можете добавить фильтр ответов
public class NotFoundLoggingFilter implements ContainerResponseFilter {
private ExampleLogger logger = new ExampleLogger();
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
if (responseContext.getStatus() != 404) {
return;
}
final URI absolutePath = requestContext.getUriInfo().getAbsolutePath();
logger.error("filter: " + absolutePath, new NotFoundException());
}
}
Это не требует никакой магии, так что мне подходит, но вы можете выбрать свой яд.
На самом деле путь должен быть на NotFoundException
- если бы у меня было больше времени, я бы предложил изменить код, чтобы добавить его.
Можете ли вы получить доступ к
HttpServletRequest
, вызвавшему исключение во времяtoResponse()
? за stackoverflow.com/q/17766072/775715