Spring MVC在ModelAttribute中接收域对象,因为angularJS数组为空

时间:2018-08-03 13:59:32

标签: angularjs spring spring-mvc model

因此,我在模型中设置了一个域对象(TestGenerationRequest),并通过JSP为该页面提供服务。然后,我有一个表单(Spring表单),用户可以在将模型提交回控制器之前在浏览器中与之交互。会收到域对象,并且会根据用户交互自动正确地填充其大多数字段。但是,每次收货时,一个字段都是空白。该字段称为“组”,是另一个域对象列表的列表。 “组”填充在浏览器中,并绑定到angularJS数组,该数组本身通过AJAX作为JSON从其他地方获取。发送回控制器的请求看起来不错,当使用Firefox的dev工具/网络检查时,请求的格式正确,但服务器端的组仍然为空。我究竟做错了什么?任何帮助表示赞赏!

TestGenerationRequest域对象:

public class TestGenerationRequest implements Serializable {

    private final static long serialVersionUID = 934343334541L;
    @JsonIgnore
    public static final int FORMAT_PORTRAIT = 1;
    @JsonIgnore
    public static final int FORMAT_LANDSCAPE = 2;

    @Min(1)
    @Max(6)
    private int testNum;
    @NotNull(message = "{generatetest.error.selectedGrades.notnull}")
    private List<String> selectedGrades;
    @Min(1)
    @Max(2)
    private int orientation;
    private boolean includeRepro;
    private List<TeachingGroup> groups;

    public TestGenerationRequest() {
        super();
        //this.selectedGrades = new ArrayList<String>();
        this.groups = new ArrayList<TeachingGroup>();
        this.orientation = TestGenerationRequest.FORMAT_PORTRAIT; //set default to portrait; this is reflected in the JSP view's default selection for user.
        this.includeRepro = false; // set default, reflected in JSP view default
    }

    public int getTestNum() {
        return testNum;
    }

    public void setTestNum(int testNum) {
        this.testNum = testNum;
    }

    public int getOrientation() {
        return orientation;
    }

    public void setOrientation(int orientation) {
        this.orientation = orientation;
    }

    public boolean isIncludeRepro() {
        return includeRepro;
    }

    public void setIncludeRepro(boolean includeRepro) {
        this.includeRepro = includeRepro;
    }

    public List<String> getSelectedGrades() {
        return selectedGrades;
    }

    public void setSelectedGrades(List<String> selectedGrades) {
        this.selectedGrades = selectedGrades;
    }

    public List<TeachingGroup> getGroups() {
        return groups;
    }

    public void setGroups(List<TeachingGroup> groups) {
        this.groups = groups;
    }

}

TeachingGroup域对象:

@Component
@XmlRootElement(name = "group")
@XmlAccessorType(XmlAccessType.FIELD)
public class TeachingGroup implements Serializable {

    @JsonIgnore
    private final static long serialVersionUID = 93459334534L;

    private String name;
    private int id;
    private List<Student> students;
    private int year;

    @JsonIgnore
    private int type;
    @JsonIgnore
    public static final int NORMAL_TEACHING_GROUP = 1;
    @JsonIgnore
    public static final int SKILLS_CLASS_GROUP = 1;

    @JsonIgnore
    private int schoolID;
    @JsonIgnore
    private int subject;
    private List<Grade> availGrades; 
    private List<Integer> availTestNums; 

    @JsonIgnore
    boolean studentsPopulated = false;

    public TeachingGroup() {
        super();
        students = new ArrayList<Student>();
        availGrades = new ArrayList<Grade>();
        availTestNums = new ArrayList<Integer>();
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

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

    @XmlElement(name = "students")
    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }


    public void addStudent(Student s) {
        if (!this.studentsPopulated || (!this.students.contains(s))) {
            this.students.add(s);
            this.studentsPopulated = true;
        }
    }

    public int getYear() {
        return year;
    }

    public void setYear(int y) {
        year = y;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public int getSchoolID() {
        return schoolID;
    }

    public void setSchoolID(int schoolID) {
        this.schoolID = schoolID;
    }

    public int getSubject() {
        return subject;
    }

    public void setSubject(int subject) {
        this.subject = subject;
    }

    public List<Grade> getAvailGrades() {
        return availGrades;
    }

    public void setAvailGrades(List<Grade> availGrades) {
        this.availGrades = availGrades;
    }

    public List<Integer> getAvailTestNums() {
        return availTestNums;
    }

    public void setAvailTestNums(List<Integer> availTestNums) {
        this.availTestNums = availTestNums;
    }

    public boolean isStudentsPopulated() {
        return studentsPopulated;
    }

    public void setStudentsPopulated(boolean studentsPopulated) {
        this.studentsPopulated = studentsPopulated;
    }

}

控制器,为初始请求提供服务并设置模型:

@RequestMapping("/generateTest")
    public String generateTest(Model model) {
        model.addAttribute("grades", subject.getGrades());
        if (!model.containsAttribute("testGenRequest")) {

            model.addAttribute("testGenRequest", new TestGenerationRequest());
        }

        return "generatetest";
    }

控制器,收到最终形式:

@RequestMapping(value = "/generateTest/download.pdf", method = RequestMethod.POST)
    public void generateTestDownload(@ModelAttribute("testGenRequest") @Valid TestGenerationRequest testGen, BindingResult result, Model model, HttpServletResponse response) {
        if (result.hasErrors()) {
            generateTest(model);
        }
        String[] suppressedFields = result.getSuppressedFields();
        if (suppressedFields.length > 0) {
            throw new RuntimeException("Attempting to bind disallowed fields: " + StringUtils.arrayToCommaDelimitedString(suppressedFields));
        }
 /*
testGen.getGroups() should return List<TeachingGroup> but the list is empty
*/
    }

@InitBinder
public void initialiseBinder(WebDataBinder binder) {
    if (binder.getTarget() != null) {
        if (binder.getTarget().getClass().equals(TestGenerationRequest.class)) {
            binder.setAllowedFields("testNum", "selectedGrades", "orientation", "includeRepro", "groups");
        }

    }

}

JSP;必须使用输入字段而不是form:hidden,否则angularJS也会忽略它,但尝试了许多排列形式,包括:hidden并将值设置为静态数据... rightValuesArray是先前通过AJAX服务的List的适当angularJS数组  generatetest.jsp:

<c:url var="actionURL" value="/generateTest/download.pdf"/>
<form:form method="POST" modelAttribute="testGenRequest" action="${actionURL}" class="form-horizontal" id="testForm">    
<form:input path="groups" value="{{rightValuesArray}}" style="display: none;"/>
<snipped rest of form>
</form:form>

对Controller的最终请求,从Firefox的开发工具Network-> request-> Params中捕获,显示groups字段包含JSON:

_includeRepro   on
_selectedGrades […]
0   on
1   on
2   on
3   on
4   on
5   on
6   on
7   on
8   on
groups  [{"name":"classA","id":439,"students":[],"year":2,"availGrades":[],"availTestNums":[]},{"name":"classB","id":440,"students":[],"year":2,"availGrades":[],"availTestNums":[]}]
includeRepro    true
orientation 1
selectedGrades  […]
0   3
1   4
2   5
3   6
4   7
5   8
testNum 3

我正在使用

  

org.springframework.web.servlet.view.json.MappingJackson2JsonView

抱歉,这是一篇很长的帖子。今天,我花了很多时间试图使它起作用,并拔掉头发。如果人们发现错误,将不胜感激。谢谢

内容协商视图解析器。

0 个答案:

没有答案