Vous pourriez avoir un ClientRequestFilter
comme suit, qui est une version simplifiée de LoggingFilter
Jersey:
import java.io.ByteArrayOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;
import javax.annotation.Priority;
import javax.ws.rs.ConstrainedTo;
import javax.ws.rs.RuntimeType;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;
@Priority(Integer.MIN_VALUE)
@ConstrainedTo(RuntimeType.CLIENT)
public class LoggingFilter implements ClientRequestFilter, WriterInterceptor {
private static final Logger LOGGER =
Logger.getLogger(LoggingFilter.class.getName());
private static final String ENTITY_STREAM_PROPERTY =
LoggingFilter.class.getName() + ".entityLogger";
private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
private static final int MAX_ENTITY_SIZE = 1024 * 8;
private void log(StringBuilder sb) {
LOGGER.info(sb.toString());
}
@Override
public void filter(ClientRequestContext context) throws IOException {
if (context.hasEntity()) {
OutputStream stream = new LoggingStream(context.getEntityStream());
context.setEntityStream(stream);
context.setProperty(ENTITY_STREAM_PROPERTY, stream);
}
}
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
LoggingStream stream = (LoggingStream)
context.getProperty(ENTITY_STREAM_PROPERTY);
context.proceed();
if (stream != null) {
log(stream.getStringBuilder(DEFAULT_CHARSET));
}
}
private class LoggingStream extends FilterOutputStream {
private final StringBuilder b = new StringBuilder();
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
LoggingStream(final OutputStream inner) {
super(inner);
}
StringBuilder getStringBuilder(final Charset charset) {
// write entity to the builder
final byte[] entity = baos.toByteArray();
b.append(new String(entity, 0,
Math.min(entity.length, MAX_ENTITY_SIZE), charset));
if (entity.length > MAX_ENTITY_SIZE) {
b.append("...more...");
}
b.append('\n');
return b;
}
@Override
public void write(final int i) throws IOException {
if (baos.size() <= MAX_ENTITY_SIZE) {
baos.write(i);
}
out.write(i);
}
}
}
Et inscrivez-vous à votre Client
:
Client client = ClientBuilder.newClient().register(LoggingFilter.class);
Merci pour cette réponse détaillée! – Sebastian
+1 pour l'excellente réponse, cela m'a beaucoup aidé. J'ai juste une petite question: comment adapteriez-vous cela pour enregistrer la réponse au lieu de la demande? Lorsque je le change pour implémenter ClientResponseFilter et changer le contexte de filtre en objet de contexte de réponse, je me retrouve avec un InputStream au lieu d'un OutputStream, et je n'arrive pas à comprendre comment aller de l'avant avec ce point. – Tim
Merci pour le code détaillé, fonctionne parfaitement pour moi. Ajout de quelques extras pour notre configuration de journalisation. – kdoteu