2015-11-07 131 views
0

我有一个Rest控制器很奇怪的问题。我有一个非常基本的休息控制器。Spring Boot REST控制器问题

package com.therealdanvega.controller; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.PathVariable; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

import com.therealdanvega.domain.Post; 
import com.therealdanvega.service.PostService; 

@RestController 
public class PostController { 

    private PostService postService; 

    @Autowired 
    public PostController(PostService postService){ 
     this.postService = postService; 
    } 

    @RequestMapping("posts/test") 
    public String test(){ 
     return "test..."; 
    } 

    @RequestMapping(name="/posts/", method=RequestMethod.GET) 
    public Iterable<Post> list(){ 
     return postService.list(); 
    } 


} 

调用一个服务

package com.therealdanvega.service; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 

import com.therealdanvega.domain.Post; 
import com.therealdanvega.repository.PostRepository; 

@Service 
public class PostService { 

    private PostRepository postRepository; 

    @Autowired 
    public PostService(PostRepository postRepository){ 
     this.postRepository = postRepository; 
    } 

    public Iterable<Post> list(){ 
     return postRepository.findAll(); 
    } 

} 

调用一个存储库来获取数据。

package com.therealdanvega.repository; 

import java.util.List; 

import org.springframework.data.repository.CrudRepository; 
import org.springframework.stereotype.Repository; 

import com.therealdanvega.domain.Post; 

@Repository 
public interface PostRepository extends CrudRepository<Post, Long> { 

    Post findFirstByOrderByPostedOnDesc(); 

    List<Post> findAllByOrderByPostedOnDesc(); 

    Post findBySlug(String slug); 

} 

我使用的内存数据库的H2和我只有一个记录后在那里可以进入到H2控制台和运行再次选择Post表确认等等。

如果我访问/测试URL,我会得到我期待的是打印到浏览器的字符串“test ...”。如果我尝试列出所有帖子(也是只有1个),浏览器会一遍又一遍循环并继续打印出代表1帖子的JSON,以至于应用程序崩溃,我在控制台中看到这一点

2015年11月7日17:58:42.959 ERROR 5546 --- [NIO-8080-EXEC-1] oaccC [[[/] [DispatcherServlet的]:。Servlet.service()为 servlet的DispatcherServlet的抛出异常 java.lang.IllegalStateException:getOutputStream方法()已经被 呼吁该响应

这是我的浏览器看起来当我访问/职位应该只列出1

enter image description here

Post Domain Class 

package com.therealdanvega.domain; 

import java.util.Date; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.ManyToOne; 
import javax.persistence.Temporal; 
import javax.persistence.TemporalType; 

import org.springframework.data.annotation.CreatedDate; 


@Entity 
public class Post { 

    @Id @GeneratedValue 
    private Long id; 
    private String title; 

    @Column(columnDefinition = "TEXT") 
    private String body; 

    @Column(columnDefinition = "TEXT") 
    private String teaser; 

    private String slug; 

    @CreatedDate 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date postedOn; 

    @ManyToOne 
    private Author author; 

    @SuppressWarnings("unused") 
    private Post(){ 
    } 

    public Post(String title){ 
     this.setTitle(title); 
    } 

    // getters & setters 
} 

有谁知道我做错了或在这里失去了什么样的?为什么不只是以JSON格式显示1条记录?

+0

为什么不使用ResponseEntity来放置对象列表?我会跳过Iterable部分... – Marged

+0

你可以显示Post对象吗? –

+0

@已绑定我的意思是我可以但不是这RestController应该做什么?获取我拥有的数据并将其转换并返回JSON? – cfaddict

回答

3

看来你的Post对象有循环引用。 Post对象中的Author对象具有Posts对象等列表。尝试将@JsonIgnore注释放在发布对象的作者属性上。

您也可以使用@JsonBackReference@JsonManagedReference来解决问题。

Jackson documentation

对象引用,身份

@JsonManagedReference,@JsonBackReference:对注解的用于 表示和处理与对 匹配性能表示父/子关系@JsonIdentityInfo:使用类/属性注释 来指示对象标识将在 序列化/反序列化值时使用,例如多个ref单个Java对象可以正确反序列化。这可以用于 正确处理循环对象图和有向无环图。

+0

非常感谢! – cfaddict

1

我相信你的帖子域对象包含作者域对象,它反过来在它的帖子字段中包含该作者的所有帖子,而该作者又包含包含帖子的作者......你看我要去哪里有了这个。

您可能最好使用fetch or load graphs来优化查询的获取策略。