简体   繁体   English

Spring-Boot REST API 无法解析 int 数组

[英]Spring-Boot REST API can't parse int array

I'm trying to create a simple SpringBoot REST api following hyperskill.org's "Web Quiz Engine" project.我正在尝试按照 hyperskill.org 的“Web Quiz Engine”项目创建一个简单的 SpringBoot REST api。

But the Solve endpoint refuses to work.但是 Solve 端点拒绝工作。

Here's the controller:这是控制器:

@CrossOrigin(origins = "*")
@RestController
@RequestMapping("api")
@Validated
public class QuizController {

  //snip

  @PostMapping(value = "/quizzes/{id}/solve")
  public Result solveQuiz(@PathVariable Long id, @RequestBody int[] answer){
    return quizService.solveQuiz(id, answer);
  }
}

Here's my postman : stackoverflow disallows embedding images这是我的邮递员: stackoverflow 不允许嵌入图像

POST http://localhost:8889/api/quizzes/1/solve?id=1发布 http://localhost:8889/api/quizzes/1/solve?id=1

Body *raw身体 *生

{
 "answer": [2]
}

And the error:和错误:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `[I` from Object value (token `JsonToken.START_OBJECT`); org.springframework.http.converter.HttpMessageNotReadableException:JSON 解析错误:无法从 Object 值(令牌 `JsonToken.START_OBJECT`)反序列化类型为 `[I` 的值; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type [I from Object value (token `JsonToken.START_OBJECT`)嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException:无法反序列化类型的值[I from Object value (token `JsonToken.START_OBJECT`)

I get the same error when I run the provided tests.当我运行提供的测试时,我得到了同样的错误。 Everything works until it try's to call Solve.一切正常,直到它尝试调用 Solve。 What's most confusing is the type `[I`.最令人困惑的是类型 `[I`。 What is going on?到底是怎么回事?

Edit: Tried to follow the answer below:编辑:尝试遵循以下答案:

  @PostMapping(value = "/quizzes/{id}/solve")
  public Result solveQuiz(@PathVariable Long id, @Valid @RequestBody AnswerArray answer){
    return quizService.solveQuiz(id, answer.getAnswers());
  }

and AnswerArray:和答案数组:

@Data
public class AnswerArray {
  @NotNull
  private List<Integer> answers;
}

Now the error is:现在错误是:

Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument 1 in public engine.Entities.Result engine.Controller.QuizController.solveQuiz(java.lang.Long,engine.Entities.AnswerArray): [Field error in object 'answerArray' on field 'answers': rejected value [null];已解决 [org.springframework.web.bind.MethodArgumentNotValidException:公共 engine.Entities.Result engine.Controller.QuizController.solveQuiz(java.lang.Long,engine.Entities.AnswerArray) 中的参数1验证失败:[对象中的字段错误'answers' 字段上的 'answerArray':拒绝值 [null]; codes [NotNull.answerArray.answers,NotNull.answers,NotNull.java.util.List,NotNull];代码 [NotNull.answerArray.answers,NotNull.answers,NotNull.java.util.List,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [answerArray.answers,answers];参数 [org.springframework.context.support.DefaultMessageSourceResolvable: 代码 [answerArray.answers,answers]; arguments [];论据 []; default message [answers]];默认消息[答案]]; default message [must not be null]] ]默认消息 [不能为空]] ]

I also tried AnswerArray with an int[] and an Integer[] and also got null values.我还尝试了带有 int[] 和 Integer[] 的 AnswerArray,并且还得到了空值。 What am I missing?我错过了什么?

well you are not posting an int[]好吧,您没有发布int[]

this is your body:这是你的身体:

{
    "answer": [
        2
    ]
}

Which is actually a Object containing a list of integers这实际上是一个包含integers listObject

so your Java object should look as follows:因此您的 Java 对象应如下所示:

// The class can be named whatever
public class Request {
    
    private List<Integer> answer;

    // constructor

    // getters and setters
}

And the function should look like:该函数应如下所示:

public Result solveQuiz(@PathVariable Long id, @RequestBody Request answer){
    return quizService.solveQuiz(id, answer.getAnswer());
}

The int[] does need to be inside a class, but the other answer left out a critical bit of information: that class needs a no-arg constructor that has an empty body. int[] 确实需要在一个类中,但另一个答案遗漏了一个关键信息:该类需要一个具有空主体的无参数构造函数。 The default constructor works, but if you add an explicit constructor (or use Lombok's @Data), you no longer get the default.默认构造函数有效,但如果您添加显式构造函数(或使用 Lombok 的 @Data),则不再获得默认构造函数。 So adding a default constructor seems to be what I ultimately needed (by use of adding Lombok's @NoArgsConstructor).所以添加一个默认构造函数似乎是我最终需要的(通过使用添加 Lombok 的@NoArgsConstructor)。 Although I had tried that before, but Spring's lack of useful error info caused me to abandon it when there was another problem simultaneously.虽然我之前尝试过,但是 Spring 缺乏有用的错误信息导致我在同时出现另一个问题时放弃了它。

In summary solveQuiz needed the int[] wrapped in an object.总之,solveQuiz 需要将 int[] 包裹在一个对象中。 And that object needs an empty no-arg constructor (or default constructor), and Getter and Setter.并且该对象需要一个空的无参数构造函数(或默认构造函数),以及 Getter 和 Setter。 (or Lombok @NoArgsConstructor) (或龙目岛@NoArgsConstructor)

So Here's my wrapper object:所以这是我的包装对象:

@Data
@NoArgsConstructor
public class AnswerArray {
  @NotNull
  private int[] answer;
}

and my api function:和我的api函数:

  @PostMapping(value = "/quizzes/{id}/solve")
  public Result solveQuiz(@PathVariable Long id, @Valid @RequestBody AnswerArray answer){
    return quizService.solveQuiz(id, answer.getAnswer());
  }

The problem may also be intellij not correctly compiling the changes, A "Rebuild Project" might have ultimately been the fix.问题也可能是 intellij 没有正确编译更改,“重建项目”最终可能是修复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM