private void serializeMessage(
      ServerProviderFactory providerFactory,
      Message message,
      Response theResponse,
      OperationResourceInfo ori,
      boolean firstTry) {

    ResponseImpl response = (ResponseImpl) JAXRSUtils.copyResponseIfNeeded(theResponse);

    final Exchange exchange = message.getExchange();

    boolean headResponse =
        response.getStatus() == 200
            && firstTry
            && ori != null
            && HttpMethod.HEAD.equals(ori.getHttpMethod());
    Object entity = response.getActualEntity();
    if (headResponse && entity != null) {
      LOG.info(new org.apache.cxf.common.i18n.Message("HEAD_WITHOUT_ENTITY", BUNDLE).toString());
      entity = null;
    }

    Method invoked =
        ori == null
            ? null
            : ori.getAnnotatedMethod() != null ? ori.getAnnotatedMethod() : ori.getMethodToInvoke();

    Annotation[] annotations = null;
    Annotation[] staticAnns = ori != null ? ori.getOutAnnotations() : new Annotation[] {};
    Annotation[] responseAnns = response.getEntityAnnotations();
    if (responseAnns != null) {
      annotations = new Annotation[staticAnns.length + responseAnns.length];
      System.arraycopy(staticAnns, 0, annotations, 0, staticAnns.length);
      System.arraycopy(responseAnns, 0, annotations, staticAnns.length, responseAnns.length);
    } else {
      annotations = staticAnns;
    }

    response.setStatus(getActualStatus(response.getStatus(), entity));
    response.setEntity(entity, annotations);

    // Prepare the headers
    MultivaluedMap<String, Object> responseHeaders =
        prepareResponseHeaders(message, response, entity, firstTry);

    // Run the filters
    try {
      JAXRSUtils.runContainerResponseFilters(providerFactory, response, message, ori, invoked);
    } catch (Throwable ex) {
      handleWriteException(providerFactory, message, ex, firstTry);
      return;
    }

    // Write the entity
    entity = InjectionUtils.getEntity(response.getActualEntity());
    setResponseStatus(message, getActualStatus(response.getStatus(), entity));
    if (entity == null) {
      if (!headResponse) {
        responseHeaders.putSingle(HttpHeaders.CONTENT_LENGTH, "0");
        if (MessageUtils.getContextualBoolean(
            message, "remove.content.type.for.empty.response", false)) {
          responseHeaders.remove(HttpHeaders.CONTENT_TYPE);
          message.remove(Message.CONTENT_TYPE);
        }
      }
      HttpUtils.convertHeaderValuesToString(responseHeaders, true);
      return;
    }

    Object ignoreWritersProp = exchange.get(JAXRSUtils.IGNORE_MESSAGE_WRITERS);
    boolean ignoreWriters =
        ignoreWritersProp == null ? false : Boolean.valueOf(ignoreWritersProp.toString());
    if (ignoreWriters) {
      writeResponseToStream(message.getContent(OutputStream.class), entity);
      return;
    }

    MediaType responseMediaType =
        getResponseMediaType(responseHeaders.getFirst(HttpHeaders.CONTENT_TYPE));

    Class<?> serviceCls = invoked != null ? ori.getClassResourceInfo().getServiceClass() : null;
    Class<?> targetType = InjectionUtils.getRawResponseClass(entity);
    Type genericType =
        InjectionUtils.getGenericResponseType(
            invoked, serviceCls, response.getActualEntity(), targetType, exchange);
    targetType = InjectionUtils.updateParamClassToTypeIfNeeded(targetType, genericType);
    annotations = response.getEntityAnnotations();

    List<WriterInterceptor> writers =
        providerFactory.createMessageBodyWriterInterceptor(
            targetType,
            genericType,
            annotations,
            responseMediaType,
            message,
            ori == null ? null : ori.getNameBindings());

    OutputStream outOriginal = message.getContent(OutputStream.class);
    if (writers == null || writers.isEmpty()) {
      writeResponseErrorMessage(
          message, outOriginal, "NO_MSG_WRITER", targetType, responseMediaType);
      return;
    }
    try {
      boolean checkWriters = false;
      if (responseMediaType.isWildcardSubtype()) {
        Produces pM =
            AnnotationUtils.getMethodAnnotation(
                ori == null ? null : ori.getAnnotatedMethod(), Produces.class);
        Produces pC = AnnotationUtils.getClassAnnotation(serviceCls, Produces.class);
        checkWriters = pM == null && pC == null;
      }
      responseMediaType = checkFinalContentType(responseMediaType, writers, checkWriters);
    } catch (Throwable ex) {
      handleWriteException(providerFactory, message, ex, firstTry);
      return;
    }
    String finalResponseContentType = JAXRSUtils.mediaTypeToString(responseMediaType);
    if (LOG.isLoggable(Level.FINE)) {
      LOG.fine("Response content type is: " + finalResponseContentType);
    }
    responseHeaders.putSingle(HttpHeaders.CONTENT_TYPE, finalResponseContentType);
    message.put(Message.CONTENT_TYPE, finalResponseContentType);

    boolean enabled = checkBufferingMode(message, writers, firstTry);
    try {

      try {
        JAXRSUtils.writeMessageBody(
            writers,
            entity,
            targetType,
            genericType,
            annotations,
            responseMediaType,
            responseHeaders,
            message);

        if (isResponseRedirected(message)) {
          return;
        }
        checkCachedStream(message, outOriginal, enabled);
      } finally {
        if (enabled) {
          OutputStream os = message.getContent(OutputStream.class);
          if (os != outOriginal && os instanceof CachedOutputStream) {
            os.close();
          }
          message.setContent(OutputStream.class, outOriginal);
          message.put(XMLStreamWriter.class.getName(), null);
        }
      }

    } catch (Throwable ex) {
      logWriteError(firstTry, targetType, responseMediaType);
      handleWriteException(providerFactory, message, ex, firstTry);
    }
  }
