简体   繁体   中英

How to map a complex structure in jsp view to a model object in spring MVC

I'm using spring mvc for the first time and I'm trying to display and edit a structure in jsp.

I have a class Snippet, which holds a list of objects of type Sentence:

public class Snippet {
  private int id;
  private List<Sentence> sentences;
  // getters, setters, default constructor
}

public class Sentence {
  private int id;
  private int scale;
  private String text;
  // getters, setters, default constructor
}

In my controller I give a new snippet for editing and when user clicks "save" store it to my db, then return another one. Currently the sentences list of the snippet is null:

@RequestMapping("/snippet")
public ModelAndView getSnippet() {
  return new ModelAndView("snippet", "snippet", snippetService.getSnippet());
}

@RequestMapping("/save")
public ModelAndView saveSnippet(@ModelAttribute Snippet snippet) {
  if(snippet != null && snippet.getSentences() != null && !snippet.getSentences().isEmpty()) {
    snippetService.updateSnippet(snippet);
  }
  return new ModelAndView("snippet", "snippet", snippetService.getSnippet());
}

In my snippet.jsp I'd like to display the snippet sentences with their scale, and on save, pass snippet with sentences and scales to the controller for storage:

<form:form method="post" action="save" modelAttribute="snippet">
  ...
  <c:forEach var="sentence" items="${snippet.sentences}">
    <tr>
      <td>${sentence.id}</td>
      <td>${sentence.text}</td>
      <td><input type="range" name="sentence.scale" value="${sentence.scale}"
         path="sentence.scale" min="0" max="5" /></td>
    </tr>
  </c:forEach>
  <tr>
    <td colspan="4"><input type="submit" value="Save" /></td>
  </tr>

I think I have to find the right way to use the path attribute but I can't figure it out.

The JSTL c:forEach tag provides the attribute varStatus , which will expose the loop status to the specified variable. Reference the index of varStatus to obtain the index of the current loop and use that index to specify the index of the collection item you want to bind or display.

<c:forEach var="sentence" items="${snippet.sentences}" varStatus="i">
    <tr>
      <td>${sentence.id}</td>
      <td>${sentence.text}</td>
      <td>
        <form:input type="range" 
          name="snippet.sentences[${i.index}].scale" 
          path="sentences[${i.index}].scale" 
          min="0" max="5" 
          /></td>
    </tr>
  </c:forEach>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM