我发现了许多与我相近的问题,但讨论总是回到同一个解决方案(DTO方法)。我面临的问题如下:
我有一个表格的以下支持对象作为JPA实体列表:
public class PlayerForm {
private List<Player> players;
public List<Player> getPlayers() {
return players;
}
public void setPlayers(List<Player> players) {
this.players = players;
}
}
以下对象的列表:
@Entity
public class Player implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public enum PlayerType{
DEV, POQA;
}
@Id
private Long id;
@Column(unique=true)
private String name;
private int score;
@Enumerated(EnumType.STRING)
private PlayerType playerType;
@ManyToMany
private List<Bonus> bonusItems;
我将PlayerForm传递给模型并使用我视图中的forllowing表单将其绑定:
<form:form method="POST" action="${action}"
modelAttribute="playerForm">
<table class="${cssClass}">
<tr>
<th>Rank</th>
<th>Name</th>
<th>Score</th>
</tr>
<c:forEach items="${playerForm.players}" var="player" varStatus="status">
<tr>
<td class="center">${status.count}</td>
<td>${player.name}</td>
<td><input name="players[${status.index}].id" type="hidden"
value="${player.id}" /><input name="players[${status.index}].name" type="hidden"
value="${player.name}" /><input name="players[${status.index}].score" type="number"
value="${player.score}" /></td>
</tr>
</c:forEach>
</table>
<input style="width: 25%;" onclick="clearPreviousMessages();"
type="submit" value="Submit Changes" />
</form:form>
提交表单后,未映射到表单输入的属性将被清零。我知道我可以使用我的实体的DTO抽象,这将解决问题。但是,有没有办法让spring mvc只将我的输入值绑定到属性,同时保持传递给模型的其他属性的初始值,即使它们没有绑定到任何输入?
答案 0 :(得分:0)
如CodeChimp所述,您需要首先加载完整的 PlayerForm 实例,并在请求之间保持其状态。您通常使用会话来执行此操作,但Spring MVC具有 @SessionAttributes 构造,可帮助您在控制器范围内维护后续请求之间的模型属性状态。
尝试使用以下元代码示例来说明它
@Controller
@SessionAttributes("playerForm")
public class FormController {
@RequestMapping("/init")
public String start(Model model) {
PlayerForm playerForm = initialiaze(); // e.g. load from DB
model.addAttribute("playerForm", playerForm);
return "form"; // return to the form
}
@RequestMapping(method=RequestMethod.POST)
public String processSubmit(@ModelAttribute("playerForm") PlayerForm playerForm) {
// do something, make changes, store in DB, whatever
return "form"; // return to the form
}
@RequestMapping("/finishEdit")
public String end(SessionStatus status) {
status.setComplete(); // remove the model attribute from the session
return "nextpage"; // move to a different page
}
}
最初,您的表单页面已加载到 / init ,并且 PlayerForm 对象已初始化并添加到模型中,您的表单将呈现所有数据。
更改数据和提交表单由processSubmit处理,但在调用方法之前,由于 @SessionAttributes(“playerForm”)和 @ModelAttribute(“playerForm”的绑定“) playerForm将从会话中获取先前的值,而不是使用表单中的值进行更新,最后,将再次更改会话中的值,并再次呈现表单。此循环将使您的所有后续请求按预期工作(不会创建空值)
最后,当使用表单导航离开页面时,应设置 status.setComplete ,以便从会话中删除模型属性