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

Jackson自定义反序列化器字符串到List,并删除\r\n

闻人嘉木
2023-03-14

我从一个服务获得以下JSON作为响应。我使用Spring RestTemplate调用服务,该服务还将JSON反序列化回一个对象。我试图将其反序列化为一个对象,该对象除其他字段外还有一个列表。反序列化时出现以下错误:

Can not instantiate value of type [simple type, class com.org.EmployeeInfo] from String value; no single-String constructor/factory method.

下面是我想要反序列化的JSON:

{
    "employees": {       
        "employeeInfo": [
            "{\r\n  \"id\": \"123\",\r\n  \"group\": \"MARKETING\",\r\n  \"role\": \"MANAGER\",\r\n}",
            "{\r\n  \"id\": \"256\",\r\n  \"group\": \"IT\",\r\n  \"role\": \"DIRECTOR\",\r\n}",
            "{\r\n  \"id\": \"789\",\r\n  \"group\": \"SALES\",\r\n  \"role\": \"CEO\",\r\n}"
        ]
    },
    "status": "EMPLOYED",
    "somethingElse": {
        "something": []
    }
}

如果我有列表,默认反序列化器失败

我计划编写一个自定义反序列化程序,将其反序列化为具有列表的对象,并删除响应的一部分。我该怎么做?感谢您的回复。

这是我的POJO:

public class Response {
    private Employees employees;
    private String status;
    private SomethingElse somethingElse; 

   // getters, setters
}

public class Employees {
    List<EmployeeInfo> employeeInfo;
    // getters, setters
}

public class EmployeeInfo
{
   private String id, group, role;
   // getters, setters 
}

谢谢


共有2个答案

郎建章
2023-03-14

该JSON是无法解析的,因为它无效,即使您有自定义反序列化器,您也无法反序列化它。

无论如何,一个自定义反序列化器示例(不起作用,仅用于学习purpouse)

public class EmployeeInfoDeSerializer extends JsonDeserializer<List<EmployeeInfo>> {

    @Override
    public List<EmployeeInfo> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {

        // for learning purpouses only, does not work
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

        List<EmployeeInfo> employeeInfos = new ArrayList<>();

        while (jp.nextToken() != JsonToken.END_OBJECT) {

            if (jp.getCurrentToken() != JsonToken.END_ARRAY) {

                JsonParser jParser = mapper.getJsonFactory().createJsonParser(jp.getText());
                employeeInfos.add(jParser.readValueAs(EmployeeInfo.class));
            }
        }
        return employeeInfos;
    }
}

在您的员工课程中

public class Employees {

    @JsonDeserialize(using=EmployeeInfoDeSerializer.class)
    private List<EmployeeInfo> employeeInfo;

    public List<EmployeeInfo> getEmployeeInfo() {
        return employeeInfo;
    }

    public void setEmployeeInfo(List<EmployeeInfo> employeeInfo) {
        this.employeeInfo = employeeInfo;
    }


}
施同
2023-03-14

我用以下方法解决了这个问题(一些逻辑需要优化)

public class EmployeeInfoJsonDeserializer extends JsonDeserializer<List<EmployeeInfo>> {

    @Override
    public List<EmployeeInfo> deserialize(final JsonParser jp, final DeserializationContext ctxt)
                    throws IOException, JsonProcessingException {

        final ObjectMapper mapper = (ObjectMapper) jp.getCodec();

        final JsonNode node = (JsonNode) mapper.readTree(jp);

        // TODO - Write the following logic in a better way
        String toStr = node.toString();
        toStr = StringUtils.replace(toStr, "\"{", "{");
        toStr = StringUtils.replace(toStr, "}\"", "}");
        toStr = StringUtils.remove(toStr, "\\r\\n");
        toStr = StringUtils.remove(toStr, "\\");

        final JsonNode newNode = mapper.readTree(toStr);

        final EmployeeInfo[] empInfo = mapper.convertValue(newNode, EmployeeInfo[].class);

        return Arrays.asList(empInfo);
    }
}

在Pojo中:

public class Employees {
       List<EmployeeInfo> employeeInfo;

       public List<EmployeeInfo> getEmployeeInfo() {
            return employeeInfo;
       }

       @JsonDeserialize(using = EmployeeInfoJsonDeserializer .class)
       public void setEmployeeInfo(final List<EmployeeInfo> employeeInfo) {
            this.employeeInfo= employeeInfo;
       }
}
 类似资料:
  • I'va是一个OID接口,可以由许多具体类型实现: 现在我有一个具有两个字段的对象,一个使用抽象接口类型(OID)定义,另一个使用具体类型(MyOID)定义 我想使用jackson以不同的方式序列化/反序列化字段,无论它们是使用抽象接口类型还是具体类型定义的: 注意,被序列化,包括类型信息(多态序列化),而被序列化为文本 为此,我将OID接口注释为: 并为每个具体类型分配了类型id: 最后,对容器

  • 我想反序列化表单中的类: 其中文本是加密的,反序列化应该在重建TestFieldEncryptedMessage实例之前取消对值的加密。 我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto 也就是说,我正在构建一个扩展SimpleModule的模块: 如您所见,设置了两个修饰符:EncryptedSerializerModif

  • 我需要编写一个方法,它接受一些对象、给定对象的类中存在的一些字段名和一些字段值。该值是字段的JSON序列化形式。该方法将获取该值并相应地反序列化它,如下所示: (我实际上只需要检索反序列化的值,而不需要重新设置它,但这使它成为一个更好的示例。)只要Jackson默认的反序列化足够,这就行了。现在让我们假设我有一个带有自定义(de)序列化程序的类: 一个可能的解决方案是手动检查注释。但是,我真的不想

  • 我使用Json-Jackson序列化/反序列化我的对象,并且与内置类配合得很好。 字符串、int等非常好。但是现在我必须序列化/反序列化以特定方式构建的对象。遵循声明: 如果我使用标准的序列化器/反序列化,它会向我显示一条错误消息,例如“java.lang.不支持的操作异常...”,因此它无法序列化/反序列化bobjs。 我如何以一般方式做到这一点,所以我不写3个序列化器/反序列化器,而是只告诉J

  • 我想通过扩展默认的反序列化器来创建自己的反序列化器,在其后面设置更多的值: 如您所见,我还想将此DTO母类重用于其他DTO。 我没有找到任何这样的例子。我真的是世界上第一个 反序列化的“AsUsual”(p,ctxt)应该是什么 我应该使用什么motherclass?JsonDeserializer/StdDeserializer/UntypedObjectDeserializer 反序列化程序会

  • 我有下面的JSON,我正试图使用Jackson API反序列化它 我基本上需要一个附件类,它有一个AttachmentFile对象列表,如下所示: 如何使用自定义反序列化器实现这一点? 谢谢