问题:请求返回jsp源码
解决:将项目的web.xml中 <servlet-mapping> 下的<url-pattern>/*</url-pattern>改为<url-pattern>/</url-pattern>
原理:首先理解/ 和 /*区别
再理解SpringMVC处理请求的流程
DispatcherServlet——》HandlerMapping——》HandlerAdapter——》Handler
这样走完后得到handler处理后的返回的ModelAndView
然后我们从这个地方开始看源码
我们将会得到一个线路得到ModelAndeView后 ——》processDispatchResult方法——》render方法——》renderMergedOutputModel方法——》最后执行rd.forward(request, response)
下面部分源码的截图
流程图
我们可以发现最后rd.forward 这个是转发的意思 那就是要转发到另外一个处理器去处理,转发到哪呢?看spring日志打印出来的内容
我们可以发现,它是要转发到/WEB-INF/jsp/studentList.jsp这个地址,既然是转发,那又要经过web.xml中配置的servlet 那就得去匹配<url-pattern> 。好接下去就是关键点。如何处理/WEB-INF/jsp/studentList.jsp这个请求
根据前面说的<url-pattern> /* </url-pattern>将匹配所有的类型的请求 那么像/WEB-INF/jsp/studentList.jsp这样的请求肯定是会被匹配上的 所以就是我们自己的quickWeb这个servlet去处理 ,但是我们自己的servlet是如何处理的呢?
首先我们自己没有这样的controller去处理,
其次看配置文件
自己配置的静态资源路径也没有设置jsp是如何映射的 ,那怎么办 ?
仔细看配置文件<mvc:default-servlet-handler/>这句话就是如果自己的都匹配不上 那就用default-servlet去处理 这个default是谁?
它就是tomcat中名称为default的servlet 。
看tomcat的web.xml文件
这个servlet的作用是什么呢
这个类的作用是专门为大多数web应用提供静态资源服务的
所以/WEB-INF/jsp/studentList.jsp 这个请求最后到了DefaultServlet这里 它就把这个当成静态资源来处理 所以就直接返回了这个路径下的文件,即studentList.jsp这个文件了 所以界面上就直接显示了jsp源码 如果没找到就返回了404,这就是404的来源了
好了 上面解释的是不正确的处理方式,下面就介绍一下正确的处理方式
我们将web.xml中url改成这个<url-pattern>/</url-pattern> (即不要之前的*)
转发之前的步骤都一样 现在看如何处理/WEB-INF/jsp/studentList.jsp这个转发的请求。
首先自己的应用由于配置的是<url-pattern>/</url-pattern> 所以就不会去处理这个请求了
那谁来处理呢?答案就是Tomcat服务器。
看tomcat的web.xml配置文件
JspServlet就是专门处理*.jsp这样的请求的(我们发现还可以处理*.jspx这样的请求)
所以我们可以深入思考一下 ,如果要改成Velocity、FreeMarker等模版 那只需要修改哪些地方呢?
总结:为什么返回JSP源码了呢?
1、请求在controller处理完之后会转发到视图servlet去处理数据与模版结合的事
2、在转发后我们自己的servlet “拦截”了这个转发的请求 ,却没有对应的模版引擎去处理,所以最后由tomcat 的defaultservlet就把它当成一个静态资源去处理 。所以就返回了源码
为什么改了之后能返回正确的界面了呢?
3、因为url-pattern改成/之后 自己的servlet就不会去“拦截”这个请求 ,所以最后就被tomcat的JspServlet匹配上了 ,在这个servlet里面就会去渲染,处理数据和界面结合的事情