【问题标题】:Cannot construct instance of `class name` (although at least on Creator exists)无法构造“类名”的实例(尽管至少在 Creator 上存在)
【发布时间】:2019-07-28 15:51:42
【问题描述】:

我有以下类,我将其用作请求有效负载:

public class SampleRequest {

    private String fromDate;
    private String toDate;

    // Getters and setters removed for brevity.
}

我正在尝试将其与以下资源一起使用(只是尝试将其打印到屏幕上以查看发生的情况):

@PostMapping("/getBySignatureOne")
public ResponseEntity<?> getRequestInfo(@Valid @RequestBody SampleRequest signatureOneRequest) {

    System.out.println(signatureOneRequest.getToDate);
    System.out.println(signatureOneRequest.getFromDate);
}

这是我发送的 JSON 请求:

{
    "fromDate":"2019-03-09",
    "toDate":"2019-03-10"
}

这是我得到的错误:

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.test.app.payload.SampleRequest` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('fromDate'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.test.app.payload.SampleRequest` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('fromDate')
 at [Source: (PushbackInputStream); line: 1, column: 2]]

我很想知道这里出了什么问题,我怀疑这是构造函数的问题,或者我在某处遗漏了一些注释,但老实说我不确定我哪里出错了。

【问题讨论】:

  • 您的 JSON 请求是什么? SampleRequest 中有构造函数吗?如果是,您还需要有默认构造函数。
  • @cosmos - 呸,我知道我会忘记提供一些东西!我刚刚用我发送的 json 编辑了问题:)
  • 添加默认构造函数为我做了!

标签: java json spring jackson


【解决方案1】:

你需要一个带所有参数的构造函数:

public SampleRequest(String fromDate, String toDate) {

    this.fromDate = fromDate;
    this.toDate = toDate;

}

或者使用来自 lombok 的 @AllArgsConstructor@Data

【讨论】:

  • 啊,这样就解决了我的主要错误-但出于某种原因,当我将字段打印到屏幕上时,我似乎看到了空值...知道可能是什么原因造成的吗?如果我们不想破坏这个问题,我也碰巧为此提出了一个新问题!
  • @slippy 看我的帖子
【解决方案2】:

您好,您需要编写自定义反序列化器,因为它无法将字符串(fromDate 和 toDate)解析为日期

{ "fromDate":"2019-03-09", “迄今为止”:“2019-03-10” }

此链接有一个自定义反序列化器入门教程https://www.baeldung.com/jackson-deserialization

反序列化器可以这样写。

public class CustomDateDeserializer extends StdDeserializer<Date> {

private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");

public CustomDateDeserializer() {
    this(null);
}

public CustomDateDeserializer(Class<?> vc) {
    super(vc);
}

@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
    String date = jsonparser.getText();
    try {
        return formatter.parse(date);
    } catch (ParseException e) {
        throw new RuntimeException(e);
    }
}}

您可以像这样在 Class 本身注册反序列化器。

@JsonDeserialize(using = ItemDeserializer.class)
public class Item {  ...}

或者您可以像这样手动注册自定义反序列化器

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Item.class, new ItemDeserializer());
mapper.registerModule(module);

【讨论】:

    猜你喜欢
    • 2020-01-17
    • 2020-06-14
    • 1970-01-01
    • 2021-01-30
    • 2019-06-01
    • 2022-12-12
    • 2021-09-17
    • 2021-10-06
    • 1970-01-01
    相关资源
    最近更新 更多