Exemple #2
0
  protected ResponseBuilder setResponseBuilder(Message outMessage, Exchange exchange)
      throws Exception {
    Response response = exchange.get(Response.class);
    if (response != null) {
      outMessage
          .getExchange()
          .getInMessage()
          .put(Message.PROTOCOL_HEADERS, response.getStringHeaders());
      return JAXRSUtils.fromResponse(JAXRSUtils.copyResponseIfNeeded(response));
    }

    Integer status = getResponseCode(exchange);
    ResponseBuilder currentResponseBuilder = JAXRSUtils.toResponseBuilder(status);

    Message responseMessage =
        exchange.getInMessage() != null ? exchange.getInMessage() : exchange.getInFaultMessage();
    // if there is no response message, we just send the response back directly
    if (responseMessage == null) {
      return currentResponseBuilder;
    }

    Map<String, List<Object>> protocolHeaders =
        CastUtils.cast((Map<?, ?>) responseMessage.get(Message.PROTOCOL_HEADERS));

    boolean splitHeaders =
        MessageUtils.isTrue(outMessage.getContextualProperty(HEADER_SPLIT_PROPERTY));
    for (Map.Entry<String, List<Object>> entry : protocolHeaders.entrySet()) {
      if (null == entry.getKey()) {
        continue;
      }
      if (entry.getValue().size() > 0) {
        if (HttpUtils.isDateRelatedHeader(entry.getKey())) {
          currentResponseBuilder.header(entry.getKey(), entry.getValue().get(0));
          continue;
        }
        for (Object valObject : entry.getValue()) {
          if (splitHeaders && valObject instanceof String) {
            String val = (String) valObject;
            String[] values;
            if (val == null || val.length() == 0) {
              values = new String[] {""};
            } else if (val.charAt(0) == '"' && val.charAt(val.length() - 1) == '"') {
              // if the value starts with a quote and ends with a quote, we do a best
              // effort attempt to determine what the individual values are.
              values = parseQuotedHeaderValue(val);
            } else {
              boolean splitPossible =
                  !(HttpHeaders.SET_COOKIE.equalsIgnoreCase(entry.getKey())
                      && val.toUpperCase().contains(HttpHeaders.EXPIRES.toUpperCase()));
              values = splitPossible ? val.split(",") : new String[] {val};
            }
            for (String s : values) {
              String theValue = s.trim();
              if (theValue.length() > 0) {
                currentResponseBuilder.header(entry.getKey(), theValue);
              }
            }
          } else {
            currentResponseBuilder.header(entry.getKey(), valObject);
          }
        }
      }
    }
    String ct = (String) responseMessage.get(Message.CONTENT_TYPE);
    if (ct != null) {
      currentResponseBuilder.type(ct);
    }
    InputStream mStream = responseMessage.getContent(InputStream.class);
    currentResponseBuilder.entity(mStream);

    return currentResponseBuilder;
  }