당신은 뉴저지의 LoggingFilter
의 단순화 된 버전 인 다음과 같은 ClientRequestFilter
, 수 :
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);
}
}
}
을 그리고 당신의 Client
에 등록 :
Client client = ClientBuilder.newClient().register(LoggingFilter.class);
이 자세한 답변을 주셔서 감사합니다! – Sebastian
+1 훌륭한 답변을 얻으려면이 방법이 도움이되었습니다. 나는 단지 하나의 작은 질문을 가지고있다 : 요청 대신 응답을 기록하기 위해 이것을 어떻게 적용 할 것인가? 내가 ClientResponseFilter을 구현하고 응답 문맥 객체에 필터 컨텍스트를 변경하는 변경하면, 나는의 InputStream 대신 OutputStream에와 끝까지, 그리고 그 시점에서 앞으로 이동하는 방법을 알아낼 수 없습니다. – Tim
자세한 코드를 보내 주셔서 감사합니다. 저에게 적합합니다. 우리의 로깅 구성을위한 몇 가지 추가 사항이 추가되었습니다. – kdoteu