【问题标题】:RestTemplate + Jackson休息模板 + 杰克逊
【发布时间】:2013-08-20 06:38:01
【问题描述】:

我想使用 Spring 的 RestTemplate 和 Jackson 来使用 WebService。我已经学习了几个教程,并且已经到了创建 DAO 的地步。这是我获取所有域对象的方法:

// Create a Rest template
RestTemplate restTemplate = new RestTemplate();

// Create a list for the message converters

List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();

// Add the Jackson Message converter
messageConverters.add(new MappingJacksonHttpMessageConverter());

// Add the message converters to the restTemplate
restTemplate.setMessageConverters(messageConverters);

List<Station> resultList = Arrays.asList(restTemplate.getForObject(BASE_URL, Station[].class));

return resultList;

但是我的 Web Service 并没有立即返回一个 Station 对象数组,而是以这种方式更语义化的表达:

{"success":true,"message":"Records Retrieved Successfully","data":{"totalCount":"14","stations":[{"id":"1264","station":"Station 1","idJefatura":"1","syncDate":"2013-01-24 13:20:43"}, ...] }}

所以我的问题是,我不确定如何“告诉”RestTemplate 在“站”指示符之后立即解析对象列表,而不创建临时对象,这似乎不是正确的解决方案。

有没有办法为 RestTemplate 指定正确的语法?

编辑:我创建了一个这样的包装对象:

public class RestResponseObject {

    private boolean success;
    private String message;
    private Data data;

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public class Data {
        private int totalCount;
        private List<Station> stations;

        public int getTotalCount() {
            return totalCount;
        }

        public void setTotalCount(int totalCount) {
            this.totalCount = totalCount;
        }

        public List<Station> getStations() {
            return stations;
        }

        public void setStations(List<Station> estaciones) {
            this.stations= estaciones;
        }
    }
}

但是我正在努力使这个对象通用,因为我的对象列表在 JSON 响应中的键名取决于该域对象的类。

【问题讨论】:

    标签: spring jackson resttemplate


    【解决方案1】:

    这里有两种解决方案:

    1. 您可以编写自己的 Deserializer 实现,在其中解析 JSON 并仅获取电台列表并将其转换为 List 对象。 Deserializer 可以在 RestTemplate 上设置。看看怎么写custom desrializer for Jackson
    2. 您可以做的另一件事是编写一个映射 Rest 响应的类。此类应包含 List 对象作为成员变量。然后默认情况下 Spring 将转换为新类,您可以从该类中获取站点。

    这是一个例子。

    响应类

    public class MyResponseClass {
          // other variables
         private List<Station> stations; //it getters and setters
    }
    

    在休息客户端

    MyResponseClass response = restTemplate.getForObject(BASE_URL, MyResponseClass.class)
    List<Station> resultList = response.getStations()
    

    【讨论】:

    • 第二个解决方案是我首先想到的。但我不想为我的每个域对象创建不同的“包装对象”。这似乎有些“错误”。或者也许有一种方法可以制作一个通用的,因为我所有的 REST 响应都遵循相同的模式?
    • 如果您的所有响应都遵循相同的格式,那么您可以编写一个通用响应,其中 MyResponseClass 包含一个 List extends Data> 其中 Data 是 Station 的超类。这只是一个建议,我不确定 Spring 将如何处理这样的一般情况。您需要尝试一下并调整您的 JSON 响应。
    • 采用 Deserializer 路线是一个更好的解决方案,但是如果您需要隐蔽包含 Stations 以外的实体的响应,则需要以通用方式编写 deserializer。如果您只有 Station,请为此编写反序列化程序。
    • 我会看看他们两个。谢谢。
    • 我尝试了这两种解决方案,但我仍在苦苦思索如何使其余的消费者通用。问题在于我的 WS 响应的语法(对此我没有任何控制权)。站点列表前面是键“站”,而我的其余域对象将前面有一个与域对象名称类似的键。有没有办法按照这种模式概括 ws 消费?我已经在我原来的问题中发布了我的 Wrapper 类,但是使用自定义反序列化也会出现同样的问题(顺便说一下,我没有找到很多例子)
    猜你喜欢
    • 1970-01-01
    • 2017-08-19
    • 2019-04-16
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 2016-01-20
    • 2011-06-26
    • 1970-01-01
    相关资源
    最近更新 更多