Serialização LocalDateTime[RESOLVIDO]

11 respostas Resolvido
javaspringrest
C

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);
		}

	}

11 Respostas

E

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

C

Obrigado pela resposta, mas ao adicionar o classe o os objetos passados na função estão vindo nulos, você teve o mesmo problema?

E

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?

C

Não, pois ao enviar os dados do front para para a API mostrava o erro que citei no inicio do tópico.

E

Ok.

Você adicionou os GET e SET no objeto Agenda.java, pois o problema pode ser esse?

C

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;
	}

}
E

Tente o seguinte:

  • Remover a anotação -

    “cido18:

    @DateTimeFormat(iso = DateTimeFormat.ISO.TIME)

  • Atualizar a anotação

    “cido18:

    @JsonFormat(pattern = “dd-MM-yyyy HH:mm:ss”)

por

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd-MM-yyyy HH:mm:ss")

C

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?

I

Faça o teste no seu proprio main, usando object mapper com o register do localdate para serializar/deserializar.

E

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.

C
Solucao aceita

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));
}

}

Criado 9 de outubro de 2016
Ultima resposta 18 de out. de 2016
Respostas 11
Participantes 3