Ответ 1
Вы можете создавать фильтры и легко связывать их с конечными точками, которые вам нужно записывать, сохраняя конечные точки и ориентируясь на бизнес-логику.
Определение аннотации привязки имени
Чтобы привязать фильтры к вашим конечным точкам REST, JAX-RS предоставляет мета-аннотацию @NameBinding
и ее можно использовать следующим образом:
@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Logged { }
Запись HTTP-запроса
Аннотация @Logged
будет использоваться для украшения класса фильтра, который реализует ContainerRequestFilter
, позволяя обрабатывать запрос:
@Logged
@Provider
public class RequestLoggingFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// Use the ContainerRequestContext to extract information from the HTTP request
// Information such as the URI, headers and HTTP entity are available
}
}
@Provider
аннотация отмечает реализацию интерфейса расширения, который должен быть обнаружен во время выполнения JAX-RS во время фазы сканирования поставщика.
ContainerRequestContext
помогает вам извлекать информацию из HTTP-запроса.
Ниже приведены методы из ContainerRequestContext
API для получения информации из HTTP-запроса, который может быть полезен для ваших журналов:
-
ContainerRequestContext#getMethod()
: Получить метод HTTP из запроса. -
ContainerRequestContext#getUriInfo()
: Получить информацию URI из HTTP-запроса. -
ContainerRequestContext#getHeaders()
: Получить заголовки из HTTP-запроса. -
ContainerRequestContext#getMediaType()
: получить тип носителя объекта. -
ContainerRequestContext#getEntityStream()
: Получить поток ввода сущности.
Запись ответа HTTP
Для регистрации ответа рассмотрите возможность использования ContainerResponseFilter
:
@Logged
@Provider
public class ResponseLoggingFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
// Use the ContainerRequestContext to extract information from the HTTP request
// Use the ContainerResponseContext to extract information from the HTTP response
}
}
ContainerResponseContext
помогает извлечь информацию из ответа HTTP.
Вот несколько методов из ContainerResponseContext
API, чтобы получить информацию из ответа HTTP, которая может быть полезна для ваших журналов:
-
ContainerResponseContext#getStatus()
: Получить код состояния из ответа HTTP. -
ContainerResponseContext#getHeaders()
: Получить заголовки из ответа HTTP. -
ContainerResponseContext#getEntityStream()
: получить выходной поток сущности.
Связывание фильтров с конечными точками
Чтобы привязать фильтр к вашим методам или классам конечных точек, аннотируйте их с помощью аннотации @Logged
, определенной выше. Для методов и/или классов, которые аннотируются, фильтры будут выполняться:
@Path("/")
public class MyEndpoint {
@GET
@Path("{id}")
@Produces("application/json")
public Response myMethod(@PathParam("id") Long id) {
// This method is not annotated with @Logged
// The logging filters won't be executed when invoking this method
...
}
@DELETE
@Logged
@Path("{id}")
@Produces("application/json")
public Response myLoggedMethod(@PathParam("id") Long id) {
// This method is annotated with @Logged
// The request logging filter will be executed before invoking this method
// The response logging filter will be executed before invoking this method
...
}
}
В приведенном выше примере фильтры регистрации будут выполняться только для myLoggedMethod(Long)
, поскольку он аннотируется с помощью @Logged
.
Дополнительная информация
Помимо методов, доступных в ContainerRequestContext
и ContainerResponseFilter
, вы можете добавить ResourceInfo
в свои фильтры, используя @Context
:
@Context
ResourceInfo resourceInfo;
Его можно использовать для получения Method
и Class
, которые соответствуют запрошенному URL:
Class<?> resourceClass = resourceInfo.getResourceClass();
Method resourceMethod = resourceInfo.getResourceMethod();
HttpServletRequest
и HttpServletResponse
также доступны для инъекций:
@Context
HttpServletRequest httpServletRequest;
@Context
HttpServletResponse httpServletResponse;
Обратитесь к этому answer для типов, которые могут быть введены @Context
.