简体   繁体   中英

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.

But the Solve endpoint refuses to work.

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

POST 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`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type [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. What's most confusing is the type `[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]; codes [NotNull.answerArray.answers,NotNull.answers,NotNull.java.util.List,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [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. What am I missing?

well you are not posting an int[]

this is your body:

{
    "answer": [
        2
    ]
}

Which is actually a Object containing a list of integers

so your Java object should look as follows:

// 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. The default constructor works, but if you add an explicit constructor (or use Lombok's @Data), you no longer get the default. So adding a default constructor seems to be what I ultimately needed (by use of adding Lombok's @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.

In summary solveQuiz needed the int[] wrapped in an object. And that object needs an empty no-arg constructor (or default constructor), and Getter and Setter. (or Lombok @NoArgsConstructor)

So Here's my wrapper object:

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

and my api function:

  @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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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