java Kafka JSON对象错误:没有从String值反序列化的String参数构造函数/工厂方法

xoshrz7s  于 2023-08-01  发布在  Java
关注(0)|答案(1)|浏览(176)

我将这个JSON字符串从Kafka反序列化到java对象时出错。

{"type":"CASA","batchList":["CVA348856650375401ABC","BNM346846350035548DEF"]}

字符串
我的反序列化代码是这样的:

ObjectMapper objectMapper = new ObjectMapper();
 FooDTO fooDto = objectMapper.readValue(payload.value(), new TypeReference<FooDTO>() {});


我还尝试了以下方法

//objectMapper.readValue(payload.value(), FooDTO.class);
//objectMapper.readValue(objectMapper.writeValueAsString(object), FooDTO.class));
//objectMapper.readValue(objectMapper.writeValueAsString(object), new TypeReference<FooDTO>()));


什么都不管用然后我认为它与空格和下一行有关,因为当我在代码中手动添加json字符串时,即:String jsonString = "{\"type\":\"CASA\",\"batchList\":[\"CVA348856650375401ABC\",\"BNM346846350035548DEF\"]}";反序列化代码可以工作。
下一行或 "\n” 未删除。我尝试了以下方法:

String jsonStringReplace = payload.value().replace("\n", "");
String jsonStringTrim = payload.value().trim();
String jsonStringStrip = payload.value().strip();
String jsonStringRegex = payload.value().replaceAll("\\r|\\n", "");


都是这样的:

raw: "{\n \"type\": \"CASA\",\n  \"batchList\": [\n    \"CVA348856650375401ABC\",\n    \"BNM346846350035548DEF\"\n  ]\n}"
jsonStringRepAll: "{\n \"type\": \"CASA\",\n  \"batchList\": [\n    \"CVA348856650375401ABC\",\n    \"BNM346846350035548DEF\"\n  ]\n}"
jsonStringTrim: "{\n  \"type\": \"CASA\",\n  \"batchList\": [\n    \"CVA348856650375401ABC\",\n    \"BNM346846350035548DEF\"\n  ]\n}"
jsonStringStrip: "{\n  \"type\": \"CASA\",\n  \"batchList\": [\n    \"CVA348856650375401ABC\",\n    \"BNM346846350035548DEF\"\n  ]\n}"
jsonStringRegex: "{\n \"type\": \"CASA\",\n  \"batchList\": [\n    \"CVA348856650375401ABC\",\n    \"BNM346846350035548DEF\"\n  ]\n}"


我总是一遍又一遍地犯同样的错误:

Cannot construct instance of `sample.ms.dto.FooDTO` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{
  "type": "CASA",
  "batchList": [
    "CVA348856650375401ABC",
    "BNM346846350035548DEF"
  ]
}')


下面是代码:

@Incoming(KafkaConstants.KAFKA_TOPIC_REQUEST)
    @Acknowledgment(Acknowledgment.Strategy.POST_PROCESSING)
    @Blocking
    @Retry
    public Response consumeRequest(Record<String, String> payload) {
        log.info("+++++ START CONSUMING REQUEST +++++");
        log.debug("{} : {}", payload.key(), payload.value());
        try {
            if (Optional.ofNullable(payload.value()).isPresent()) {
 ObjectMapper objectMapper = new ObjectMapper();
     FooDTO fooDto = objectMapper.readValue(payload.value(), new TypeReference<FooDTO>() 
{});
...
}
}


下面的代码是DTO:

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Valid
public class FooDTO {

    //@NotNull
    private String batchKey;

    //@NotNull
    private String type;

    //@NotNull
    private List<String> batchList;
}

xtfmy6hx

xtfmy6hx1#

首先,在代码中不要为每个请求示例化一个新的ObjectMapper。将其作为具有您的方法consumeRequest的类的成员并重用它。此外,为了让你的代码更简单,你可以使用一个3d party实用程序JsonUtils,它是ObjectMapper类的一个薄 Package 器,可以在一行中完成你想要做的事情:

FooDTO fooDto = JsonUtils.readObjectFromJsonString(jsonStr, FooDTO.class);

字符串
您的String "{\"type\":\"CASA\",\"batchList\":[\"CVA348856650375401ABC\",\"BNM346846350035548DEF\"]}"应该可以正常工作。JsonUtils类附带由我编写和维护的MgntUtils开源库。下面是JsonUtils Javadoc,该库可以作为Maven artifactGitHub获得(包括源代码和Javadoc)

相关问题