Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Json Parse Error

Mensagem de erro: JSON parse error: Unexpected token (START_OBJECT), expected START_ARRAY:

Entidade JobForm:

public class JobForm {

    @NotNull
    private String name;
    @NotNull
    private BigDecimal valueOfService;
    @NotNull
    private LocalTime durationTime;

    public String getName() {
        return name;
    }

    public BigDecimal getValueOfService() {
        return valueOfService;
    }

    public LocalTime getDurationTime() {
        return durationTime;
    }

    public Job convert(){
        Job job = new Job();
        job.setName(this.name);
        job.setTimeOfDuration(this.durationTime);
        job.setValueOfService(this.valueOfService);
        return job;
    }

}

Metodo Post do controller:

    @PostMapping
    @Transactional
    @CacheEvict(value = "serviceList", allEntries = true)
    public ResponseEntity<Job> insert(@RequestBody @Valid JobForm jobForm, UriComponentsBuilder uriBuilder) {
        Job savedJob = serviceRepository.save(jobForm.convert());
        URI uri = uriBuilder.path("/service/{id}")
                .buildAndExpand(savedJob.getServiceId())
                .toUri();
        return ResponseEntity.created(uri).body(savedJob);
    }

maven:

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.6.0</version>
        </dependency>

Já tentei diversas anotações @JsonFormt, @JsonSerialize e JsonDeserialize com jackson e algumas outras e não obtive sucesso, fiz varias pesquisas e também não obtive sucesso.

7 respostas

Oi Rafael,

Na sua classe JobForm está faltando os métodos setters dos atributos e o Jackson utiliza os setters para preencher o objeto com as ifnromações recebidas nas API.

Outra coisa, posta aqui o json que você está enviando na requisição, pois pode ter algum problema nele.

Oi Professor.

Os Setters não resolveu... :(

o json que está sendo gerado no swagger é esse que no caso é o mesmo do cliente:

{
  "durationTime": {
    "hour": 0,
    "minute": 0,
    "second": 0,
    "nano": 0
  }
}

Se eu modificar para: "duarationTime":"10:10:10" funciona perfeitamente. O que acontece é que existe alguma configuração que está gerando(ou deve ser o padrão) essa "serialização" em objeto, dividindo os valores hora, minuto, segundo, e nano segundo quando na verdade eu preciso de uma simples string.

Ah sim, a questão então seria com a data.

Você pode alterar o padrão de formatação com a anotação @JsonFormat. Por exemplo:

@JsonFormat(pattern = "HH:mm:ss")
@NotNull
private LocalTime durationTime;

Não está resolvendo... Como eu disse, quando eu edito o json que vem como modelo no swagger e coloco "00:00:00" por exemplo ele funciona, porém lá no meu cliente ele ta vindo igual o modelo do swagger que é nesse formato de objeto que mencionei:

{
  "durationTime": {
    "hour": 0,
    "minute": 0,
    "second": 0,
    "nano": 0
  }
}

eu acredito que tenha duas formas de resolver, uma é configurando pra que não seja criado esse formato de objeto e sim o formato esperado "HH:mm:ss" , ou deserializar esse formato para que o controller receba o esperado. Já tentei varias configurações sem sucesso...

mensagem de erro: JSON parse error: Cannot deserialize value of type java.time.LocalTime from Object value (token JsonToken.START_OBJECT);

Rodrigo você pode simular no seu computador pra achar uma solução? Como eu falei, se você usar o postman e enviar a tempo como "HH:mm:ss por exemplo , funciona. O que acontece é no meu cliente que no caso é um app android nativo em Java onde uso repositório do retrofit o Json esta chegando naquele formato que mencionei

{
  "durationTime": {
    "hour": 0,
    "minute": 0,
    "second": 0,
    "nano": 0
  }
}

É a biblioteca do Jackson que gera esse formato por padrão? Sinceramente não sei mais o que faço, to quase apelando pra gambiarra hahaha.

Oi Rafael,

Ah sim! Então se não tiver como o cliente enviar no formato padrão, você vai precisar criar um "conversor", com uma classe dto para receber essa data como objeto com os campos separados e converter manualmente para LocalDateTime.

solução!

Finalmenteeeeee eu consegueguiii!!!!! hahaha dei um grito quando compilou, satisfação aspira! Eu estava insistindo no lado do servidor quando o problema era no cliente, eu não sabia que o retrofit também tinha a opção de usar a biblioteca do Jackson , sendo que eu tava usando Gson, tava dando incompatibilidade com a json gerado para a variável LocalTime, com duas linhas eu consegui resolver sem precisar deserializar nem fazer nada mirabolante ou gambiarra.