[REST] json系列化有点问题

xyyz150 2015-06-27

最近做公司的api平台,用到了rop,帮助节省了很多工作量,先感谢作者。但是用到json序列化时遇到一个问题:服务端有一个打印:“输出响应”输出的json和返回到客户端的json不一致,发现是json序列化的代码不一致。

代码如下:

AnnotationServletServiceRouter 类

 writeResponse方法

 

 

private void writeResponse(Object ropResponse, HttpServletResponse httpServletResponse, MessageFormat messageFormat, String jsonpCallback) {
        try {
            if (!(ropResponse instanceof ErrorResponse) && messageFormat == MessageFormat.stream) {
                if (logger.isDebugEnabled()) {
                    logger.debug("使用{}输出方式,由服务自身负责响应输出工作.", MessageFormat.stream);
                }
                return;
            }
            if (logger.isDebugEnabled()) {
                logger.debug("输出响应:" + MessageMarshallerUtils.getMessage(ropResponse, messageFormat));
            }
            RopMarshaller ropMarshaller = xmlMarshallerRop;
            String contentType = APPLICATION_XML;
            if (messageFormat == MessageFormat.json) {
                ropMarshaller = jsonMarshallerRop;
                contentType = APPLICATION_JSON;
            }
            httpServletResponse.addHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
            httpServletResponse.addHeader(ACCESS_CONTROL_ALLOW_METHODS, "*");
            httpServletResponse.setCharacterEncoding(Constants.UTF8);
            httpServletResponse.setContentType(contentType);

            if (jsonpCallback != null) {
                httpServletResponse.getOutputStream().write(jsonpCallback.getBytes());
                httpServletResponse.getOutputStream().write('(');
            }
            ropMarshaller.marshaller(ropResponse, httpServletResponse.getOutputStream());
            if (jsonpCallback != null) {
                httpServletResponse.getOutputStream().write(')');
                httpServletResponse.getOutputStream().write(';');
            }
        } catch (IOException e) {
            throw new RopException(e);
        }
    }

 

 

里面输出响应的方法MessageMarshallerUtils.getMessage 对应类:

MessageMarshallerUtils初始化ObjectMapper方法

 

 

static {
        
        SerializationConfig serializationConfig = jsonObjectMapper.getSerializationConfig();
        serializationConfig = serializationConfig.without(SerializationConfig.Feature.WRAP_ROOT_VALUE)
                .with(SerializationConfig.Feature.INDENT_OUTPUT);



    }

 

 

输出到客户端ropMarshaller.marshaller对应的类:

JacksonJsonRopMarshaller类初始化objectMapper方法

 

private ObjectMapper getObjectMapper() throws IOException {
        if (this.objectMapper == null) {
            ObjectMapper objectMapper = new ObjectMapper();
            AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
            SerializationConfig serializationConfig = objectMapper.getSerializationConfig();
            serializationConfig = serializationConfig.without(SerializationConfig.Feature.WRAP_ROOT_VALUE)
                    .with(SerializationConfig.Feature.INDENT_OUTPUT)
                    .withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL)
                    .withSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY)
                    .withAnnotationIntrospector(introspector);
            objectMapper.setSerializationConfig(serializationConfig);
            this.objectMapper = objectMapper;
        }
        return this.objectMapper;
    }

 

 

这两个类的初始化不一致,导致了如下情况下会出bug

 

 

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "getDeliveryNoticestatusresponse")
public class GetDeliveryStatusResponse {
    @XmlElement(name = "iscancle")
    private boolean Cancle;

    public boolean getCancle() {
        return Cancle;
    }

    public void setCancle(boolean iscancle) {
        Cancle = iscancle;
    }
}

 

 

返回response的类如上所示,

那么在控制台用log4j打印的为:

2015-06-27 10:46:40,633 [org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean#0-2] DEBUG [com.rop.impl.AnnotationServletServiceRouter] - 输出响应:{"cancle":false}

 

而返回到客户端的打印为:

2015-06-27 10:46:40,642 [main] DEBUG [com.rop.client.DefaultRopClient] - {"iscancle":false}

 

即处理打印时方法没有加

AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();
serializationConfig.withAnnotationIntrospector(introspector);

 

没有考虑jaxb的注解别名,希望作者在MessageMarshallerUtils的初始化objectMapper时上能加上以上代码

 最后还是很感谢作者的rop

Global site tag (gtag.js) - Google Analytics