java - traduccion - resteasy example
Solicitud de registro y respuesta en un solo lugar con JAX-RS (2)
Tengo un servidor web RESTEasy con muchos métodos. Quiero implementar logback para realizar un seguimiento de todas las solicitudes y respuestas, pero no quiero agregar log.info()
a todos los métodos.
Tal vez haya forma de capturar solicitudes y respuestas en un solo lugar y registrarlo. Tal vez algo como un filtro en la cadena de proceso de solicitud HTTP en RESTEasy.
@Path("/rest")
@Produces("application/json")
public class CounterRestService {
//Don''t want use log in controler every method to track requests and responces
static final Logger log = LoggerFactory.getLogger(CounterRestService.class);
@POST
@Path("/create")
public CounterResponce create(@QueryParam("name") String name) {
log.info("create "+name)
try {
CounterService.getInstance().put(name);
log.info("responce data"); // <- :((
return new CounterResponce();
} catch (Exception e){
log.info("responce error data"); // <- :((
return new CounterResponce("error", e.getMessage());
}
}
@POST
@Path("/insert")
public CounterResponce create(Counter counter) {
try {
CounterService.getInstance().put(counter);
return new CounterResponce();
} catch (Exception e){
return new CounterResponce("error", e.getMessage());
}
}
...
}
Pruebe los interceptores (no solo los interceptores EJB de vainilla puede usar CDI con eso).
Ellos están ahí para implementar preocupaciones transversales (aspectos).
Puede crear filtros y vincularlos fácilmente a los puntos finales que necesita registrar, manteniendo sus puntos finos y centrados en la lógica empresarial.
Definición de una anotación de enlace de nombre
Para enlazar los filtros a sus puntos finales REST, JAX-RS proporciona la meta-anotación @NameBinding
y se puede usar de la siguiente manera:
@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Logged { }
Registro de la solicitud HTTP
La anotación @Logged
se usará para decorar una clase de filtro, que implementa ContainerRequestFilter
, lo que le permite manejar la solicitud:
@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
}
}
La anotación @Provider
marca una implementación de una interfaz de extensión que debe ser detectable por el tiempo de ejecución de JAX-RS durante la fase de exploración del proveedor.
ContainerRequestContext
ayuda a extraer información de la solicitud HTTP.
Aquí hay métodos de la API ContainerRequestContext
para obtener información de la solicitud HTTP que puede ser útil para sus registros:
-
ContainerRequestContext#getMethod()
:ContainerRequestContext#getMethod()
el método HTTP de la solicitud. -
ContainerRequestContext#getUriInfo()
: obtiene información de URI de la solicitud HTTP. -
ContainerRequestContext#getHeaders()
: Obtenga los encabezados de la solicitud HTTP. -
ContainerRequestContext#getMediaType()
: Obtiene el tipo de medio de la entidad. -
ContainerRequestContext#getEntityStream()
: Obtiene el flujo de entrada de la entidad.
Registro de la respuesta HTTP
Para registrar la respuesta, considere implementar un 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
}
}
El ContainerResponseContext
ayuda a extraer información de la respuesta HTTP.
Aquí hay algunos métodos de la API ContainerResponseContext
para obtener información de la respuesta HTTP que puede ser útil para sus registros:
-
ContainerResponseContext#getStatus()
: Obtenga el código de estado de la respuesta HTTP. -
ContainerResponseContext#getHeaders()
: Obtenga los encabezados de la respuesta HTTP. -
ContainerResponseContext#getEntityStream()
: Obtiene el flujo de salida de la entidad.
Uniendo los filtros a sus puntos finales
Para enlazar el filtro a sus métodos o clases de puntos finales, @Logged
con la anotación @Logged
definida anteriormente. Para los métodos y / o clases que están anotados, los filtros se ejecutarán:
@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
...
}
}
En el ejemplo anterior, los filtros de registro se ejecutarán solo para myLoggedMethod(Long)
porque se anota con @Logged
.
Información Adicional
Además de los métodos disponibles en las interfaces ContainerRequestContext
y ContainerResponseFilter
, puede inyectar ResourceInfo
en sus filtros usando @Context
:
@Context
ResourceInfo resourceInfo;
Puede usarse para obtener el Method
y la Class
que coinciden con la URL solicitada:
Class<?> resourceClass = resourceInfo.getResourceClass();
Method resourceMethod = resourceInfo.getResourceMethod();
HttpServletRequest
y HttpServletResponse
también están disponibles para inyección:
@Context
HttpServletRequest httpServletRequest;
@Context
HttpServletResponse httpServletResponse;
Consulte esta answer para conocer los tipos que se pueden inyectar con @Context
.