cido18
Outubro 9, 2016, 9:35pm
#1
Olá a todos,
Estou tentando serializar um objeto que possui uma data com a classe LocalDateTime
utilizando o Spring Boot, mas o seguinte erro:
2016-10-09 18:28:26.218 WARN 17395 — [ XNIO-2 task-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Text ‘2016-10-09T13:00:00.000Z’ could not be parsed at index 2 (through reference chain: br.com.wt.agendadoador.modelo.Agenda[“date”]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Text ‘2016-10-09T13:00:00.000Z’ could not be parsed at index 2 (through reference chain: br.com.wt.agendadoador.modelo.Agenda[“date”])
Fiz algumas pesquisas mas não consegui encontrar o motivo…
Trecho da classe:
@Entity
public class Agenda {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="doador_id")
@JsonProperty
private Doador doador;
@Enumerated(EnumType.STRING)
private StatusAgenda statusAgenda;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name="laboratorio_id")
@JsonProperty
private Laboratorio laboratorio;
@JsonFormat(pattern = "dd-MM-yyyy HH:mm:ss")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
private LocalDateTime date;
Minha configuração no application.properties e Jackson-datetype-jrs310:
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS =false
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>`
Por fim o Controller
@RestController
@RequestMapping(value = "agenda")
public class AgendaController {
@Autowired
private AgendaRepository agendaRepository;
@RequestMapping(value = "/", method = RequestMethod.POST,headers="Accept=application/json", produces = "application/json")
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
public ResponseEntity<Void> add(@Valid @RequestBody Agenda agenda) {
HttpHeaders headers = new HttpHeaders();
try {
agenda.setStatusAgenda(StatusAgenda.EMABERTO);
agendaRepository.save(agenda);
return new ResponseEntity<Void>(headers, HttpStatus.OK);
} catch (RuntimeErrorException e) {
System.out.println(e.getMessage());
return new ResponseEntity<Void>(headers, HttpStatus.NOT_ACCEPTABLE);
}
}
Olá @cido18 ,
Já passei por esse mesmo problema, minha sugestão é você remover a anotação @JsonDeserialize
em:
Pois com a dependência:
Já faz isso autômatico.
Então, adicione essa classe no ciclo de vida de injeção de dependência do Jackson
que resolve seu problema
https://gist.github.com/emanuelbatista/7996512a728bdc7ef5510214979ce386
cido18
Outubro 10, 2016, 1:12am
#3
Obrigado pela resposta, mas ao adicionar o classe o os objetos passados na função estão vindo nulos, você teve o mesmo problema?
Olá @cido18
Não tive o mesmo problema, mas posso ajudar com esse problema.
Antes de você adicionar essa nova classe esses parâmetros funcionavam na chamada ao Web Service?
cido18
Outubro 10, 2016, 12:15pm
#5
Não, pois ao enviar os dados do front para para a API mostrava o erro que citei no inicio do tópico.
Ok.
Você adicionou os GET e SET no objeto Agenda.java
, pois o problema pode ser esse?
cido18
Outubro 10, 2016, 1:16pm
#7
Adicionei sim. Segue a classe.
@Entity
public class Agenda {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne
@JoinColumn(name="doador_id")
@NotNull
private Doador doador;
@Enumerated(EnumType.STRING)
@NotBlank
private StatusAgenda statusAgenda;
@OneToOne
@JoinColumn(name="laboratorio_id")
@NotNull
private Laboratorio laboratorio;
@JsonFormat(pattern = "dd-MM-yyyy HH:mm:ss")
@DateTimeFormat(iso = DateTimeFormat.ISO.TIME)
@NotNull
private LocalDateTime date;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Doador getDoador() {
return doador;
}
public void setDoador(Doador doador) {
this.doador = doador;
}
public Laboratorio getLaboratorio() {
return laboratorio;
}
public void setLaboratorio(Laboratorio laboratorio) {
this.laboratorio = laboratorio;
}
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public StatusAgenda getStatusAgenda() {
return statusAgenda;
}
public void setStatusAgenda(StatusAgenda statusAgenda) {
this.statusAgenda = statusAgenda;
}
@Override
public String toString() {
return "Agenda [id=" + id + ", doador=" + doador + ", statusAgenda=" + statusAgenda + ", laboratorio="
+ laboratorio + ", date=" + date + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((date == null) ? 0 : date.hashCode());
result = prime * result + ((doador == null) ? 0 : doador.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((laboratorio == null) ? 0 : laboratorio.hashCode());
result = prime * result + ((statusAgenda == null) ? 0 : statusAgenda.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Agenda other = (Agenda) obj;
if (date == null) {
if (other.date != null)
return false;
} else if (!date.equals(other.date))
return false;
if (doador == null) {
if (other.doador != null)
return false;
} else if (!doador.equals(other.doador))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (laboratorio == null) {
if (other.laboratorio != null)
return false;
} else if (!laboratorio.equals(other.laboratorio))
return false;
if (statusAgenda != other.statusAgenda)
return false;
return true;
}
}
Tente o seguinte:
Remover a anotação - [quote=“cido18, post:1, topic:336749”]
@DateTimeFormat (iso = DateTimeFormat.ISO.TIME)
[/quote]
Atualizar a anotação [quote=“cido18, post:1, topic:336749”]
@JsonFormat (pattern = “dd-MM-yyyy HH:mm:ss”)
[/quote]
por
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd-MM-yyyy HH:mm:ss")
cido18
Outubro 10, 2016, 10:38pm
#9
Olá @emanuelbatista ,
Desculpe a demora. Ainda não consegui resolver, mas pelos meus teste ao adicionar a @Configuration os dados passados para minha API são anulados. Será que não está faltando nenhum outro jar?
igomes
Outubro 11, 2016, 1:15am
#10
Faça o teste no seu proprio main, usando object mapper com o register do localdate para serializar/deserializar.
Meu caro @cido18
Segue esse tutorial -> https://blog.oio.de/2015/06/13/add-support-for-java-8-date-time-api-to-jackson-serialized-rest-web-services/
Que você vai conseguir resolver seu problema referente a conversão de datas do Java 8.
cido18
Outubro 18, 2016, 12:38pm
#12
Obrigado pela ajuda @igomes e @emanuelbatista
O problema no caso era os dados vindos do front corrigido isso resolvi a questão da conversão na seguinte maneira:
@Configuration
public class JacksonConfiguration {
@Autowired
private void registerSerializersDeserializers(List<ObjectMapper> objectMappers) {
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
simpleModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
objectMappers.forEach(objectMapper -> objectMapper.registerModule(simpleModule));
}
}