最近在学习SpringMVC框架源码,为了方便学习,用Idea创建了一个SpringMVC项目,Idea提供了便捷的SpringMVC项目创建方式,就是在创建项目时勾选“Spring MVC”复选框,这样Idea会自动将SpingMVC需要的包导入项目中,导入成功后有一个jar包引起了我的注意,如下:
spring-webmvc-portlet.jar。我之前手动导入或通过maven依赖引入SpringMVC的jar包时,并没有这个包。不过我并没有细究,然后开始了代码的编写,这就为后面的坑埋下了伏笔。
我写了一段小Demo如下:
@Controller public class Demo { @RequestMapping("/test3") public ModelAndView test3(){ System.out.println("test3 receive request"); ModelAndView mav = new ModelAndView(); mav.addObject("name","gjw"); mav.addObject("age",23); mav.setViewName("index"); return mav; } }
dispatcherServlet的配置如下:
<context:component-scan base-package="com.gjw.controller"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean>
这段代码很简单,就是访问/test3这个URI时,显示index.jsp页面的内容,并向该页面传递两个值,name和age,然而当我实际访问时,却报了404错误,提示找不到资源/test3.jsp,我的视图名字设置的index啊,怎么会跳转到test3.jsp呢,于是我打断点跟踪了dispatcherServlet内部的执行过程,发现在生成ModelAndView对象时,View is null,我明明设置了view的啊,怎么会是null(不解),后续的流程中由于view为null,于是将RequestMapping注解中的值设置成了view的值,最后渲染的便是/test3.jsp。
正当我不得其解时,我突然想到会不会是我的ModelAndView对象有问题,于是我看了导入的包,发现我导入的是
import org.springframework.web.protlet.ModelAndView
而正确的应该是
import org.springframework.web.servlet.ModelAndView
一个是protlet包下的,另一个是servlet包下的,两个类不光名字一致,而且内部的方法也一致,用Idea输入代码时,由于有自动代码提示,没有细看,结果用错了类。修改之后运行成功。
之后我百度了下protlet,原来它也是SUN公司提出的JavaWeb规范,和Servlet类似,都是一种JavaWeb技术,SpringMVC框架也提供了对protlet的支持,于是才会有spring-webmvc-portlet.jar这个jar包。