将数据发布到控制器时,Spring标记请求不正确

时间:2015-02-20 09:38:07

标签: java jsp spring-mvc

Controller设置为空team并获取所有organizations,然后将这2个对象传递给JSP。由于某种原因,表单无法提交数据并导致: 400 The request sent by the client was syntactically incorrect.。 Chrome会显示传递的表单数据:

name:Chris Paul Camps
rating:9
organization:com.sprhib.model.Organization@7ebffc91

JSP

 <form:form method="POST" commandName="team" action="${pageContext.request.contextPath}/team/add.html" class="col-md-4">
             <div class="form-group">
                 <label for="name"><spring:message code="label.name"></spring:message>:</label>
                 <form:input class="form-control" path="name" id="name" />
             </div>
            <div class="form-group">
                <label for="rating"><spring:message code="label.rating"></spring:message>:</label>
                <form:input class="form-control" path="rating" id="rating" />
            </div>
            <div class="form-group">
                <label for="organization"><spring:message code="label.organization"></spring:message>:</label>
                <form:select class="form-control" path="organization" id="organization">
                    <form:option value="" label="- Select -"/>
                    <form:options items="${organizations}" itemLabel="name" />
                </form:select>
            </div>
            <input type="submit" value="<spring:message code="label.add"></spring:message>" class="btn btn-default"/>
        </form:form>

控制器

@RequestMapping(value="/add", method=RequestMethod.GET)
    public ModelAndView addTeamPage() {
        ModelAndView modelAndView = new ModelAndView("teams/add-team-form");
        modelAndView.addObject("team", new Team());
        modelAndView.addObject("organizations", organizationService.getOrganizations());

        return modelAndView;
    }

    @RequestMapping(value="/add", method=RequestMethod.POST)
    public ModelAndView addingTeam(@ModelAttribute Team team) {
        ModelAndView modelAndView = new ModelAndView("home");
        teamService.addTeam(team);
        String message = "Team was successfully added.";
        modelAndView.addObject("message", message);
        return modelAndView;
    }

团队实体:

@Entity
@Table(name="teams")
public class Team {


    private Integer id;

    private String name;

    private Integer rating;

    private Set<Member> members;

    private Organization organization;

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getRating() {
        return rating;
    }
    public void setRating(Integer rating) {
        this.rating = rating;
    }

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "FK_Organization_id", nullable = false)
    public Organization getOrganization() {
        return organization;
    }

    public void setOrganization(Organization organization) {
        this.organization = organization;
    }

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "team_member", joinColumns =
    @JoinColumn(name = "FK_Team_id", referencedColumnName= "id"),
            inverseJoinColumns = @JoinColumn(name = "FK_Member_id", referencedColumnName = "id")
    )
    public Set<Member> getMembers() {
        return members;
    }

    public void setMembers(Set<Member> members) {
        this.members = members;
    }

}

组织实体:

@Entity
@Table(name = "organization")
public class Organization {

    private Integer id;

    private String name;

    private Set<Team> teams;

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "organization")
    public Set<Team> getTeams() {
        return teams;
    }

    public void setTeams(Set<Team> teams) {
        this.teams = teams;
    }
}

更新

更改为此后出现相同的错误:

<form:select class="form-control" path="organization" id="organization">
                    <form:option value="" label="- Select -"/>
                    <form:options items="${organizations}" itemLabel="name" itemValue="id"/>
                </form:select>

我是否必须在控制器中有两个@ModelAttribute,一个用于团队,另一个用于组织?

UPDATE2:

为什么organization似乎null出现此错误:nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: com.sprhib.model.Team.organization

1 个答案:

答案 0 :(得分:1)

尝试将控制器方法更改为

@RequestMapping(value="/add", method=RequestMethod.POST)
public ModelAndView addingTeam(@ModelAttribute Team team,  BindingResult result) {

您最有可能存在绑定错误,但是因为在您的控制器内部没有 BindingResult 紧跟在 @ModelAttribute 之后得到一个糟糕的请求

检查docs BindingResult的无效排序和@ModelAttribute。

  

错误或BindingResult参数必须遵循模型对象   正如方法签名可能具有的那样立即绑定   多一个模型

通过添加BindingResult,我会更深入地了解失败的确切属性

评论后更新


您还需要注册一个可以转换您的组织的活页夹,大致类似于

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(Organization.class,
            new PropertyEditorSupport() {

                @Override
                public void setAsText(String text) {
                    Organization organization = dao.find(Organization.class,
                            Integer.parseInt(text));
                    setValue(organization);
                }
            });
}

dao.find(Organization.class, Integer.parseInt(text));当然是一个元代码