当前位置: 首页 > 知识库问答 >
问题:

包含泛型类型对象的java jackson parse对象

安高义
2023-03-14

我有以下问题。

我必须将json请求解析为包含泛型类型字段的对象。

编辑

我使用常规类类型进行了一些测试(因此我在将其替换为泛型之前使其工作)。现在解析单个元素效果很好。

问题是何时需要从该类中解析出列表对象。

所以我不得不告诉jackson,我的T是list类型,而不仅仅是AlbumModel。

这是我尝试过的。

 @Override
    public ListResponseModel<AlbumModel> parse(String responseBody) throws Exception {
    JavaType type = mapper.getTypeFactory().constructParametricType(ResponseModel.class,
        AlbumModel.class);
    return mapper.readValue(responseBody,
        mapper.getTypeFactory().constructParametricType(ResponseModel.class, type));
    }

但是上面的代码不起作用。这种情况的解决方案是什么?

我的泛型类型在List响应模型中的定义如下:List

已成功,如:

public class BaseResponseModel<T> {

    @JsonProperty("data")
    private T data;

    @JsonProperty("paginations")
    private PaginationModel pagination;
}

到目前为止,我有以下代码,但它总是解析为哈希。

public class ResponseParser extends BaseJacksonMapperResponseParser<ResponseModel<AlbumModel>> {

    public static final String TAG = ResponseParser.class.getSimpleName();

    @Override
    public ResponseModel<AlbumModel> parse(String responseBody) throws Exception {
        return mapper.readValue(responseBody,
                mapper.getTypeFactory().constructParametricType(ResponseModel.class, AlbumModel.class));
    }
}

public abstract class BaseJacksonMapperResponseParser<T> implements HttpResponseParser<T> {

    public static final String TAG = BaseJacksonMapperResponseParser.class.getSimpleName();

    public static ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.disable(Feature.FAIL_ON_UNKNOWN_PROPERTIES);
        mapper.enable(Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        mapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
    }

}

共有3个答案

苏洛城
2023-03-14

由于您使用的是Jackson,您可能需要创建一个自定义JsonDeserializer或JsonSerializer,这取决于您是在处理响应还是请求。我这样做是因为在我的回答中,我想要一个标准的观点。我不是百分之百肯定它将与通用领域的工作,虽然。下面是我正在做的一个例子:

public class DateSerializer extends JsonSerializer<Date> {

    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZ");

    @Override
    public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        String dateString = dateFormat.format(value);
        jgen.writeString(dateString);
    }

}

然后我就像这样把它添加到我的类中:

@JsonSerialize(using = DateSerializer.class)
public Date getModifiedDate() {
    return modifiedDate;
}
谢夜洛
2023-03-14

您的类型T将在运行时被“擦除”,因此Jackson不知道什么是真正的T类型并将其反序列化为Map。您的解析方法需要第二个参数,它将是Class

编辑

关于TypeReference魔力的小说明。当您执行new XX(){}时,您正在创建一个匿名类,因此如果它是一个带有typevariables的类(如果您愿意,可以参数化),那么newX

abstract class MyGenericClass<T> {}
class MySpecializedClass extends MyGenericClass<List<Y>> {}

夏振国
2023-03-14

我同意尤金的回答,但我只是想再详细一点。第一步是重构您的解析方法,以便它使用第二个参数。您需要调用方传入一个TypeReference实例,而不是在方法中分配类型引用。

public BaseResponseModel<T> parse(String responseBody, TypeReference<T> ref) throws Exception {
    return mapper.readValue(responseBody, ref);
}

不幸的是,您的代码片段没有显示调用parse的代码,因此我将补充一些内容:

BaseResponseParser<Collection<Person>> parser = new BaseResponseParser<Collection<Person>>();
BaseResponseModel<Collection<Person>> result = parser.parse(jsonText, new TypeReference<Collection<Person>>(){});

请注意,在本例中编译TypeReference实例时,它是对我们期望的实际具体类的类型引用。

您可以在运行时执行同样的操作来传递类,但是TypeReference功能更强大,因为它甚至可以在类型T是泛型集合时工作。TypeReference实现中有一些魔力,允许它保留通常会被擦除的类型信息。

[更新]

更新为使用集合

 类似资料:
  • 现在,当我在地图上迭代时…我能以某种方式获得每个Class1对象的类型(K,V)吗??

  • 我已经编写了在android studio上显示可扩展列表视图的代码。以下是ExplandableListView的代码: 这是执行操作的方法: 它在函数定义中的“groupPosition”处显示警告: 当鼠标悬停在上面时,会显示

  • 我不想为每个类型T编写这个方法只是为了调用getMessage()并将其传递给下一个方法。 有可能写出这样的方法吗?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T(如字符串getMessage())。

  • 我在我们公司做项目,我有一个注入对象的问题。让我们考虑一下我有这个实体提供商: 并使用上面的实体提供程序扩展JPAContainer 问题是(我理解),我无法使用类类型定义@Inject对象,因为Inject方法需要一个空构造函数。这里有什么解决方案吗?如何让它发挥作用?现在我得到了一个例外 非常感谢您的回答:)Ondrej

  • 我有很多实体扩展了实体,也有很多数据扩展到 我有一个通用的存储库、服务和映射器,如下所示 我的仓库: 我的服务: 我的地图绘制者: 我想在方法中从T创建一个对象,在类中从方法中从Dto创建一个对象

  • 问题内容: 我的任务是用Java编写哈希表,该哈希表必须适用于任何数据类型。我正在编写的代码规则如下:-哈希表必须具有一个数组作为基础数据结构,其大小在构造对象时确定- 发生冲突时,应该放置碰撞的元素链接列表,该列表包含哈希表中该索引(键)处的所有元素 因此,对于基础数据类型,我做了一个LinkedList类型的数组(自定义,不是Java API LinkedList)。 当然,问题是实例化此数组