containerresponse.java
来自「resetful样式的ws样例,一种面向资源的webservices服务」· Java 代码 · 共 359 行
JAVA
359 行
/* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://jersey.dev.java.net/CDDL+GPL.html * or jersey/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at jersey/legal/LICENSE.txt. * Sun designates this particular file as subject to the "Classpath" exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: "Portions Copyrighted [year] * [name of copyright owner]" * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */package com.sun.jersey.spi.container;import com.sun.jersey.impl.container.OutBoundHeaders;import com.sun.jersey.api.Responses;import com.sun.jersey.api.core.HttpResponseContext;import com.sun.jersey.impl.ResponseImpl;import java.io.IOException;import java.io.OutputStream;import java.net.URI;import java.util.List;import java.util.logging.Logger;import javax.ws.rs.WebApplicationException;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.MultivaluedMap;import javax.ws.rs.core.Response;import javax.ws.rs.ext.MessageBodyWriter;import javax.ws.rs.ext.RuntimeDelegate;import javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate;/** * Containers instantiate, or inherit, and provide an instance to the * {@link WebApplication}. * * @author Paul.Sandoz@Sun.Com */public class ContainerResponse implements HttpResponseContext { private static final Logger LOGGER = Logger.getLogger(ContainerResponse.class.getName()); private static final RuntimeDelegate rd = RuntimeDelegate.getInstance(); private ExtendedMessageBodyWorkers bodyContext; private ContainerRequest request; private ContainerResponseWriter responseWriter; private Response response; private int status; private MultivaluedMap<String, Object> headers; private Object entity; private boolean isCommitted; private CommittingOutputStream out; private final class CommittingOutputStream extends OutputStream { private OutputStream o; @Override public void write(byte b[]) throws IOException { commitWrite(); o.write(b); } @Override public void write(byte b[], int off, int len) throws IOException { commitWrite(); o.write(b, off, len); } public void write(int b) throws IOException { commitWrite(); o.write(b); } @Override public void flush() throws IOException { o.flush(); } @Override public void close() throws IOException { commitClose(); o.close(); } private void commitWrite() throws IOException { if (!isCommitted) { if (getStatus() == 204) setStatus(200); isCommitted = true; o = responseWriter.writeStatusAndHeaders(-1, ContainerResponse.this); } } private void commitClose() throws IOException { if (!isCommitted) { isCommitted = true; o = responseWriter.writeStatusAndHeaders(-1, ContainerResponse.this); } } }; /** * Instantate a new ContainerResponse. * * @param wa the web application. * @param request the container request associated with this response. * @param responseWriter the response writer */ public ContainerResponse( WebApplication wa, ContainerRequest request, ContainerResponseWriter responseWriter) { this.bodyContext = wa.getMessageBodyWorkers(); this.request = request; this.responseWriter = responseWriter; this.status = Responses.NO_CONTENT; } // ContainerResponse /** * Convert a header value, represented as a general object, to the * string value. * <p> * This method defers to {@link RuntimeDelegate#createHeaderDelegate} to * obtain a {@link HeaderDelegate} to convert the value to a string. * <p> * Containers may use this method to convert the header values obtained * from the {@link #getHttpHeaders} * * @param headerValue the header value as an object * @return the string value */ @SuppressWarnings("unchecked") public static String getHeaderValue(Object headerValue) { HeaderDelegate hp = rd.createHeaderDelegate(headerValue.getClass()); return hp.toString(headerValue); } /** * Write the response. * <p> * The status and headers will be written by calling the method * {@link ContainerResponseWriter#writeStatusAndHeaders} on the provided * {@link ContainerResponseWriter} instance. The {@link OutputStream} * returned from that method call is used to write the entity (if any) * to that {@link OutputStream}. An appropriate {@link MessageBodyWriter} * will be found to write the entity. * * @throws WebApplicationException if {@link MessageBodyWriter} cannot be * found for the entity with a 406 (Not Acceptable) response. * @throws java.io.IOException if there is an error writing the entity */ @SuppressWarnings("unchecked") public void write() throws IOException { if (isCommitted) return; if (entity == null) { responseWriter.writeStatusAndHeaders(-1, this); return; } MediaType contentType = getContentType(); if (contentType == null) { List<MediaType> mts = bodyContext.getMessageBodyWriterMediaTypes( entity.getClass(), null, null); contentType = request.getAcceptableMediaType(mts); if (contentType.isWildcardType() || contentType.isWildcardSubtype()) contentType = MediaType.APPLICATION_OCTET_STREAM_TYPE; getHttpHeaders().putSingle("Content-Type", contentType); } final MessageBodyWriter p = bodyContext.getMessageBodyWriter( entity.getClass(), null, null, contentType); // If there is no message body writer return a Not Acceptable response if (p == null) { LOGGER.severe("A message body reader for Java type, " + entity.getClass() + ", and MIME media type, " + contentType + ", was not found"); throw new WebApplicationException( Responses.notAcceptable().build()); } isCommitted = true; OutputStream os = responseWriter.writeStatusAndHeaders(-1, this); p.writeTo(entity, entity.getClass(), null, null, contentType, getHttpHeaders(), os); } /** * Reset the response to 204 (No content) with no headers. */ public void reset() { setResponse(Responses.noContent().build()); } /** * * @return the container response writer */ public ContainerResponseWriter getContainerResponseWriter() { return responseWriter; } /** * Set the container response writer. * @param responseWriter the container response writer */ public void setContainerResponseWriter(ContainerResponseWriter responseWriter) { this.responseWriter = responseWriter; } // HttpResponseContext public Response getResponse() { return response; } public void setResponse(Response response) { setResponse(response, null); } public void setResponse(Response r, MediaType contentType) { this.isCommitted = false; this.out = null; this.response = r = (r != null) ? r : Responses.noContent().build(); this.status = r.getStatus(); this.entity = r.getEntity(); // If HTTP method is HEAD then there should be no entity if (request.getHttpMethod().equals("HEAD")) this.entity = null; // Otherwise if there is no entity then there should be no content type else if (this.entity == null) { contentType = null; } if (r instanceof ResponseImpl) { this.headers = setResponseOptimal((ResponseImpl)r, contentType); } else { this.headers = setResponseNonOptimal(r, contentType); } } public boolean isResponseSet() { return response != null; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public Object getEntity() { return entity; } public void setEntity(Object entity) { this.entity = entity; checkStatusAndEntity(); } public MultivaluedMap<String, Object> getHttpHeaders() { if (headers == null) headers = new OutBoundHeaders(); return headers; } public OutputStream getOutputStream() throws IOException { if (out == null) out = new CommittingOutputStream(); return out; } public boolean isCommitted() { return isCommitted; } // private MediaType getContentType() { final Object mediaTypeHeader = getHttpHeaders().getFirst("Content-Type"); if (mediaTypeHeader instanceof MediaType) { return (MediaType)mediaTypeHeader; } else if (mediaTypeHeader != null) { return MediaType.valueOf(mediaTypeHeader.toString()); } return null; } private void checkStatusAndEntity() { if (status == 204 && entity != null) status = 200; else if (status == 200 && entity == null) status = 204; } private MultivaluedMap<String, Object> setResponseOptimal(ResponseImpl r, MediaType contentType) { return r.getMetadataOptimal(request, contentType); } private MultivaluedMap<String, Object> setResponseNonOptimal(Response r, MediaType contentType) { MultivaluedMap<String, Object> _headers = r.getMetadata(); if (_headers.getFirst("Content-Type") == null && contentType != null) { _headers.putSingle("Content-Type", contentType); } Object location = _headers.getFirst("Location"); if (location != null) { if (location instanceof URI) { URI absoluteLocation = request.getBaseUri().resolve((URI)location); _headers.putSingle("Location", absoluteLocation); } } return _headers; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?