2015-11-07 63 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來優化查詢的獲取策略。