0

我的 Spring MVC Web 应用程序使用了两个模型类 Player 和 Team。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
    }

我正在尝试在复选框的帮助下将团队分配给玩家,我的 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,但我不确定如何执行此操作。有人可以帮我解决这个问题。

谢谢

4

2 回答 2

0

您可以使用 @RequestBody 将表单数据编码为 json 并将其发送到您的控制器方法

于 2013-08-14T02:13:05.387 回答
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>

我从复选框移动到选择。此更改背后的原因是(我认为)最终用户从下拉列表中进行多项选择会有所帮助。

我对我的控制器进行了一些更新。

@ModelAttribute("teamCache")
    public List<Team> getTeams(){
        return teamService.getTeams();
    }

我的选择使用了teamCache (表单中的项目属性:选择)

@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;
    }

我希望它对其他人有用。另外请让我知道是否有更好的解决方案。

谢谢

于 2013-08-16T19:47:06.293 回答