第一篇文章「从零学习Spring MVC框架「环境搭建和MVC架构」」中我们初步进行了环境搭建,对Spring MVC框架的运行原理有个大体了解,为了帮助大家理解相关概念及原理,第一篇教程中使用的方式是在控制台打印结果。所以上篇文章的案例很多概念没有涉及到,如ModelAndView、视图解析器等,今天我们就要详细讲解这些概念,并且提供几种常用的处理静态文件的解决方案。
首先给出一张图,建议点击放大看,这张图就是我们本文章案例的大体框架和思路,看不懂没关系,文末还会给出,相信仔细阅读完本篇文章的图文,就可以理解这张图了,按照顺序仔细看:
应用案例
接下来就要搭建环境,完成上图中的运行流程:在搜索栏中键入webjujidi 后,跳转到main.jsp,打印出「Web项目聚集地」,并且加载一个静态资源图片。
- 案例截图
- 导入Jar包
- web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>SpringMVC02</display-name>
<servlet>
<servlet-name>spring-mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某规则分发到目标Controller来处理。
在DispatcherServlet的初始化过程中,框架会在web应用的WEB-INF文件夹下寻找名为spring-mvc-servlet.xml的配置文件,生成文件中定义的bean,关于spring-mvc-servlet.xml的配置文件在最下方给出。
- WebController.java
@Controller
public class WebController {
@RequestMapping("/test01")
public String test04(Model model){
model.addAttribute("message" , "聚集地");
return "jsp/main";
}
@RequestMapping(value="/webjujidi")
public ModelAndView juJiDi(){
ModelAndView mvAndView = new ModelAndView();
mvAndView.addObject("message","web项目聚集地");
mvAndView.setViewName("jsp/main");
return mvAndView;
}
}
@Controller
@Controller注明来表明这个类是一个控制器,可以负责处理请求。
ModelandView
modelandview顾名思义,模型和试图,你可以定义view(视图资源)的名字,和model(数据模型),数据可以再视图中展示。
@RequestMapping
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。注解有六个属性,下面我们把她分成三类进行说明:
value, method(重要)
value:指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
consumes,produces
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
params,headers
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
- spring-mvc-servlet.xml
<!-- 启动springMVC注解 -->
<mvc:annotation-driven/>
<!-- 扫描注解所在的包 -->
<context:component-scan base-package="com.**.controller"></context:component-scan>
<!-- 视图解析器 -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
关于前两行的配置在第一篇教程「从零学习Spring MVC框架「环境搭建和MVC架构」」已经详细介绍,这里不再重复讲解,不了解的读者可以移步第一篇教程查看,这里讲解视图解析器。
ViewResolver
ViewResolver顾名思义:视图解析器,它可以根据.xml里面配置的视图资源的路径前缀和文件格式后缀拼凑成所想要的具体视图文件,比如html,jsp等等,不理解没关系后面会有图形象的解释清楚。
- main.jsp(在WEB-INF下的jsp文件夹下)
<body>
${message }
<img src="img/a.jpg">
</body>
WEB-INF规下面的东西是安全的(即不能通过url获得web-info下的任何文件),但是你可以通过servlet或者Spring MVC中Controller进行转发。即我们使用 return "jsp/main"的方式进行跳转到main.jsp页面。
- 运行截图
下方我们使用 ${message }接到了值,但是静态文件也被DispatcherServlet所拦截,没有显示:
静态文件为什么不加载,因为在我们配置DispatcherServlet的时候,拦截的路径是/,即所包括静态文件都被拦截了。这里列出两种解决方案:
方式一
添加使用配置即可
spring-mvc-servlet.xml
<!-- 启动springMVC注解 -->
<mvc:annotation-driven/>
<!-- 扫描注解所在的包 -->
<context:component-scan base-package="com.**.controller"></context:component-scan>
<!-- 视图解析器 -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 排除静态资源的第一种方式 -->
<mvc:default-servlet-handler/>
方式二
在spring-mvc-servlet.xml中添加添加的配置,mapping填写静态文件的路径。
spring-mvc-servlet.xml
<!-- 启动springMVC注解 -->
<mvc:annotation-driven/>
<!-- 扫描注解所在的包 -->
<context:component-scan base-package="com.**.controller"></context:component-scan>
<!-- 视图解析器 -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 排除静态资源的第二种方式 -->
<mvc:resources location="/WEB-INF/resources/" mapping="/js/**"></mvc:resources>
<mvc:resources location="/WEB-INF/resources/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/WEB-INF/resources/" mapping="/img/**"></mvc:resources>
采用上面的两种方式中的哪种方式都可以解决静态资源被拦截的问题,当我们配置了之后再运行项目,静态资源问题解决:
- 总结
相信阅读上方文章后,对下面这个图应该会了解非常清楚:
我们用文字表述出来:当在地址栏输入webjujidi等url的时候,此请求会被DispatcherServlet所拦截,然后根据Servlet中的配置,找到spring-mvc-servlet.xml,在spring-mvc-servlet.xml中会对controller包进行扫描。
在添加@controller注解的类中,根据@RequestMapping的值对请求的映射路径进行匹配,然后执行匹配的方法。方法中会对model进行赋值,同样确定了视图的名称,即跳转到哪个页面。返回modelandview对象后调用试图解析器,添加前缀和后缀得到了跳转页面的地址。
跳转之后的地址,可以利用el表达式进行接值,即model的添加的对象,至此整个流程讲述完毕。
原文发布时间为:2018-07-29
本文来自云栖社区合作伙伴“Web项目聚集地”,了解相关信息可以关注“Web项目聚集地”。