Spring MVC:首次调用控制器方法后路径变量丢失

时间:2014-01-28 23:56:59

标签: spring-mvc

我有一个映射到包含路径变量(@RequestMapping(value="/{studentId}/activity/add", ...)的URL的控制器方法。由于我在此方法中进行了一些验证,因此可能会多次调用该方法。对该方法的第一次调用工作正常,但如果我尝试第二次调用它(例如,如果我第一次填充字段时出现了一些错误),则路径变量会丢失而页面addNewActivity不能加载。

控制器方法:

    @RequestMapping(value="/{studentId}/activity/add", method = RequestMethod.POST, params="saveNew")
    public String postAddNewActivity(@PathVariable Integer studentId,
            @Validated(Activity.ActivityAddNewChecks.class) @ModelAttribute("studentActivityDTO") StudentActivityDTO studentActivityDTO,
            BindingResult result,
            Model model) {

        logger.debug("Received request to add new activity to student");

        if (result.hasErrors()) {
            model.addAttribute("studentActivityDTO", studentActivityDTO);
            model.addAttribute("courseList", courseService.getAll());
            model.addAttribute("teacherList", teacherService.getAll());
            return "addNewActivity";
        }
        else {
            Activity activity = studentActivityDTO.getActivity();
            activityService.add(studentId, activity);
            return "success/addActivitySuccess";
        }
    }

这就是第一次调用URL的方式:

http://someserver/essaysWebApp/essays/main/student/39/activity/add

这就是第二次调用方法的样子:

http://someserver/essaysWebApp/essays/main/student//activity/add

这是第二次调用方法时我在堆栈跟踪中得到的全部内容:

[TRACE] [http-bio-8080-exec-4 12:54:10] (FrameworkServlet.java:initContextHolders:1018) Bound request context to thread: org.apache.catalina.connector.RequestFacade@2bc04b7e
[DEBUG] [http-bio-8080-exec-4 12:54:10] (DispatcherServlet.java:doService:823) DispatcherServlet with name 'spring' processing POST request for [/essaysWebApp/essays/main/student//activity/add]
[TRACE] [http-bio-8080-exec-4 12:54:10] (DispatcherServlet.java:getHandler:1088) Testing handler map [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@21a40993] in DispatcherServlet with name 'spring'
[DEBUG] [http-bio-8080-exec-4 12:54:10] (AbstractHandlerMethodMapping.java:getHandlerInternal:220) Looking up handler method for path /main/student//activity/add
[DEBUG] [http-bio-8080-exec-4 12:54:10] (AbstractHandlerMethodMapping.java:getHandlerInternal:230) Did not find handler method for [/main/student//activity/add]
[TRACE] [http-bio-8080-exec-4 12:54:10] (DispatcherServlet.java:getHandler:1088) Testing handler map [org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping@62cc540b] in DispatcherServlet with name 'spring'
[TRACE] [http-bio-8080-exec-4 12:54:10] (AbstractUrlHandlerMapping.java:getHandlerInternal:127) No handler mapping found for [/main/student//activity/add]
[ WARN] [http-bio-8080-exec-4 12:54:10] (DispatcherServlet.java:noHandlerFound:1108) No mapping found for HTTP request with URI [/essaysWebApp/essays/main/student//activity/add] in DispatcherServlet with name 'spring'
[TRACE] [http-bio-8080-exec-4 12:54:10] (FrameworkServlet.java:resetContextHolders:1028) Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@2bc04b7e
[DEBUG] [http-bio-8080-exec-4 12:54:10] (FrameworkServlet.java:processRequest:966) Successfully completed request
[TRACE] [http-bio-8080-exec-4 12:54:10] (AbstractApplicationContext.java:publishEvent:332) Publishing event in WebApplicationContext for namespace 'spring-servlet': ServletRequestHandledEvent: url=[/essaysWebApp/essays/main/student//activity/add]; client=[0:0:0:0:0:0:0:1]; method=[POST]; servlet=[spring]; session=[null]; user=[null]; time=[16ms]; status=[OK]
[TRACE] [http-bio-8080-exec-4 12:54:10] (AbstractApplicationContext.java:publishEvent:332) Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/essaysWebApp/essays/main/student//activity/add]; client=[0:0:0:0:0:0:0:1]; method=[POST]; servlet=[spring]; session=[null]; user=[null]; time=[16ms]; status=[OK]

我甚至可以开始明白为什么会这样。有人可以帮忙吗?

我忘了说如果用户第一次在所有字段中输入正确的值,else语句的if部分就会被执行,一切正常。

更新:这是控制器映射到的jsp页面:

<c:url var="studentUrl" value="/essays/main/student/${studentActivityDTO.student.studentId}/activity/add" />
<form:form modelAttribute="studentActivityDTO" method="POST" action="${studentUrl}">
<form:errors path="*" cssClass="errorblock" element="div" />

    <form:label path="student.firstName">First name:</form:label>
    <form:input path="student.firstName" readonly="true"/>

    <form:label path="student.lastName">Last name:</form:label>
    <form:input path="student.lastName" readonly="true"/>

    <form:label path="student.indexNumber">Index number:</form:label>
    <form:input path="student.indexNumber" readonly="true"/>

    <form:label path="student.program.programId">MK:</form:label>
    <form:input path="student.program.programId" readonly="true"/>

    <form:label path="student.rollNumber">Roll number:</form:label>
    <form:input path="student.rollNumber" readonly="true"/>

    <form:label path="student.rollYear">Roll year:</form:label>
    <form:input path="student.rollYear" readonly="true"/>

    <form:label path="student.program.programDescription">Program desc:</form:label>
    <form:input path="student.program.programDescription" readonly="true"/>

    <h2>Add new activity</h2>

    <form:radiobutton path="activity.essayFlag" value="Essay" />Essay
    <form:radiobutton path="activity.essayFlag" value="Other"/>Other

    <form:label path="activity.activityDescription">Desc:</form:label>
    <form:input path="activity.activityDescription"/>
    <form:errors path="activity.activityDescription" cssClass="error"/>

    <form:label path="activity.course">Course:</form:label>
    <form:select path="activity.course" id="courseSelect">
        <form:option value="" label="Select" />
        <form:options items="${courseList}" itemValue="courseId" itemLabel="courseDescription" />               
    </form:select>
    <form:errors path="activity.course" cssClass="error"/>

    Teachers:
    <select multiple="multiple" name="activity.teachers" >
        <c:forEach var="theTeacher" items="${teacherList}">
                <option value="${theTeacher.teacherId}">${theTeacher.title.titleDescription} ${theTeacher.firstName} ${theTeacher.lastName}</option>
        </c:forEach>
    </select>
    <form:errors path="activity.teachers" cssClass="error"/>

    <form:label path="activity.submissionDate">Date:</form:label>
    <form:input path="activity.submissionDate" class="datepicker"/>
    <form:errors path="activity.submissionDate" cssClass="error"/>

    <form:label path="activity.score">Score:</form:label>
    <form:input path="activity.score"/>
    <form:errors path="activity.score" cssClass="error"/>

    <form:label path="activity.note">Note:</form:label>
    <form:textarea path="activity.note"/>

    <input type="submit" value="Cancel" name="cancel"/>
    <input type="submit" value="Submit" name="saveNew"/>
</form:form>

1 个答案:

答案 0 :(得分:1)

您永远不会从student.studentId提交<form>。因此,Spring无法使用相应的StudentActivityDTO值重建student的{​​{1}}字段。

将其添加到模型

studentId

并转发到您的观点,model.addAttribute("studentActivityDTO", studentActivityDTO); 没有价值,我认为其类型为studentId或某些String类(例如Number)。

EL将表达式Long解析为${}只会打印空null

请务必提交String student.studentId