注册自定义属性编辑器后,无法绑定复选框

时间:2013-06-06 00:56:19

标签: spring spring-mvc spring-mvc-initbinders

我有以下一系列注册团队的步骤:

  1. 选择团队 - 这将显示此团队的球员列表作为复选框(下面的JSP页面)
  2. 用户可以选择一个或多个显示的球员
  3. 应该调用
  4. newdTeam请求处理程序方法,从上面的步骤2设置所选的玩家。正在调用处理程序,但即使我在步骤2中选择了玩家,players集也是空的。不确定问题出在哪里。
  5. 我没有看到属性编辑器被调用。任何帮助表示赞赏。

    团队

    @NodeEntity
    public class Team
    {
        @GraphId
        private Long nodeId;
    
        @GraphProperty
        @Indexed (unique = true)
        private String name;
    
        @Fetch
        @RelatedTo (type = "PLAYED_WITH_TEAM", direction = Direction.INCOMING)
        private final Set<Player> players = new HashSet<Player>();
    
        public String getName()
        {
            return name;
        }
    
        public void setName(String name)
        {
            this.name = StringUtil.capitalizeFirstLetter(name);
        }
    
        public Long getNodeId()
        {
            return nodeId;
        }
    
        public Collection<Player> getPlayers()
        {
            return players;
        }
    
        public void setPlayers(Set<Player> plyrs)
        {
            System.err.println("called set plrs");
            players.addAll(plyrs);
        }
    }
    

    播放器

    @NodeEntity
    public class Player
    {
        @GraphId
        private Long nodeId;
    
        @Indexed (unique = true)
        private String name;
    
        @GraphProperty
        @Indexed
        private String firstName;
    
        @GraphProperty
        private String email;
    
            //getters and setters
    }
    

    控制器

    @Controller
    @RequestMapping ("/registration")
    public class RegistrationController
    {
        private transient final Logger LOG = LoggerFactory.getLogger(getClass());
    
        @Autowired
        private LeagueRepository leagueRepo;
    
        @Autowired
        private TeamRepository teamRepo;
    
        @RequestMapping (method = RequestMethod.GET)
        public String get()
        {
            return "/registration/start";
        }
    
        @Transactional
        @RequestMapping (value = "/start", method = RequestMethod.POST)
        public String hasParticipatedEarlier(@RequestParam boolean participatedInEarlierLeague, Model model)
        {
            if (participatedInEarlierLeague)
            {
                LOG.debug("Participated in earlier leagues. Retrieving the past league teams.");
                Iterable<League> allLeagues = leagueRepo.findAll();
                Set<League> sortedLeagues = new TreeSet<League>();
                for (League l: allLeagues)
                {
                    sortedLeagues.add(l);
                }
                LOG.debug("Past leagues sorted by start date {}", sortedLeagues);
                model.addAttribute("pastLeagues", sortedLeagues);
            }
            else
            {
                LOG.debug("Did not participate in earlier leagues. Redirecting to register the new one.");
            }
            return "/registration/leagues";
        }
    
        @RequestMapping (value = "/selectTeam", method = RequestMethod.POST)
        public String selectTeam(@RequestParam Long selectedTeam, Model model)
        {
            LOG.debug("Participated as team {} in previous league", selectedTeam);
            Team team = teamRepo.findOne(selectedTeam);
            model.addAttribute("team", team);
            model.addAttribute("players", team.getPlayers());
            return "registration/players";
        }
    
        @RequestMapping (value = "/newTeam", method = RequestMethod.POST)
        public String newdTeam(@ModelAttribute Team team, Model model)
        {
            LOG.debug("Selected players from existing list {}", team.getPlayers());
    
            return "registration/registrationConfirmation";
        }
    
        @InitBinder
        public void initBinder(WebDataBinder binder)
        {
            binder.registerCustomEditor(Player.class, new PlayerPropertyEditor());
        }
    }
    

    PlayerPropertyEditor

    public class PlayerPropertyEditor extends PropertyEditorSupport
    {
        @Autowired
        PlayerRepository playerRepo;
    
        @Override
        public String getAsText()
        {
            System.err.println("get as txt");
            return ((Player) getValue()).getNodeId().toString();
        }
    
        @Override
        public void setAsText(String incomingId) throws IllegalArgumentException
        {
            System.err.println(incomingId);
            Player player = playerRepo.findOne(Long.valueOf(incomingId));
            setValue(player);
        }
    }
    

    JSP

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
    <%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
    <%@ taglib prefix="f" uri="http://www.springframework.org/tags/form" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Players of ${team.name}</title>
    
    </head>
    <body>
        <f:form action="newTeam" method="post" modelAttribute="team">
            <f:checkboxes items="${players}" path="players" itemLabel="name" itemValue="nodeId" delimiter="<br/>"/>
            <input type="submit" value="Submit">
        </f:form>
    </body>
    </html>
    

1 个答案:

答案 0 :(得分:0)

我看到的一个问题是你在PlayerRepository内注入了PlayerPropertyEditor,这没有任何效果,因为它不在Spring上下文中。你应该通过构造函数传递它。然后将其注入Controller

<强> PlayerPropertyEditor

public class PlayerPropertyEditor extends PropertyEditorSupport
{
    private PlayerRepository playerRepo;

    public PlayerPropertyEditor(PlayerRepository playerRepo) {
        this.playerRepo = playerRepo;
    }
    // other methods
}

控制器

@Autowired
private PlayerRepository playerRepo;

@InitBinder
public void initBinder(WebDataBinder binder)
{
    binder.registerCustomEditor(Player.class, new PlayerPropertyEditor(playerRepo));
}

其次,我想这是主要问题,您应该覆盖equals课程的hashCodePlayer。我没有测试过,但我依赖this answer