【问题标题】:Deserializing JSON with Jersey and MOXy into a List collection使用 Jersey 和 MOXy 将 JSON 反序列化为 List 集合
【发布时间】:2014-10-08 06:21:19
【问题描述】:

我正在尝试获取 JSON 对象并将它们放入一个集合中(我选择了列表)。通过使用适当的 getter 和 setter 创建 BuiltCharacter,我已经能够将 JSON 响应解组为单个 POJO。对于 JSON 元素数组,我尝试了以下方法:

List<BuiltCharacter> characters = response.readEntity(new GenericType<List<BuiltCharacter>>(){});

List<BuiltCharacter> characters = client.target(uri).request(MediaType.APPLICATION_JSON).get(new GenericType<List<BuiltCharacter>>(){});

使用这些方法让我得到了以下结果:

线程“main”java.lang.ClassCastException 中的异常:BuiltCharacter 无法转换为 java.util.List

我最初使用 Character 作为类名,但被提醒这是一个保留的类名。不过,我不知道这里发生了什么!

【问题讨论】:

  • 您尝试反序列化的 JSON 看起来如何?真的是数组吗?
  • @MichalGajdos,这是我正在使用的示例:census.soe.com/get/ps2:v2/character/… 如果我尝试为此使用单个 POJO,我上面的两个代码示例实际上都会成功地将两个 JSON 元素读入一个目的。因此,当我查找 character.first_lower 时,它将返回“Dreadnaut”和“Daddy”。令人困惑!
  • 您愿意分享更多代码吗?可能是整个方法,甚至是 REST 资源类?
  • 嗨,我已经开始了这个赏金。你可以在这里看到一个例子:krishantha.net/notes/…。不起作用的是方法public List&lt;SalesType&gt; getSalesType() { WebTarget target = client .target("http://localhost:8080/SalesMonitor/webapi/"); List&lt;SalesType&gt; response = target.path("saletypes") .request(MediaType.APPLICATION_JSON).get(new GenericType&lt;List&lt;SalesType&gt;&gt;(){}); System.out.println(response); return response; },我得到SalesType cannot be cast to java.util.List
  • @George 请作为答案发布(注意它只是参考;您可以稍后将其删除)(1)您的资源类(2)SalesType 类(3)您的依赖项。我无法重现该问题。 OP 链接到的 JSON 是一个 JSON 对象,它不映射到列表。它需要是一个 JSON 数组。

标签: java json jersey moxy


【解决方案1】:

关于赏金的答案,但似乎与原帖中的问题相同

查看您提供的the link,所有示例都返回SalesType,而不是List&lt;SalesType&gt;。您不能指望将SalesType 转换为List&lt;SalesType&gt;。如果您从资源类返回 SalesType,则会提供异常。

即使来自the link 的原始帖子,JSON 也是作为 JSON 对象传入的。 List 不映射到 JSON 对象 ({}),而是映射到 JSON 数组 ([])。

如果您想要SalesType 的列表,则只需从资源中返回一个列表。下面是一个完整的例子

import java.util.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

class SalesType {
    public String test;
}
public class MOXyTest extends JerseyTest {

    @Path("test")
    public static class TestResource {

        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public Response getSalesTypeList() {
            List<SalesType> list = new ArrayList<>();
            SalesType sales = new SalesType();
            sales.test = "test";
            list.add(sales);
            list.add(sales);
            return Response.ok(
                   new GenericEntity<List<SalesType>>(list){}).build();
        }
    }

    @Override
    public Application configure() {
        return new ResourceConfig(TestResource.class);
    }

    @Test
    public void testGetSalesTypeList() {
        List<SalesType> list = target("test").request()
                .get(new GenericType<List<SalesType>>(){});
        for (SalesType sales: list) {
            System.out.println(sales.test);
        }
    }
}

这是我使用的两个依赖项(使用Jersey Test Framework

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-inmemory</artifactId>
    <version>${jersey2.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>${jersey2.version}</version>
</dependency>

您的问题可以通过在上面示例的资源类中返回sales 轻松重现。上面的当前代码有效,但只是为了查看错误,如果您替换 GenericEntity(这是在 Response 中返回的泛型类型的包装器),您将看到相同的错误

java.lang.ClassCastException: com.stackoverflow.jersey.test.SalesType
                              cannot be cast to java.util.List

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 2018-10-06
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多