如何从客户端的 javax.ws.rs 实体中获取纯 XML
How to get plain XML from javax.ws.rs Entity on client side
我有一个 REST
客户端通过 Entity.entity(myObject, MediaType.APPLICATION_XML_TYPE)
创建了一个 XML
实体。在那之后,我打电话给 webTarget.request().buildPost(...
如何获取我的客户端将发送到服务器的请求正文XML
? (出于调试原因,我需要它。)我得到的只是一个 Entity
对象。
当然我可以自己用 Marshaller
序列化它,但这真的和客户端发送的 XML
一样吗?
你可以 ClientRequestFilter
as following, which is a simplified version of Jersey's LoggingFilter
:
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);
我有一个 REST
客户端通过 Entity.entity(myObject, MediaType.APPLICATION_XML_TYPE)
创建了一个 XML
实体。在那之后,我打电话给 webTarget.request().buildPost(...
如何获取我的客户端将发送到服务器的请求正文XML
? (出于调试原因,我需要它。)我得到的只是一个 Entity
对象。
当然我可以自己用 Marshaller
序列化它,但这真的和客户端发送的 XML
一样吗?
你可以 ClientRequestFilter
as following, which is a simplified version of Jersey's LoggingFilter
:
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);