早在本科期间十分流行的java web框架是SSH,即struts2、spring和hibernate。struts2是一个MVC框架,在web开发中作为控制器来帮助我们建立模型与视图的数据交互,而对于MVC框架来说,如今更加流行的是本篇的主角SpringMVC。看到这个名字也会知道它和spring是有关系的,其实springMVC是依赖于spring的。spring的两大核心是IOC(控制反转,也叫依赖注入DI)和AOP(面向切面编程)。hibernate是一个ORM(对象关系映射)框架,它将POJO与数据表建立映射关系,可以自动生成SQL语句并执行。在这个项目中使用的mybatis是另一个ORM框架,它主要着力于SQL与POJO之间的映射关系,因此可以进行更为细致的SQL优化。
本文介绍的是上述中的Spring MVC的配置过程。Spring MVC是一个基于DispatcherServlet的MVC框架,每一个request请求都是由DispatcherServlet负责转发给相应的Handler,然后再由Handler处理并返回相应的视图(View)和模型(Model)。
现在我们需要使用spring mvc,因此首先需要导入所需的jar包。只需要在pom.xml文件中加入spring mvc的依赖,maven就可以将所需的以下包导入项目中:
添加依赖如下:
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>${spring-version}version>
dependency>
这里为了以后修改spring mvc版本方便,使用了参数的形式,spring-version可以在dependencies节点之前定义:
<properties>
<spring-version>4.3.7.RELEASEspring-version>
properties>
由于是web项目,我们首先需要配置web.xml文件,粘贴如下:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>TODOdisplay-name>
<servlet>
<servlet-name>dispatcherservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<session-config>
<session-timeout>60session-timeout>
session-config>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
web-app>
在servlet标签中我们定义了DispatcherServlet以及映射URL。该servlet通过servlet-name定义了名字dispatcher,默认情况下spring会自动到WEB-INF下扫描dispatcher-servlet.xml文件,这里我们也可以通过init-param中的contextConfigLocation指定配置文件,如类路径下的applicationContext.xml文件。
servlet标签内的load-on-startup元素是可选的,如果存在,则该servlet会在应用程序启动时装载并调用它的init方法,否则会在该servlet的第一次请求时加载。
contextLoaderListener指定了IOC容器初始化的方法,这里指向了类路径下的applicationContext.xml文件。使用applicationContext.xml文件时,需要在web.xml中添加listener,即org.springframework.web.context.ContextLoaderListener。
其实可以看到这里有两个contextConfigLocation,一个是applicationContext.xml,另一个是在servlet节点中的dispatcher-servlet.xml。这两个文件都可以进行spring的配置,至于两者的区别,我们查看spring的官方文档的说明:
Spring lets you define multiple contexts in a parent-child hierarchy.
The applicationContext.xml defines the beans for the "root webapp context", i.e. the context associated with the webapp.
The spring-servlet.xml (or whatever else you call it) defines the beans for one servlet's app context. There can be many of these in a webapp, one per Spring servlet (e.g. spring1-servlet.xml for servlet spring1, spring2-servlet.xml for servlet spring2).
Beans in spring-servlet.xml can reference beans in applicationContext.xml, but not vice versa.
All Spring MVC controllers must go in the spring-servlet.xml context.
In most simple cases, the applicationContext.xml context is unnecessary. It is generally used to contain beans that are shared between all servlets in a webapp. If you only have one servlet, then there's not really much point, unless you have a specific use for it.
可以看到applicationContext.xml不是必需的,它定义的是整个web应用的上下文,与其他xxx-servlet.xml是父子层级关系。xxx-servlet.xml定义了每个对应的servlet的上下文,所有的MVC控制器必需定义在xxx-servlet.xml中。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd"
default-lazy-init="true">
<mvc:annotation-driven>mvc:annotation-driven>
<context:component-scan base-package="com.loveqh.todo.controller"/>
<mvc:resources mapping="/js/**" location="/WEB-INF/static/js/"/>
<mvc:resources mapping="/styles/**" location="/WEB-INF/static/css/"/>
<mvc:resources mapping="/images/**" location="/WEB-INF/static/img/"/>
<mvc:resources location="/WEB-INF/pages/" mapping="/pages/**"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
bean>
beans>
目前没有什么bean,因此是空的。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
beans>
接下来我们就可以定义第一个Controller,代码如下:
package com.loveqh.todo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Created by WL on 2017-04-27.
*/
@Controller
@RequestMapping(value = "/user")
public class LoginController {
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String index() {
System.out.println("用户登录");
return "index";
}
}
这样启动tomcat之后,访问http://localhost:8080/user/login时,DispatcherServlet会将请求转发到LoginController的index方法进行处理。index方法返回一个字符串“index”,根据上面的dispatcher-servlet.xml中的视图解析器定义的前缀和后缀,spring会返回/WEB-INF/pages/index.jsp页面。
在第一次尝试运行时,出现了报错,提示找不到jar包,错误如下:
org.apache.catalina.core.StandardContext listenerStart
严重: Error configuring application listener of class org.springframework.web.context.ContextLoaderListener
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1892)
但是通过仔细检查,spring-context包已经通过maven成功导入了,仍然报错。后经查阅资料,需要将web部署所需的包都拷贝至out目录下的WEB-INF/lib中,将jar包复制过去之后,错误果然消失。
至此,SpringMVC配置大功告成!下一步,我们将使用SpringMVC完成项目的用户注册和登录功能。