Restlet复杂对象到XML序列化

时间:2015-02-28 12:32:29

标签: java xml serialization deserialization restlet-2.0

我有restlet web服务,它将响应返回为xml。我用杰克逊作为活页夹。 下面是I级返回。

 import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;

    public class ApiResponse<T> implements Serializable {

        /**
         * 
         */
        private static final long serialVersionUID = -2736991050157565598L;

        private int responseCode;
        private String reponseMessage;
        private List<T> body = new ArrayList<T>();

        public int getResponseCode() {
            return responseCode;
        }

        public void setResponseCode(int responseCode) {
            this.responseCode = responseCode;
        }

        public String getReponseMessage() {
            return reponseMessage;
        }

        public void setReponseMessage(String reponseMessage) {
            this.reponseMessage = reponseMessage;
        }

        public List<T> getBody() {
            return body;
        }

        public void setBody(List<T> body) {
            this.body = body;
        }

    }

以下是该服务的回复。除了将嵌套对象的属性名称与父对象相同之外,一切都很好。它显示了嵌套标签名称的正文,但我希望它是T模板。有什么想法吗?

<ApiResponse>
    <responseCode>1</responseCode>
    <reponseMessage />
     <body>
        <body>
          <reportId>1</reportId>
          <reportName>name1</reportName>
        </body>
        <body>
          <reportId>2</reportId>
          <reportName>name2</reportName>
        </body>
     </body>
</ApiResponse>

1 个答案:

答案 0 :(得分:2)

这是杰克逊的默认序列化。但是,您可以利用自定义序列化程序来改进这一点此功能允许您将杰克逊生成的内容放在特定课程中。您可以使用自己的策略覆盖默认策略,并以非常精细的方式配置将要创建的内容。

下面是为类SomeBean生成内容的此类实体示例:

public class SomeBeanSerializer extends JsonSerializer<SomeBean> {
    @Override
    public void serialize(SomeBean bean, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
                  JsonProcessingException {
        jgen.writeStartObject();

        // Fields
        jgen.writeNumberField("id", bean.getId());
        (...)

        // Link
        String href = (...)
        HypermediaLink linkToSelf = new HypermediaLink();
        linkToSelf.setHref(href + bean.getId());
        linkToSelf.setRel("self");
        jgen.writeObjectField("hypermediaLink", linkToSelf);

        jgen.writeEndObject();
    }
}

以下是在Restlet中配置它的方法:

JacksonConverter jacksonConverter = getRegisteredJacksonConverter();

if (jacksonConverter != null) {
    ObjectMapper objectMapper = jacksonConverter.getObjectMapper();
    SimpleModule module = new SimpleModule("MyModule", new Version(1, 0, 0, null));
    module.addSerializer(SomeBean.class, new SomeBeanSerializer());
    objectMapper.registerModule(module);
}

此链接可帮助您了解如何配置Restlet的Jackson转换器:https://templth.wordpress.com/2015/02/23/optimizing-restlet-server-applications/。它提供了方法getRegisteredJacksonConverter的内容。

已编辑:使用Restlet版本2.3,此级别会发生变化。对象映射器现在由JacksonRepresentation而不是JacksonConverter本身引入。现在,对于这种类型的每个表示,实例化对象映射器。这意味着您需要对这两个元素进行子类化以配置自定义序列化程序。

以下是类CustomJacksonRepresentation的代码:

public class CustomJacksonRepresentation<T>
                extends JacksonRepresentation<T> {
    @Override
    public ObjectMapper getObjectMapper() {
        if (this.objectMapper == null) {
            this.objectMapper = createObjectMapper();
            SimpleModule module = new SimpleModule("MyModule",
                                    new Version(1, 0, 0, null));
            module.addSerializer(SomeBean.class,
                               new SomeBeanSerializer());
            objectMapper.registerModule(module);
        }
        return this.objectMapper;
    }
}

以下是类CustomJacksonConverter的代码:

public class CustomJacksonConverter
                extends JacksonConverter {
    protected <T> JacksonRepresentation<T> create(
                        MediaType mediaType, T source) {
        return new CustomJacksonRepresentation<T>(
                                 mediaType, source);
    }

    protected <T> JacksonRepresentation<T> create(
              Representation source, Class<T> objectClass) {
        return new CustomJacksonRepresentation<T>(
                                 source, objectClass);
    }
}

实现后,您需要更换Restlet自动注册的现有jackson转换器。以下是执行此操作的代码:

// Looking for the registered jackson converter
JacksonConverter jacksonConverter = null;
List<ConverterHelper> converters
         = Engine.getInstance().getRegisteredConverters();
for (ConverterHelper converterHelper : converters) {
    if (converterHelper instanceof JacksonConverter) {
        jacksonConverter = (JacksonConverter) converterHelper;
        break;
    }
}

// converters
Engine.getInstance().getRegisteredConverters().remove(
                                       jacksonConverter);
CustomJacksonConverter customJacksonConverter
                          = new CustomJacksonConverter();
Engine.getInstance().getRegisteredConverters().add(
                                 customJacksonConverter);

您可以注意到,在Restlet的第3版中将重构管理转换器的方法,以便配置更方便! ; - )

希望它可以帮到你, 亨利