Рассмотрят следующие объекты:Как настроить Джексон десериализатор для вложенных entites с весной Ботинками
package br.com.investors.domain.endereco;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.ComparisonChain;
import org.hibernate.validator.constraints.NotBlank;
import javax.persistence.*;
import java.io.Serializable;
import static com.google.common.base.Preconditions.checkArgument;
import static javax.persistence.GenerationType.SEQUENCE;
@Entity
public class Regiao implements Serializable, Comparable<Regiao> {
@Id
@GeneratedValue(strategy = SEQUENCE)
private Long id;
@Version
private Long version;
@NotBlank
@Column(length = 100, unique = true)
private String nome = "";
Regiao() {}
public Regiao(String nome) {
checkArgument(!Strings.isNullOrEmpty(nome), "Nome não pode ser vazio");
this.nome = nome;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Regiao) {
Regiao o = (Regiao) obj;
return Objects.equal(this.nome, o.nome);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(nome);
}
@Override
public int compareTo(Regiao o) {
return ComparisonChain.start()
.compare(this.nome, o.nome)
.result();
}
@Override
public String toString() {
return Objects.toStringHelper(getClass()).add("nome", nome).toString();
}
public Long getId() {
return id;
}
public Long getVersion() {
return version;
}
public String getNome() {
return nome;
}
}
и
package br.com.investors.domain.endereco;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.collect.ComparisonChain;
import org.hibernate.validator.constraints.NotBlank;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static javax.persistence.GenerationType.SEQUENCE;
@Entity
public class Cidade implements Serializable, Comparable<Cidade> {
@Id
@GeneratedValue(strategy = SEQUENCE)
private Long id;
@Version
private Long version;
@NotBlank
@Column(length = 100, unique = true)
private String nome = "";
@NotNull
@ManyToOne
private Regiao regiao;
@NotNull
@ManyToOne
private Estado estado;
Cidade() {}
public Cidade(String nome, Regiao regiao, Estado estado) {
checkArgument(!Strings.isNullOrEmpty(nome), "Nome não pode ser vazio");
checkNotNull(regiao, "Região não pode ser nulo");
checkNotNull(estado, "Estado não pode ser nulo");
this.nome = nome;
this.regiao = regiao;
this.estado = estado;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Cidade) {
Cidade o = (Cidade) obj;
return Objects.equal(this.nome, o.nome) &&
Objects.equal(this.estado, o.estado) &&
Objects.equal(this.regiao, o.regiao);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(nome, regiao, estado);
}
@Override
public int compareTo(Cidade o) {
return ComparisonChain.start()
.compare(this.estado, o.estado)
.compare(this.regiao, o.regiao)
.compare(this.nome, o.nome)
.result();
}
@Override
public String toString() {
return Objects.toStringHelper(getClass()).add("nome", nome).add("regiao", regiao).add("estado", estado).toString();
}
public Long getId() {
return id;
}
public Long getVersion() {
return version;
}
public String getNome() {
return nome;
}
public Regiao getRegiao() {
return regiao;
}
public Estado getEstado() {
return estado;
}
}
Я выкладываю в JSON к RestController
@RequestMapping(value = "/cidades", method = POST, consumes = APPLICATION_JSON_VALUE)
void inserir(@RequestBody Cidade cidade) {
repository.save(cidade);
}
Я использую конфигурации по умолчанию Spring Boot для сериализации и десериализации объектов.
Если я отправляю JSON, как это, она отлично работает:
{
"nome": "Cidade",
"regiao": "/10"
}
Но мне нужно отправить JSON как это:
{
"nome": "Cidade",
"regiao": {
"id": 10,
"version": 0,
"nome": "regiao"
}
}
Если я так, я получаю ошибку
{
"timestamp": "2015-04-02",
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "Could not read JSON: Template must not be null or empty! (through reference chain: br.com.investors.domain.endereco.Cidade[\"regiao\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Template must not be null or empty! (through reference chain: br.com.investors.domain.endereco.Cidade[\"regiao\"])",
"path": "/cidades/"
}
Выполнение некоторой отладки, я обнаружил, что Джексон пытается создать URI из свойства «regiao» отправленного объекта, ожидая строки шаблон типа "/ {id}". Я ищу его, но не могу найти правильный ответ.
Я видел некоторые связанные с этим проблемы в StackOverflow, но никто не работал для меня.
Можете ли вы, ребята, сказать, в чем дело?
Я думаю, что это всего лишь конфигурация, но не знаю, как и где.
Я также стараюсь избегать специальных сериализаторов и десериализаторов.
EDIT:
Если я отправляю JSON только с идентификаторами вложенных сущностей, как это:
{
"nome": "Cidade",
"estado": "10",
"regiao": "10"
}
Я получаю сообщение:
{
"timestamp": "2015-04-07",
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "Could not read JSON: Failed to convert from type java.net.URI to type br.com.investors.domain.endereco.Estado for value '10'; nested exception is java.lang.IllegalArgumentException: Cannot resolve URI 10. Is it local or remote? Only local URIs are resolvable. (through reference chain: br.com.investors.domain.endereco.Cidade[\"estado\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Failed to convert from type java.net.URI to type br.com.investors.domain.endereco.Estado for value '10'; nested exception is java.lang.IllegalArgumentException: Cannot resolve URI 10. Is it local or remote? Only local URIs are resolvable. (through reference chain: br.com.investors.domain.endereco.Cidade[\"estado\"])",
"path": "/cidades"
}
В I что правильный способ отправки вложенного объекта похож на «regiao»: «/ 10», я жестко кодирую это в своем Javascript для обхода:
function(item) {
item.regiao = "/" + item.regiao.id; //OMG
item.estado = "/" + item.estado.id; //OMG!!
if (item.id) {
return $http.put('/cidades/' + item.id, item);
} else {
return $http.post('/cidades', item);
}
}
Это работает, но это отстой. Как я могу исправить это в Javascript или настроить Джексона?
Чтение некоторых документов, что-то связано с UriToEntityConverter, но до сих пор не знает правильного способа настройки этого.
Спасибо.
Вы можете разместить поглотитель и сеттеры для relavant полей, то есть '' regiao' в Cidadae' и атрибуты 'Regiao 'вы пытаетесь опубликовать? –
Обновлено @ci_ объектов. Теперь вы можете увидеть полные классы. –
Как вы устанавливаете поля версии и id? Для них нет конструкторов или сеттеров. Попробуйте добавить сеттеры для всех ваших участников. Есть способы, чтобы он работал без него, но посмотрите, работает ли сначала сеттеры. –