我下载了Spring MVC 3 Showcase的代码。有一件事困扰我(好吧,不止一个),为什么这个(为简洁而编辑)样本返回null
?
@Controller
@RequestMapping("/form")
public class FormController {
@RequestMapping(method=RequestMethod.POST)
public String processSubmit(@Valid FormBean form,
BindingResult result,
WebRequest webRequest,
HttpSession session, Model model) {
if (result.hasErrors()) {
return null;
} else {
session.setAttribute("form", form);
return "redirect:/form";
}
}
}
答案 0 :(得分:25)
如果控制器返回空视图名称,或声明void
返回类型,Spring将尝试从请求URL推断视图名称。
在您的情况下,它将假设视图名称为form
,并继续该假设。
它使用RequestToViewNameTranslator
的实现来执行此操作,其默认实现是DefaultRequestToViewNameTranslator
,javadoc for which解释了它适用的确切规则。
答案 1 :(得分:2)
AnnotationMethodHandlerAdapter.invokeHandlerMethod()
负责调用处理程序方法。在此处,ModelAndView
将通过ServletHandlerMethodInvoker.getModelAndView()
检索。
在您的情况下,getModelAndView()
将获得处理程序方法的null
返回值。 getModelAndView()
方法检查返回值的类型,但是as in Java null is never an instanceof any class,该方法的逻辑将创建一个新的ModelAndView
。新的ModelAndView
最初将其视图属性设置为null
。
然后在DispatcherServlet.doDispatch()
中备份调用堆栈,如果ModelAndView
对象与View
对象关联mv.hasView()
,则会进行测试。因为view == null
,doDispatch()
的逻辑调用mv.setViewName(getDefaultViewName(request))
。它委派给已注册的RequestToViewNameTranslator
,其默认实现为DefaultRequestToViewNameTranslator
。此子类将请求URI转换为视图名称,在您的情况下为form
。
稍后在doDispatch()
,通过render()
- > resolveViewName()
,此示例的ViewResolver
提供了视图名称form
。此示例中只使用了一个ViewResolver
,InternalResourceViewResolver
。此外,在InternalResourceViewResolver
中配置了此src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml
,以将前缀/WEB-INF/views/
和后缀.jsp
添加到视图名称。总的来说,它将使用JSP文件View
创建/WEB-INF/views/form.jsp
。幸运的是,JSP文件恰好存在于此位置。