下面列出了怎么用javax.ws.rs.ext.WriterInterceptorContext的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
// If there is no annotation(like exception), we don't compress it
if (context.getAnnotations().length > 0) {
try {
this.compress(context);
} catch (Throwable e) {
LOG.warn("Failed to compress response", e);
/*
* FIXME: This will cause java.lang.IllegalStateException:
* Illegal attempt to call getOutputStream() after getWriter()
*/
throw e;
}
}
context.proceed();
}
@Override
public void aroundWriteTo(WriterInterceptorContext writerInterceptorContext)
throws IOException, WebApplicationException {
writerInterceptorContext
.setOutputStream(new ClientAbortExceptionOutputStream(writerInterceptorContext.getOutputStream()));
try {
writerInterceptorContext.proceed();
} catch (Exception e) {
for (Throwable cause = e; cause != null; cause = cause.getCause()) {
if (cause instanceof ClientAbortException) {
LogManager.getLogger().info("Client closed response too early.");
return;
}
}
throw e;
}
}
public void testWrapsInputStream(String contentType) throws WebApplicationException, IOException {
WriterInterceptorContext context = mockContext(contentType);
OutputStream os = mock(OutputStream.class);
when(context.getOutputStream()).thenReturn(os);
writeInterceptor.aroundWriteTo(context);
verifyZeroInteractions(os);
ArgumentCaptor<OutputStream> updatedOsCapture = ArgumentCaptor.forClass(OutputStream.class);
verify(context).setOutputStream(updatedOsCapture.capture());
verify(context).getMediaType();
verify(context).getOutputStream();
verify(context).proceed();
verifyNoMoreInteractions(context);
OutputStream updatedOs = updatedOsCapture.getValue();
// just make sure we have some wrapper
assertNotSame(os, updatedOs);
updatedOs.close();
verify(os).close();
}
@Test
public void testWrapsOutputStreamAlways() throws IOException {
WriterInterceptorContext context = mock(WriterInterceptorContext.class);
OutputStream os = mock(OutputStream.class);
when(context.getOutputStream()).thenReturn(os);
ArgumentCaptor<OutputStream> updatedOsCapture = ArgumentCaptor.forClass(OutputStream.class);
alwaysBase64WriteInterceptor.aroundWriteTo(context);
verify(alwaysBase64WriteInterceptor).isBase64(context);
verifyZeroInteractions(os);
verify(context).setOutputStream(updatedOsCapture.capture());
verify(context).proceed();
verify(context).getOutputStream();
verifyNoMoreInteractions(context);
OutputStream updatedOs = updatedOsCapture.getValue();
// just make sure we have some wrapper
assertNotSame(os, updatedOs);
updatedOs.close();
verify(os).close();
}
@Test
public void testSnappyWriterInterceptor() throws IOException {
SnappyWriterInterceptor writerInterceptor = new SnappyWriterInterceptor();
MultivaluedMap<String, Object> headers = new MultivaluedHashMap<>();
WriterInterceptorContext mockInterceptorContext = Mockito.mock(WriterInterceptorContext.class);
Mockito.when(mockInterceptorContext.getHeaders()).thenReturn(headers);
Mockito.when(mockInterceptorContext.getOutputStream()).thenReturn(new ByteArrayOutputStream());
Mockito.doNothing().when(mockInterceptorContext).setOutputStream(Mockito.any(OutputStream.class));
// call aroundWriteTo on mock
writerInterceptor.aroundWriteTo(mockInterceptorContext);
// verify that setOutputStream method was called once with argument which is an instance of SnappyFramedOutputStream
Mockito.verify(mockInterceptorContext, Mockito.times(1))
.setOutputStream(Mockito.any(SnappyFramedOutputStream.class));
}
/**
* <p>applyStreaming.</p>
*
* @param requestContext a {@link javax.ws.rs.container.ContainerRequestContext} object.
* @param context a {@link javax.ws.rs.ext.WriterInterceptorContext} object.
* @throws java.io.IOException if any.
*/
protected void applyStreaming(ContainerRequestContext requestContext, WriterInterceptorContext context)
throws IOException {
Object entity = context.getEntity();
StreamingProcess<Object> process = MessageHelper.getStreamingProcess(context.getEntity(), manager);
if (process != null) {
ContainerResponseContext responseContext =
(ContainerResponseContext) requestContext.getProperty(RESP_PROP_N);
responseContext.setStatusInfo(Response.Status.PARTIAL_CONTENT);
context.getHeaders().putSingle(ACCEPT_RANGES, BYTES_RANGE);
context.setType(StreamingOutput.class);
context.setEntity(new MediaStreaming(
entity,
requestContext.getHeaderString(MediaStreaming.RANGE),
process,
context.getMediaType(),
context.getHeaders()
)
);
}
}
/**
* {@inheritDoc}
*/
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
if (!context.getHeaders().containsKey(HttpHeaders.CONTENT_LENGTH)) {
Object entity = context.getEntity();
StreamingProcess<Object> process = MessageHelper.getStreamingProcess(entity, manager);
if (process != null) {
long length = process.length(entity);
if (length != -1)
context.getHeaders().putSingle(HttpHeaders.CONTENT_LENGTH, length);
}
}
context.proceed();
}
/**
* {@inheritDoc}
*/
@Override
public void aroundWriteTo(final WriterInterceptorContext writerInterceptorContext)
throws IOException, WebApplicationException {
final LoggingStream stream = (LoggingStream) writerInterceptorContext.getProperty(ENTITY_LOGGER_PROPERTY);
writerInterceptorContext.proceed();
final Object requestId = Requests.getProperty(LOGGING_ID_PROPERTY);
final long id = requestId != null ? (Long) requestId : _id.incrementAndGet();
StringBuilder b = (StringBuilder) writerInterceptorContext.getProperty(LOGGER_BUFFER_PROPERTY);
if (b == null) {
b = new StringBuilder();
writerInterceptorContext.setProperty(LOGGER_BUFFER_PROPERTY, b);
}
printPrefixedHeaders(b, id, RESPONSE_PREFIX, HeaderUtils.asStringHeaders(writerInterceptorContext.getHeaders()));
if (stream != null) {
log(stream.getStringBuilder(MessageUtils.getCharset(writerInterceptorContext.getMediaType())));
} else {
log(b);
}
}
protected void protectHttpHeadersIfNeeded(WriterInterceptorContext ctx, JwsHeaders jwsHeaders) {
if (protectHttpHeaders) {
JoseJaxrsUtils.protectHttpHeaders(ctx.getHeaders(),
jwsHeaders,
protectedHttpHeaders);
}
}
protected ResponseMethodStats doWrite(WriterInterceptorContext context) throws IOException, WebApplicationException {
ResponseMethodStats stats;
long start = System.nanoTime();
OutputStream originalOutputStream = context.getOutputStream();
CountingOutputStream countingStream = new CountingOutputStream(originalOutputStream);
context.setOutputStream(countingStream);
try {
context.proceed();
} finally {
long stop = System.nanoTime();
long time = TimeUnit.NANOSECONDS.toMillis(stop - start);
context.setOutputStream(originalOutputStream);
stats = (ResponseMethodStats) context.getProperty(RESPONSE_STATS_NAME);
if (stats == null) {
log.warn("No response stats found for " + getClass() + ". Using default.");
stats = new ResponseMethodStats();
}
RequestMethodStats requestStats = (RequestMethodStats) context.getProperty(REQUEST_STATS_NAME);
if (requestStats == null) {
log.warn("No request method stats found for " + getClass() + ". Using default.");
requestStats = new RequestMethodStats();
requestStats.callStartTime = stop + TimeUnit.MILLISECONDS.toNanos(1);
}
stats.serializationTime = time;
stats.loginTime = requestStats.getLoginTime();
stats.callTime = TimeUnit.NANOSECONDS.toMillis(stop - requestStats.getCallStartTime());
stats.bytesWritten = countingStream.getCount();
// Merge in the headers we saved in the postProcess call, if any.
putNew(stats.responseHeaders, context.getHeaders());
}
return stats;
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
String callback = getCallbackValue(JAXRSUtils.getCurrentMessage());
if (!StringUtils.isEmpty(callback)) {
context.getHeaders().putSingle(Message.CONTENT_TYPE,
JAXRSUtils.toMediaType(getMediaType()));
context.getOutputStream().write((callback + getPaddingEnd()).getBytes(StandardCharsets.UTF_8));
}
context.proceed();
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException {
// Only sign the request if we have a Body.
if (context.getEntity() != null) {
// skip digest if already set
if (addDigest
&& context.getHeaders().keySet().stream().noneMatch(DIGEST_HEADER_NAME::equalsIgnoreCase)) {
addDigest(context);
} else {
sign(context);
context.proceed();
}
}
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
final List<String> requestHeader = httpHeaders.getRequestHeader(HttpHeaders.ACCEPT_ENCODING);
if (requestHeader != null && requestHeader.contains("gzip")) {
// DO NOT CLOSE STREAMS
final OutputStream contextOutputStream = context.getOutputStream();
final GZIPOutputStream gzipOutputStream = new GZIPOutputStream(contextOutputStream);
context.setOutputStream(gzipOutputStream);
context.getHeaders().add(HttpHeaders.CONTENT_ENCODING, "gzip");
}
context.proceed();
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException {
MultivaluedMap<String, Object> responseHeaders = context.getHeaders();
Object rangeHeader = responseHeaders.getFirst("Content-Range");
// Use a custom header here
// Some clients needs to know the content length in response headers in order to display a loading state
// Browsers don't let programmers to change the default "Accept-Encoding" header, then we use a custom one.
String acceptEncoding = requestHeaders.getHeaderString("x-accept-encoding");
GZIPOutputStream gzipOutputStream = null;
if (acceptEncoding != null && acceptEncoding.equals("identity")) {
responseHeaders.add("Content-Encoding", "identity");
} else if (rangeHeader == null) {
responseHeaders.add("Content-Encoding", "gzip");
responseHeaders.remove("Content-Length");
gzipOutputStream = new GZIPOutputStream(context.getOutputStream(), DEFAULT_BUFFER_SIZE);
context.setOutputStream(gzipOutputStream);
}
try {
context.proceed();
} finally {
if (gzipOutputStream != null) {
gzipOutputStream.finish();
}
}
}
public void testDoesNotWrapInputStream(String contentType) throws WebApplicationException, IOException {
WriterInterceptorContext context = mockContext(contentType);
OutputStream os = mock(OutputStream.class);
when(context.getOutputStream()).thenReturn(os);
writeInterceptor.aroundWriteTo(context);
verifyZeroInteractions(os);
verify(context).getMediaType();
verify(context).proceed();
verifyNoMoreInteractions(context);
}
private static WriterInterceptorContext mockContext(String contentType) {
WriterInterceptorContext context = mock(WriterInterceptorContext.class);
if (contentType != null) {
when(context.getMediaType()).thenReturn(MediaType.valueOf(contentType));
}
return context;
}
@Override
public final void aroundWriteTo(WriterInterceptorContext context) throws IOException {
if (isBase64(context)) {
context.setOutputStream(Base64.getEncoder().wrap(context.getOutputStream()));
}
context.proceed();
}
@Test
public void testWrapsOutputStreamNever() throws IOException {
WriterInterceptorContext context = mock(WriterInterceptorContext.class);
OutputStream os = mock(OutputStream.class);
when(context.getOutputStream()).thenReturn(os);
neverBase64WriteInterceptor.aroundWriteTo(context);
verify(neverBase64WriteInterceptor).isBase64(context);
verify(context).proceed();
verifyNoMoreInteractions(context);
}
private void setContentTypeIfNeeded(JoseHeaders headers, WriterInterceptorContext ctx) {
if (contentTypeRequired) {
MediaType mt = ctx.getMediaType();
if (mt != null
&& !JAXRSUtils.mediaTypeToString(mt).equals(JoseConstants.MEDIA_TYPE_JOSE)) {
if ("application".equals(mt.getType())) {
headers.setContentType(mt.getSubtype());
} else {
headers.setContentType(JAXRSUtils.mediaTypeToString(mt));
}
}
}
}
protected void sign(WriterInterceptorContext writerInterceptorContext) {
Message m = JAXRSUtils.getCurrentMessage();
String method = "";
String path = "";
// We don't pass the HTTP method + URI for the response case
if (MessageUtils.isRequestor(m)) {
method = HttpUtils.getProtocolHeader(JAXRSUtils.getCurrentMessage(),
Message.HTTP_REQUEST_METHOD, "");
path = uriInfo.getRequestUri().getPath();
}
performSignature(writerInterceptorContext.getHeaders(), path, method);
}
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
Span span = buildSpan(context, "serialize");
try (Scope scope = tracer.activateSpan(span)) {
decorateWrite(context, span);
context.proceed();
} catch (Exception e) {
Tags.ERROR.set(span, true);
throw e;
} finally {
span.finish();
}
}
private void prepareProtectedHeader(JwsHeaders headers,
WriterInterceptorContext ctx,
JwsSignatureProvider signer,
boolean protectHttp) {
headers.setSignatureAlgorithm(signer.getAlgorithm());
setContentTypeIfNeeded(headers, ctx);
if (!encodePayload) {
headers.setPayloadEncodingStatus(false);
}
if (protectHttp) {
protectHttpHeadersIfNeeded(ctx, headers);
}
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException
{
MessageDigest digest = null;
try
{
digest = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException e)
{
throw new IllegalArgumentException(e);
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DigestOutputStream digestStream = new DigestOutputStream(buffer, digest);
OutputStream old = context.getOutputStream();
context.setOutputStream(digestStream);
try
{
context.proceed();
byte[] hash = digest.digest();
String encodedHash = Base64.getEncoder().encodeToString(hash);
context.getHeaders().putSingle("Content-MD5", encodedHash);
byte[] content = buffer.toByteArray();
old.write(content);
}
finally
{
context.setOutputStream(old);
}
}
@Override
public void aroundWriteTo(final WriterInterceptorContext context) throws IOException, WebApplicationException {
context.proceed();
read(context::getProperty, "write-request", RequestWritingStage.class)
.ifPresent(throwingConsumer(stage ->
context.setProperty("process-response", stage.write())));
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
handleMessage(PhaseInterceptorChain.getCurrentMessage());
context.setMediaType(MediaType.APPLICATION_JSON_TYPE);
context.proceed();
context.setMediaType(JAXRSUtils.toMediaType(getMediaType()));
}
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
boolean compress = false;
String ae = request.getHeader("accept-encoding");
if (ae != null && ae.indexOf("gzip") >= 0) {
compress = true;
}
if(compress) {
MultivaluedMap<String, Object> headers = context.getHeaders();
for(Object type : headers.get("content-type")) {
String ctype = type.toString();
if(ctype.contains("zip") ||
ctype.contains("compress") ||
ctype.contains("image")) {
compress = false;
break;
}
}
if(compress) {
headers.add("Content-Encoding", "gzip");
final OutputStream outputStream = context.getOutputStream();
context.setOutputStream(new GZIPOutputStream(outputStream));
}
}
context.proceed();
}
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
MultivaluedMap<String,Object> headers = context.getHeaders();
headers.add("Content-Encoding", "gzip");
final OutputStream outputStream = context.getOutputStream();
context.setOutputStream(new GZIPOutputStream(outputStream));
context.proceed();
}
/**
* {@inheritDoc}
*/
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
if (isWritable(context)) {
MultivaluedMap<String, Object> respHeaders = context.getHeaders();
ContainerRequestContext requestContext = requestProvider.get();
MultivaluedMap<String, String> reqHeaders = requestContext.getHeaders();
if (reqHeaders.containsKey(MediaStreaming.RANGE)) {
if (reqHeaders.containsKey(IF_RANGE)) {
String ifRangeHeader = reqHeaders.getFirst(IF_RANGE);
if (StringUtils.isBlank(ifRangeHeader)) {
return;
}
if (respHeaders.containsKey(HttpHeaders.ETAG)) {
if (MessageHelper.getHeaderString(respHeaders, HttpHeaders.ETAG)
.equals(ifRangeHeader)) {
applyStreaming(requestContext, context);
return;
}
}
if (respHeaders.containsKey(HttpHeaders.LAST_MODIFIED)) {
if (MessageHelper.getHeaderString(respHeaders, HttpHeaders.LAST_MODIFIED)
.equals(ifRangeHeader)) {
applyStreaming(requestContext, context);
}
}
} else {
applyStreaming(requestContext, context);
}
}
}
context.proceed();
}
/**
* <p>isWritable.</p>
*
* @param context a {@link javax.ws.rs.ext.WriterInterceptorContext} object.
* @return a boolean.
*/
protected boolean isWritable(WriterInterceptorContext context) {
return context.getEntity() != null
&& !Boolean.FALSE.equals(requestProvider.get().getProperty(MessageHelper.STREAMING_RANGE_ENABLED))
&& context.getHeaders().containsKey(HttpHeaders.CONTENT_LENGTH)
&& !(context.getEntity() instanceof MediaStreaming);
}
/**
* {@inheritDoc}
*/
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
Object entity = context.getEntity();
if (entity instanceof Images.Captcha || entity instanceof Captcha) {
context.setMediaType(IMG_TYPE);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, IMG_TYPE);
if (entity instanceof Captcha) {
Captcha captcha = (Captcha) entity;
context.setType(BufferedImage.class);
context.setEntity(captcha.getImage());
}
}
context.proceed();
}