2017-09-08 122 views
1

我知道這個問題上的問題已經被問到,但是我發現的答案都沒有解決我的問題。使用列表和複選框的Spring MVC數據綁定

我在我的數據庫上有多對多的關係。我正在使用JPA和Hibernate來創建和修改我的表格。這裏是我的模型類:

Book.java

@Entity 
@Table(name="tb_books") 
public class Book implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", updatable = false, nullable = false, insertable = false) 
    private Integer id; 

    @Column(name = "title", nullable = false, length = 255) 
    private String title; 

    @Column(name = "author", nullable = false, length = 255) 
    private String author; 

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER) 
    @JoinTable(name = "book_tag", 
       joinColumns = { @JoinColumn(name = "fk_book") }, 
       inverseJoinColumns = { @JoinColumn(name = "fk_tag") }) 
    private List<Tag> tags; 

    //getters, setters, equals and hash methods... 

} 

Tag.java

@Entity 
@Table(name="tb_tags") 
public class Tag implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name = "id", updatable = false, nullable = false) 
    private Integer id; 

    @Column(name = "description", nullable = false, length = 255) 
    private String description; 

    //getters, setters, equals and hash methods... 
} 

我試圖使插入和更新我的book_tag表從JSP中正在添加數據使用Spring MVC。這是我的控制器和插入頁面:

BookController.java

@Controller 
@RequestMapping(value = "/book") 
public class BookController { 

    @Autowired 
    private BookService bookService; 

    /* 
     Controller method that gets us to the adding book page. 
    */  
    @RequestMapping(value = "/add", method = RequestMethod.GET) 
    public ModelAndView addBookPage() { 

     List<Tag> tags = tagService.getTags(); //all tags from the database 

     ModelAndView modelAndView = new ModelAndView("form-book"); 
     modelAndView.addObject("book", new Book()); 
     modelAndView.addObject("tags", tags); 

     return modelAndView; 
    } 

    @RequestMapping(value = "/add", method = RequestMethod.POST) 
    public ModelAndView addBookProcess(@ModelAttribute Book book) { 

     bookService.addBook(book); 
     return new ModelAndView("redirect:/book/add"); 
    } 

    //... 

} 

形式,book.jsp

<form:form method="POST" modelAttribute="book" action="${pageContext.request.contextPath}/book/add.html"> 
<table> 
    <tbody> 
     <tr> 
      <td>Title:</td> 
      <td><form:input path="title" autocomplete="off" /></td> 
     </tr> 
     <tr> 
      <td>Author:</td> 
      <td><form:input path="author" autocomplete="off" /></td> 
     </tr> 
     <tr> 
      <td colspan="2"> 

       <form:checkboxes path="tags" 
       items="${tags}" 
       itemLabel="description" 
       itemValue="id"/> 

      </td> 
     </tr> 
     <tr> 
      <td><input type="submit" value="Add" /></td> 
      <td><input type="button" onclick="location.href = '${pageContext.request.contextPath}/index'" value="Cancel"/></td> 
     </tr> 
    </tbody> 
</table> 

</form:form> 

一切工作正常,除非我嘗試更新或一個插入書或更多複選框被選中。當我嘗試這樣做時,我只是得到一個「錯誤的請求」頁面,我想象因爲我在做有關數據綁定的問題。

這是我應該如何處理這種情況?有沒有更好的辦法?我究竟做錯了什麼?

+0

我建這些文件在Spring的引導項目,它的工作原理爲我印刷。 –

+0

真的嗎?即使您在發送表單之前選擇了其中一個複選框,它也可以工作嗎? – DanielPDF

+0

https://github.com/alessandroscarlatti/so-9-8-2017-2 –

回答

1

顯然,來自複選框的列表實際上是一個字符串數組,它無法轉換爲定義模型類的標籤列表。

我通過創建一個自定義的PropertyEditor來解決我的問題,這將允許我將複選框與標記列表綁定。

public class TagPropertyEditor extends PropertyEditorSupport { 

    private TagService tagService; 

    public TagPropertyEditor(TagService tagService){ 
     this.tagService = tagService; 
    } 

    @Override 
    public String getAsText() { 
     return ((Tag) getValue()).getId().toString(); 
    } 

    @Override 
    public void setAsText(String incomingId) throws IllegalArgumentException { 
     Tag tag = tagService.getTag(Integer.valueOf(incomingId)); 
     setValue(tag); 
    } 
} 

,然後在我的BookController的註冊:

//... 
@InitBinder 
public void initBinder(WebDataBinder binder){ 
    binder.registerCustomEditor(Tag.class, new TagPropertyEditor(tagService)); 
} 

這是對我的JSP的checboxes標籤:

<form:checkboxes path="tags" 
        items="${tags}" 
        itemLabel="description" 
        itemValue="id"/>