1
resposta

POST de um JSON com lista usando @RequestBody

Prezados,

Estou tentando fazer um POST de um JSON que contenha uma lista com um (ou mais) resposta(s). O exemplo é praticamente igual o visto nas vídeo-aulas, recebe com form e chama um método para conversão antes de persistir no banco.

    @PostMapping
    public ResponseEntity<TopicoDto> cadastrar(@RequestBody @Valid TopicoForm form, UriComponentsBuilder uriBuilder) {
        Topico topico = form.converter(cursoRepository, usuarioRepository);
        topicoRepository.save(topico);

        URI uri = uriBuilder.path("/topicos/{id}").buildAndExpand(topico.getId()).toUri();
        return ResponseEntity.created(uri).body(new TopicoDto(topico));
    }

Ao chamar o método converter da classe TopicoForm crio o novo Tópico que deveria ser salvo no banco.

    public Topico converter(CursoRepository cursoRepository, UsuarioRepository usuarioRepository) {
        Curso curso = cursoRepository.findByNome(nomeCurso);

        // Por enquanto passar deixar Aluno como autor padrão.
        Usuario usuario = usuarioRepository.findByNome("Aluno");

        return new Topico(titulo, mensagem, curso, usuario, respostas);
    }

JSON :

{
    "titulo":"Finalizando projeto Spring",
    "mensagem":"Texto da mensagem blablabla",
    "nomeCurso":"Spring Boot",
    "respostas":["Resposta 1", "Resposta 2"]
}

O erro que estou encontrando é na hora de construir essa Resposta recebida via JSON, mas não entendi muito bem: WARN 44937 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of br.com.alura.forum.modelo.Resposta (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Resposta1'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of br.com.alura.forum.modelo.Resposta (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('Resposta1') at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 5, column: 15] (through reference chain: br.com.alura.forum.controller.form.TopicoForm["respostas"]->java.util.ArrayList[0])]

Se eu alterar minha tudo no projeto pra resposta ser apenas uma String, funciona. Creio que o erro esteja justamente nessa parte de lidar com uma lista vindo via JSON.

1 resposta

Oi Rogério,

Do jeito que você está enviando a requisição, deveria ter uma classe form assim:

public class TopicoForm {

    private String titulo;
    private String mensagem;
    private String nomeCurso;
    private List<String> respostas;

}

Pois no json que você envia as respostas é um array de strings: "respostas":["Resposta 1", "Resposta 2"].

Se você quer enviar um objeto resposta, precisa alterar a classe para:

public class TopicoForm {

    private String titulo;
    private String mensagem;
    private String nomeCurso;
    private List<RespostaForm> respostas;

}
public class RespostaForm {

    private String mensagem;

}

E enviar o json assim:

{
    "titulo":"Finalizando projeto Spring",
    "mensagem":"Texto da mensagem blablabla",
    "nomeCurso":"Spring Boot",
    "respostas": [ 
        {"mensagem" : "Resposta 1"},
        {"mensagem" : "Resposta 2"}
    ]
}

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software