【问题标题】:JsonMappingException when calling a RESTful service调用 RESTful 服务时出现 JsonMappingException
【发布时间】:2017-07-11 14:16:54
【问题描述】:

我将 Java8 与 Spring、Hibernate 和 JPA 结合使用。

我有一个保存 Person 对象的 RESTful 服务:

@RequestMapping(value = "/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity<Person> savePerson(@RequestBody Person person) {
    try {
        person = personService.save(person);
        return new ResponseEntity<Person>(person, HttpStatus.OK);
    } catch (Exception e) {
        Person p = null;
        return new ResponseEntity<Person>(p, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

尝试merge Person 对象时出现以下错误:

16:02:58,472 警告 [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] (默认任务 11)未能读取 HTTP 消息: org.springframework.http.converter.HttpMessageNotReadableException: 无法读取文件:N/A at [来源: java.io.PushbackInputStream@7583d44c;行:29,列:3](通过 参考链:com.jobs.spring.domain.Person["blockedPersons"]); 嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:不适用 [来源: java.io.PushbackInputStream@7583d44c;行:29,列:3](通过 参考链:com.jobs.spring.domain.Person["blockedPersons"])

我猜是因为它谈到了“reference chain”,所以我可能有一些递归错误。或者由于某种原因,它正在努力将 Java 解析为 JSON 对象。

如果有人可以提供建议,我将不胜感激。

更多信息:

Person.java

@Entity
@Table(name = "person")
@XmlRootElement(name = "person")
public class Person extends AbstractDomain<Long> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinTable(name = "person_blocked", joinColumns = {
            @JoinColumn(name = "PER_ID", referencedColumnName = "ID") }, inverseJoinColumns = {
                    @JoinColumn(name = "BLOCK_ID", referencedColumnName = "ID", unique = true) })
    private Set<BlockedPerson> blockedPersons = null;

    ...
}

BlockedPerson.java

@Entity
@Table(name = "blocked_person")
@XmlRootElement(name = "blocked_person")
public class BlockedPerson extends AbstractDomain<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "ID", unique = true, nullable = false)
    private Integer id;

    @Column(name = "BLOCKED_PER_ID", nullable = false)
    private Long blockedPersonId;

    @XmlElement
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @XmlElement
    public Long getBlockedPersonId() {
        return blockedPersonId;
    }

    public void setBlockedPersonId(Long blockedPersonId) {
        this.blockedPersonId = blockedPersonId;
    }

}

【问题讨论】:

  • 如果你能告诉我们Person类会更容易。
  • 嗨 CrazySabbath,感谢您的回复。我确实有上面的Person 类显示有问题的@OneToMany 字段。您还希望我展示getter 和setters 吗? (我只是在添加此 @OneToMany 字段时才开始收到此错误)。
  • 我的错误,错过了粗体文本大声笑。您是否将实体直接传递给您的控制器?我会避免这种情况。你能显示 Person 类声明吗?和@RequestBody 打印?如果我是你,我会创建其他类,具有相同的字段并扩展可序列化。然后我会将这些类转换为 JPA 类。
  • 更重要的是,如果你使用的是spring,你可以在你的控制器类中添加RestController注解并移除@ResponseBody。
  • 我已经更新了上面的代码以显示Person 类定义。 “和@RequestBody 打印?”是什么意思?另外,在控制器中,我尝试用@RestController 替换@ResponseBody,但我得到:The annotation @RestController is disallowed for this location

标签: java json hibernate rest


【解决方案1】:

解决方案

上述错误的原因是我在Person 的setter 方法中遇到异常,该异常在null 对象上执行以下操作。

this.blockedPersons.clear();

修复:

改变:

private Set<BlockedPerson> blockedPersons = null;

到:

private Set<BlockedPerson> blockedPersons = new HashSet<BlockedPerson>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多