/**
   * This implementation sets the default headers by calling {@link #addDefaultHeaders}, and then
   * calls {@link #writeInternal}.
   */
  @Override
  public final void write(final T t, MediaType contentType, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    final HttpHeaders headers = outputMessage.getHeaders();
    addDefaultHeaders(headers, t, contentType);

    if (outputMessage instanceof StreamingHttpOutputMessage) {
      StreamingHttpOutputMessage streamingOutputMessage =
          (StreamingHttpOutputMessage) outputMessage;
      streamingOutputMessage.setBody(
          new StreamingHttpOutputMessage.Body() {
            @Override
            public void writeTo(final OutputStream outputStream) throws IOException {
              writeInternal(
                  t,
                  new HttpOutputMessage() {
                    @Override
                    public OutputStream getBody() throws IOException {
                      return outputStream;
                    }

                    @Override
                    public HttpHeaders getHeaders() {
                      return headers;
                    }
                  });
            }
          });
    } else {
      writeInternal(t, outputMessage);
      outputMessage.getBody().flush();
    }
  }
 @Override
 protected void writeInternal(String t, HttpOutputMessage outputMessage)
     throws IOException, HttpMessageNotWritableException {
   MediaType contentType = outputMessage.getHeaders().getContentType();
   Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
   FileCopyUtils.copy(t, new OutputStreamWriter(outputMessage.getBody(), charset));
 }
 @Override
 public void write(JSONEntity entity, MediaType contentType, HttpOutputMessage outputMessage)
     throws IOException, HttpMessageNotWritableException {
   // First write the entity to a JSON string
   try {
     HttpHeaders headers = outputMessage.getHeaders();
     if (headers.getContentType() == null) {
       if (contentType == null
           || contentType.isWildcardType()
           || contentType.isWildcardSubtype()) {
         contentType = MediaType.APPLICATION_JSON;
       }
       if (contentType != null) {
         headers.setContentType(contentType);
       }
     }
     String jsonString = EntityFactory.createJSONStringForEntity(entity);
     long length =
         JSONEntityHttpMessageConverter.writeToStream(
             jsonString, outputMessage.getBody(), contentType.getCharSet());
     if (headers.getContentLength() == -1) {
       headers.setContentLength(length);
     }
   } catch (JSONObjectAdapterException e) {
     throw new HttpMessageNotWritableException(e.getMessage());
   }
 }
  public static HttpOutputMessage mockHttpOutputMessage() {
    final HttpHeaders headers = mock(HttpHeaders.class);

    final HttpOutputMessage message = mock(HttpOutputMessage.class);
    when(message.getHeaders()).thenReturn(headers);

    return message;
  }
  @Override
  protected void writeInternal(Object o, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    JsonEncoding encoding = getEncoding(outputMessage.getHeaders().getContentType());
    JsonGenerator jsonGenerator =
        this.objectMapper.getJsonFactory().createJsonGenerator(outputMessage.getBody(), encoding);
    try {
      if (this.prefixJson) {
        jsonGenerator.writeRaw("{} && ");
      }
      this.objectMapper.writeValue(jsonGenerator, o);
    } catch (JsonGenerationException ex) {
      throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
    }
  }
  @Override
  protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
    JsonGenerator generator =
        this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
    try {
      writePrefix(generator, object);

      Class<?> serializationView = null;
      FilterProvider filters = null;
      Object value = object;
      JavaType javaType = null;
      if (object instanceof MappingJacksonValue) {
        MappingJacksonValue container = (MappingJacksonValue) object;
        value = container.getValue();
        serializationView = container.getSerializationView();
        filters = container.getFilters();
      }
      if (type != null && value != null && TypeUtils.isAssignable(type, value.getClass())) {
        javaType = getJavaType(type, null);
      }
      ObjectWriter objectWriter;
      if (serializationView != null) {
        objectWriter = this.objectMapper.writerWithView(serializationView);
      } else if (filters != null) {
        objectWriter = this.objectMapper.writer(filters);
      } else {
        objectWriter = this.objectMapper.writer();
      }
      if (javaType != null && javaType.isContainerType()) {
        objectWriter = objectWriter.forType(javaType);
      }
      objectWriter.writeValue(generator, value);

      writeSuffix(generator, object);
      generator.flush();

    } catch (JsonProcessingException ex) {
      throw new HttpMessageNotWritableException("Could not write content: " + ex.getMessage(), ex);
    }
  }
  @Override
  public void write(
      final BufferedImage image, final MediaType contentType, final HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    if (outputMessage instanceof StreamingHttpOutputMessage) {
      StreamingHttpOutputMessage streamingOutputMessage =
          (StreamingHttpOutputMessage) outputMessage;
      streamingOutputMessage.setBody(
          new StreamingHttpOutputMessage.Body() {
            @Override
            public void writeTo(OutputStream outputStream) throws IOException {
              writeInternal(image, contentType, outputMessage.getHeaders(), outputStream);
            }
          });
    } else {
      writeInternal(image, contentType, outputMessage.getHeaders(), outputMessage.getBody());
    }
  }
  protected void writeJson(ResponseWrapper response, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());

    ObjectMapper mapper = new ObjectMapper();

    // Add support for jackson mixins
    JsonMixin[] jsonMixins = response.getJsonResponse().mixins();
    for (JsonMixin jsonMixin : jsonMixins) {
      mapper.addMixIn(jsonMixin.target(), jsonMixin.mixin());
    }

    JsonGenerator jsonGenerator =
        mapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
    try {
      mapper.writeValue(jsonGenerator, response.getOriginalResponse());
    } catch (IOException ex) {
      throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
    }
  }
  /**
   * This implementation delegates to {@link #getDefaultContentType(Object)} if a content type was
   * not provided, calls {@link #getContentLength}, and sets the corresponding headers on the output
   * message. It then calls {@link #writeInternal}.
   */
  public final void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    HttpHeaders headers = outputMessage.getHeaders();
    if (headers.getContentType() == null) {
      MediaType contentTypeToUse = contentType;
      if (contentType == null || contentType.isWildcardType() || contentType.isWildcardSubtype()) {
        contentTypeToUse = getDefaultContentType(t);
      }
      if (contentTypeToUse != null) {
        headers.setContentType(contentTypeToUse);
      }
    }
    if (headers.getContentLength() == -1) {
      Long contentLength = getContentLength(t, headers.getContentType());
      if (contentLength != null) {
        headers.setContentLength(contentLength);
      }
    }
    writeInternal(t, outputMessage);
    outputMessage.getBody().flush();
  }
  @Override
  public void write(F file, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {

    copy(file.getInputStream(), outputMessage.getBody());
  }