SpringMVC是现在JavaWeb应用最广泛的表现层MVC框架之一,它是基于Servlet规范实现的。所谓表现层MVC框架,用途就是拦截HTTP请求,调用业务层处理数据,返回视图给用户,SpringMVC和Spring很容易整合在一起使用。
学习SpringMVC必须掌握Spring框架相关的核心知识,这部分内容可以参考/Java/JavaEE企业级应用框架/Spring/SpringFramework/Core
相关章节。
虽然Spring工程具有高度可配置、使用灵活的特点,但是毕竟每次创建项目都要重新配置一次,比较麻烦。我这里抽取了SSM(SpringMVC+Spring+MyBatis)项目的Maven工程骨架,可以方便的创建SSM项目:https://gitee.com/gacfox/ssm-archetype
下面我们主要介绍一些和SpringMVC相关的核心配置文件。
注意:我们除非在学习阶段,或者维护历史遗留代码,否则没有必要手动搭建配置SpringMVC工程,Spring工程建议使用SpringBoot来搭建。
SpringMVC工程除了Spring的核心依赖,还需要spring-web
和spring-webmvc
两个依赖包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
SpringMVC是基于Servlet规范的框架,因此在工程的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"
version="3.0">
<display-name>SSM Maven Webapp</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>logbackConfigLocation</param-name>
<param-value>classpath:logback.xml</param-value>
</context-param>
<!--spring dispatcher servlet-->
<servlet>
<servlet-name>SpringDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:demo-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringDispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--spring encoding filter-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--logback listener-->
<listener>
<listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class>
</listener>
<!--spring context loader listener-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--spring memory cleanup listener-->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
</web-app>
CharacterEncodingFilter
是Spring提供的编码过滤器,由于我们开发的大多是中文应用,因此最佳实践就是把整个项目从页面,到IDE,再到数据库,全部统一成UTF-8。
DispatcherServlet
是SpringMVC的核心转发处理器,这很好理解,毕竟SpringMVC是架构在Servlet上的,SpringMVC的Controller要拦截请求,那么必须使用Servlet(类似于Struts2使用Filter)。
IntrospectorCleanupListener
是一个用于Web应用移除时确保资源回收,防止内存泄漏的监听器。
demo-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- use spring annotation -->
<mvc:annotation-driven/>
<!-- base package scan -->
<context:component-scan base-package="com.gacfox.controller"/>
<!-- static resources-->
<mvc:resources location="/static/" mapping="/static/**"/>
<!-- multipart resolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
<!--thymeleaf template-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"/>
</bean>
<bean id="templateResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/template/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
<property name="characterEncoding" value="UTF-8"/>
<!--<property name="cacheable" value="false" />-->
</bean>
<!-- jackson config -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</beans>
这个文件是SpringMVC的DispatcherServlet的配置文件。这里要注意SpringMVC会启动一个子容器,因此该文件不要和原Spring配置文件混淆,也不要互相引用,这样会导致一些Bean的重复加载问题。
<mvc:annotation-driven>
和<context:component-scan>
开启了注解扫描并指定了扫描包,我们代码中Controller层的控制器一般都会标注@Controller
或@RestController
等注解,这些控制器Bean就是通过该配置扫描加载的。
<mvc:resources>
,这个配置是针对静态资源的,比如JS库,CSS库等,location="/resources/"
对应webapp/resources
。mapping="/resources/**"
则表示resources文件夹下的所有文件。如果我们不配置静态资源,那么默认是无法访问到resources目录的。
之后我们配置了一个id
为viewResolver
的Bean,这个是Thymeleaf模板的处理器配置,我们把所有模板文件都放到了webapp/template
文件夹下。SpringMVC常见的可以搭配的模板引擎有JSP、FreeMarker、Velocity以及Thymeleaf等,各有优势,这里就不赘述了,上面例子配置的是Thymeleaf。
实际上,随着技术发展,现在前后端分离项目已经成为主流,由Tomcat提供静态资源、使用后端模板技术等,已经逐渐成为历史。
运行工程的方法比较简单,直接使用mvn package
将工程打包为war
文件,放入Tomcat的webapps
目录,启动服务器便可以访问了。
如果使用Eclipse进行开发,直接在服务器中添加工程,然后启动即可。