set content-length using MappingJacksonHttpMessage

2019-07-23 09:03发布

I'm using Spring MVC to setup a REST controller that returns a JSON object, using MappingJacksonHttpMessageConverter.

How do I tell the MappingJacksonHttpMessageConverter to also set the "Content-Length" attribute on the response header ? (By default the "Content-Length" is set to -1, as the MappingJacksonHttpMessageConverter does not calculate the JSON object length).

I do not care if the content length calculation will affect the controller's response time (as the MappingJacksonHttpMessageConverter will need to buffer the marshalled JSON object in order to calculate its length).

This question was already asked, however not answered.

1条回答
Summer. ? 凉城
2楼-- · 2019-07-23 09:47

use my MappingJsonHttpMessageConverter instead of MappingJacksonHttpMessageConverter the writeInternal where I add ByteArrayOutputStream and Content-length

package org.zcoreframework.web.http.converter;


import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.SerializationFeature;


public class MappingJsonHttpMessageConverter extends MappingJackson2HttpMessageConverter {

    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {

        JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
        // The following has been deprecated as late as Jackson 2.2 (April 2013);
        // preserved for the time being, for Jackson 2.0/2.1 compatibility.
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        @SuppressWarnings("deprecation")
        JsonGenerator jsonGenerator =
                this.getObjectMapper().getJsonFactory().createJsonGenerator(byteArrayOutputStream, encoding);

        // A workaround for JsonGenerators not applying serialization features
        // https://github.com/FasterXML/jackson-databind/issues/12
        if (this.getObjectMapper().isEnabled(SerializationFeature.INDENT_OUTPUT)) {
            jsonGenerator.useDefaultPrettyPrinter();
        }

        try {
            this.getObjectMapper().writeValue(jsonGenerator, object);

            //--> set content length
            outputMessage.getHeaders().setContentLength(byteArrayOutputStream.size());      
            byteArrayOutputStream.writeTo(outputMessage.getBody());
            byteArrayOutputStream.flush();          
        }
        catch (JsonProcessingException ex) {
            throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
        }
    }
}
查看更多
登录 后发表回答