我在Spring上从事API Rest项目。我有一个服务“ CreateMateriel”,它将参数数据JSON作为:
Materiel对象的JSON
{
"agence": 1,
"code": "001",
"type": "MyType"
}
“材料”与“法新社”有多对一的关系。我放置了一个@JsonIdentityInfo标记以使用Agence的Id而不是Agence的Object
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "idAgence")
@JsonIdentityReference(alwaysAsId = true)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "agence")
private Agence agence;
但是当我在POST / materiels上发送JSON时,我遇到了以下异常:
2017-05-16 18:00:53.021 WARN 8080 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Unresolved forward references for:
at [Source: java.io.PushbackInputStream@767dfd7a; line: 5, column: 1]Object id [1] (for fr.app.domain.Agence) at [Source: java.io.PushbackInputStream@767dfd7a; line: 2, column: 14].; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for:
at [Source: java.io.PushbackInputStream@767dfd7a; line: 5, column: 1]Object id [1] (for fr.app.domain.Agence) at [Source: java.io.PushbackInputStream@767dfd7a; line: 2, column: 14].
经过大量研究,我已经看到在JsonIdentityInfo中使用ObjectIdResolver
…但是我认为这不是最好的解决方案。这就是为什么我寻求您的帮助以发现问题的根源。谢谢
MaterielController.java
package fr.app.controllers;
import fr.app.domain.Materiel;
import fr.app.services.MaterielService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Collection;
@RestController @RequestMapping(value = "/materiels")
public class MaterielController {
@Resource
private MaterielService materielService;
@RequestMapping(method = RequestMethod.POST)
public Materiel createMateriel(@RequestBody Materiel materiel) {
return this.materielService.createMateriel(materiel);
}
@RequestMapping(method = RequestMethod.GET)
public Collection<Materiel> getAllMateriels() {
return this.materielService.getAllMateriels();
}
@RequestMapping(value = "/{code}", method = RequestMethod.GET)
public Materiel getMaterielByCode(@PathVariable(value = "code") String code) {
//find materiel by code
return this.materielService.getMaterielByCode(code);
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public void deleteMateriel(@PathVariable(value = "id") Long id) {
this.materielService.deleteMateriel(id);
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public Materiel updateMateriel(@PathVariable(value = "id") Long id, @RequestBody
Materiel materiel) {
materiel.setIdMateriel(id);
return this.materielService.updateMateriel(materiel);
}
}
Materiel.java
package fr.app.domain;
import com.fasterxml.jackson.annotation.*;
import javax.persistence.*;
@Entity
public class Materiel {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long idMateriel;
@Column(name = "type_materiel", nullable = false)
private String type;
@Column(name = "code_materiel", unique = true, nullable = false)
private String code;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "idAgence")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "agence")
private Agence agence;
public Materiel() { }
public Materiel(String type, String code, String dateScan) {
this.type = type;
this.code = code;
this.dateScan = dateScan;
}
public Long getIdMateriel() {
return idMateriel;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Agence getAgence() {
return agence;
}
public void setAgence(Agence agence) {
if(this.agence != null)
this.agence.deleteMateriel(this);
this.agence = agence;
this.agence.addMateriel(this);
}
}
MaterielService.java
package fr.app.services;
import fr.app.domain.Materiel;
import fr.app.repositories.MaterielRepository;
import org.apache.commons.collections.IteratorUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Collection;
@Service(value = "materielService")
public class MaterielServiceImpl implements MaterielService {
@Resource
private MaterielRepository materielRepository;
...
@Override
public Materiel createMateriel(Materiel materiel) {
return this.materielRepository.save(materiel);
}
...
}
Agence.java
package fr.app.domain;
import com.fasterxml.jackson.annotation.*;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
@Entity
public class Agence {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long idAgence;
@Column(name = "nom",unique = true, nullable = false)
private String nom;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "agence")
private Set<Materiel> materiels = new HashSet<Materiel>();
public Agence() { }
public Agence(String nom) {
this.nom = nom;
}
public Long getIdAgence() {
return idAgence;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public Set<Materiel> getMateriels() {
return materiels;
}
public void setMateriels(Set<Materiel> materiels) {
this.materiels = materiels;
}
public void addMateriel(Materiel materiel) {
this.materiels.add(materiel);
}
public void deleteMateriel(Materiel materiel) {
this.materiels.remove(materiel);
}
}
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.9.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.9.Final</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
<!-- Needed for JSON View -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
好的,我发现了问题。
最后,我需要添加解析器。所以我在这里找到一个实现的例子ObjectIDResolver
:
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.annotation.ObjectIdResolver;
import javax.persistence.EntityManager;
/**
* @author fta on 20.12.15.
*/
public class EntityIdResolver
implements ObjectIdResolver {
private EntityManager entityManager;
public EntityIdResolver(
final EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public void bindItem(
final ObjectIdGenerator.IdKey id,
final Object pojo) {
}
@Override
public Object resolveId(final ObjectIdGenerator.IdKey id) {
return this.entityManager.find(id.scope, id.key);
}
@Override
public ObjectIdResolver newForDeserialization(final Object context) {
return this;
}
@Override
public boolean canUseFor(final ObjectIdResolver resolverType) {
return false;
}
}
接下来我添加@JsonIdentityInfo
:
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "idAgence",
resolver = EntityIdResolver.class,
scope=Agence.class)
public class Agence {
// ...
}
问题内容: 我是C ++的新手。使用序列化和反序列化类型数据的最简单方法是什么。我发现了一些使用示例,但它们对我来说是晦涩的。 问题答案: 请注意,将键解释为路径,例如,将对“ ab” =“ z”放置将创建{“ a”:{“ b”:“ z”}} JSON,而不是{“ ab”:“ z”} 。否则,使用是微不足道的。这是一个小例子。
我想用Spring靴的方式来做这件事。
问题内容: 有岗位这里,询问如何通过返回EF4CTP5序列化对象时,解决循环引用错误。不久前,我在WCF Web表单项目中遇到了同样的问题。 我能够在WCF / Web窗体项目和MVC3项目中“解决”此问题。我认为什么类型的项目都不重要,因为这似乎是EF序列化的“事物”。 我通过在ObjectContext构造函数中禁用ProxyCreation来解决此问题,如下所示: 我的问题是:有人可以解释为
问题内容: 我正在尝试反序列化来自API的JSON响应。JSON如下所示(MAC地址和位置已更改): 问题在于措施措施。由于对象的名称正在更改,因此我不知道如何将其正确反序列化为C#对象。我在这里发现使用字典的解决方案存在类似问题,但是如果以这种方式尝试,我只会得到空目录。 这是我的反序列化方法: 这是APIResponse类: 有什么方法可以轻松地适当地反序列化这些措施吗? 问题答案: 看来您应
本文向大家介绍js序列化和反序列化的使用讲解,包括了js序列化和反序列化的使用讲解的使用技巧和注意事项,需要的朋友参考一下 (1)序列化 即js中的Object转化为字符串 1.使用obj.toJSONString() 2.使用JSON.stringify(obj) (2)反序列化 即js中JSON字符串转化为Object 1.使用eval('('+josnStr+')') 为什么要 eval这里
我正在开发一个应用程序,它使用Gson作为JSON反序列化器,需要从REST API反序列化多态JSON。在解释mi问题之前,请注意,我已经用Gson研究了多态反序列化,并在几个案例中成功地实现了它。这是我面临的一个具体问题。在问这个问题之前,我也读过这篇很棒的帖子和关于堆栈溢出的讨论。顺便说一下,我正在使用RuntimeTypeAdapterFactory来反序列化多态对象。 我遇到的问题是,G