My Spring MVC Web应用程序使用两个模型类Player和Team。玩家和团队之间存在 ManyToMany关系。这是模型类。
@Entity
@Table(name="TEAMS")
public class Team {
@Id
@Column(name="ID")
private int id;
@Column(name="NAME")
@Size(min=2, max=30)
private String name;
@ManyToMany(mappedBy="teams")
private Set<Player> players = new HashSet<Player>();
//getter and setter methods
}
@Entity
@Table(name="PLAYERS")
public class Player {
@Id
@Column(name="ID")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="players_seq")
@SequenceGenerator(name="players_seq", sequenceName="PLAYERS_SEQ")
private int id;
@Column(name="LASTNAME")
@Size(min=2, max=30)
private String lastname;
@Column(name="FIRSTNAME")
@Size(min=2, max=30)
private String firstname;
@Column(name="BIRTHDAY")
@DateTimeFormat(pattern="MM/dd/yyyy")
@NotNull @Past
private Date dob;
@Column(name="PLAYING_ROLE")
@NotNull
private String playingRole;
@ManyToMany(cascade =CascadeType.ALL)
@JoinTable(name="TEAM_PLAYER",
joinColumns={@JoinColumn(name="PLAYER_ID")},
inverseJoinColumns={@JoinColumn(name="TEAM_ID")})
private Set<Team> teams = new HashSet<Team>();
//getter and setters
}
我试图在Checkboxes的帮助下将团队分配给玩家,我的JSP看起来像这样
<table>
<form:form modelAttribute="player" method="POST"
action="${editPlayer }">
<tr>
<td>Last name:</td>
<td><form:input path="lastname" /> <form:errors
path="lastname" cssStyle="color:red;" /></td>
</tr>
<tr>
<td>First Name:</td>
<td><form:input path="firstname" /> <form:errors
path="firstname" cssStyle="color:red;" /></td>
</tr>
<tr>
<td>Birthday:</td>
<td><form:input path="dob" /> <form:errors path="dob"
cssStyle="color:red;" /></td>
</tr>
<tr>
<td>Playing Style:</td>
<td><form:input path="playingRole" /> <form:errors
path="playingRole" cssStyle="color:red;" /></td>
</tr>
<tr>
<td>Teams:</td>
<td><form:checkboxes items="${teams}" path="teams"
itemValue="id" itemLabel="name" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Update Player" /></td>
</tr>
</form:form>
</table>
我的PlayerController.java看起来像这样
@Controller
public class PlayerController {
@Autowired
private PlayerService playerService;
@Autowired
private TeamService teamService;
@ModelAttribute("teams")
public List<Team> getTeams(){
return teamService.getTeams();
}
@RequestMapping(value="/player/edit/{id}", method=RequestMethod.GET)
public ModelAndView updatePlayerPage(@PathVariable int id){
Player player = playerService.getPlayer(id);
ModelAndView modelAndView = new ModelAndView("player/edit");
modelAndView.addObject("player", player);
return modelAndView;
}
@RequestMapping(value="/player/edit/{id}", method=RequestMethod.POST)
public ModelAndView updatePlayer(@ModelAttribute @Valid Player player, BindingResult result, @PathVariable int id){
if(result.hasErrors()){
System.out.println("HAS ERRORS!. Number of errors: "+result.getAllErrors().size());
for(Object o : result.getAllErrors()){
System.out.println(o);
}
System.out.println("\n Player details: "+ player );
return new ModelAndView("player/edit");
}
playerService.updatePlayer(player);
ModelAndView modelAndView = new ModelAndView("home");
String message = "Player updated successfully";
modelAndView.addObject("message", message);
return modelAndView;
}
//it has got some other methods also that does some other functionality
}
JSP页面正在正确呈现,但是当我尝试保存时,我得到异常
Field error in object 'player' on field 'teams': rejected value [5050]; codes [typeMismatch.player.teams,typeMismatch.teams,typeMismatch.java.util.Set,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [player.teams,teams]; arguments []; default message [teams]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Set' for property 'teams'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.sunil.model.Team] for property 'teams[0]': no matching editors or conversion strategy found]
异常背后的原因是我需要将Team分配给Player,但我不知道如何做到这一点。有人可以帮我解决这个问题。
由于
答案 0 :(得分:0)
您可以使用@RequestBody将表单数据编码为json并将其发送到您的控制器方法
答案 1 :(得分:0)
好吧最后我能够解决它..我希望它对其他人有用..
我更新了JSP页面
<form:form modelAttribute="player" method="POST"
action="${editPlayer }">
<tr>
<td>Last name:</td>
<td><form:input path="lastname" /> <form:errors
path="lastname" cssStyle="color:red;" /></td>
</tr>
<tr>
<td>First Name:</td>
<td><form:input path="firstname" /> <form:errors
path="firstname" cssStyle="color:red;" /></td>
</tr>
<tr>
<td>Birthday:</td>
<td><form:input path="dob" /> <form:errors path="dob"
cssStyle="color:red;" /></td>
</tr>
<tr>
<td>Playing Style:</td>
<td><form:input path="playingRole" /> <form:errors
path="playingRole" cssStyle="color:red;" /></td>
</tr>
<tr>
<td>Available Teams:</td>
<td><form:select path="teams" multiple="true" items="${teamCache}" itemLabel="name" itemValue="id"/></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Update Player" /></td>
</tr>
</form:form>
我从Checkbox移到了Select。这种变化背后的原因是(我觉得)最终用户从下拉列表中进行多项选择会有所帮助。
我对我的控制器进行了几次更新。
@ModelAttribute("teamCache")
public List<Team> getTeams(){
return teamService.getTeams();
}
我的选择使用teamsCache (表格中的项目属性:选择)
@RequestMapping(value="/player/edit/{id}", method=RequestMethod.GET)
public ModelAndView updatePlayerPage(@PathVariable int id){
Player player = playerService.getPlayer(id);
List<Team> teams = teamService.getTeams();
teamCache = new HashMap<Integer, Team>();
for(Team team : teams){
teamCache.put((Integer)team.getId(), team);
}
ModelAndView modelAndView = new ModelAndView("player/edit");
modelAndView.addObject("player", player);
return modelAndView;
}
@InitBinder
protected void initBinder(WebDataBinder binder) throws Exception{
binder.registerCustomEditor(Set.class,"teams", new CustomCollectionEditor(Set.class){
protected Object convertElement(Object element){
if (element instanceof String) {
Team team = teamCache.get(Integer.parseInt(element.toString()));
return team;
}
return null;
}
});
}
@RequestMapping(value="/player/edit/{id}", method=RequestMethod.POST)
public ModelAndView updatePlayer(@ModelAttribute @Valid Player player, BindingResult result, @PathVariable int id){
if(result.hasErrors()){
return new ModelAndView("player/edit");
}
playerService.updatePlayer(player);
ModelAndView modelAndView = new ModelAndView("home");
String message = "Player updated successfully";
modelAndView.addObject("message", message);
return modelAndView;
}
我希望它对其他人有用。如果有更好的解决方案,请告诉我。
由于