SpringMVC是Spring下的一個(gè)模塊,與Spring自然無(wú)縫銜接,相比Structs2我更喜歡SpringMVC。這篇博客介紹一下SpringMVC的基本工作流程最后會(huì)附上一個(gè)小demo可供演示。
先上一張圖:

這張圖展示了SpringMVC大致的工作流程,下面開(kāi)始逐步講解:
- 用戶(hù)通過(guò)瀏覽器發(fā)送一個(gè)Http給Web應(yīng)用。
- 如果該請(qǐng)求與web.xml中DisPatcherServlet的配置匹配,則將該請(qǐng)求交由DispatcherServlet處理。
- DispatcherServlet根據(jù)請(qǐng)求的信息URL、HTTP處理器等信息以及HandlerMapping的配置找到處理請(qǐng)求的Handler(一般是Controller)。
- 找到Handler后,通過(guò)HandlerAdapter對(duì)Handler進(jìn)行封裝,使用統(tǒng)一的接口來(lái)調(diào)用Handler.
- 在Handler完成業(yè)務(wù)處理之后返回一個(gè)ModelAndView給DispatcherServlet,ModelAndView,顧名思義,其中包含一個(gè)邏輯視圖名和模型數(shù)據(jù)信息。
- 然后DisPatcherServlet調(diào)用ViewResolver完成邏輯視圖名到真實(shí)的視圖對(duì)象的解析。
- 當(dāng)?shù)玫秸鎸?shí)的視圖對(duì)象View后,DispatcherServlet會(huì)用這個(gè)View對(duì)ModelAndView中的視圖對(duì)象進(jìn)行渲染。
- 最終返回客戶(hù)端一個(gè)Http相應(yīng),可能是HTML頁(yè)面,也可能是一個(gè)圖片等。
下面做一個(gè)demo來(lái)實(shí)踐一下整個(gè)過(guò)程:
- 先用IDEA創(chuàng)建一個(gè)空的的maven工程(也可以new->project->maven->勾選create from archetype->選中webapp,但感覺(jué)有問(wèn)題)。然后按照web應(yīng)用目錄結(jié)構(gòu)手動(dòng)創(chuàng)建一個(gè)webapp及其子目錄。
- 在pom.xml中添加依賴(lài),最終結(jié)果如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringMVC-Demo</groupId>
<artifactId>springmvc-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<packaging>war</packaging>
</project>
注意要添加jstl依賴(lài),否則會(huì)報(bào)錯(cuò)。
- 配置web.xml和xxx-servlet.xml文件,配置如下:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>Springmvc-demo</display-name>
<servlet>
<servlet-name>vzard</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>vzard</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--解決中文post亂碼-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
vzard-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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--指明 controller 所在包,并掃描其中的注解-->
<context:component-scan base-package="org.vzard.Controller"/>
<!-- 靜態(tài)資源(js、image等)的訪問(wèn) -->
<mvc:default-servlet-handler/>
<!-- 開(kāi)啟注解 -->
<mvc:annotation-driven/>
<!--ViewResolver 視圖解析器-->
<!--用于支持Servlet、JSP視圖解析-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
這里要注意的是還要添加一個(gè)applicationContext.xml文件,這個(gè)文件是Spring的全局配置文件,親測(cè)不配置會(huì)報(bào)錯(cuò),里面可以不配置東西,但是這個(gè)文件一定要有。
applicationContext.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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
</beans>
- 然后就是業(yè)務(wù)邏輯分析部分,這個(gè)demo要做的事是:開(kāi)啟應(yīng)用-->進(jìn)入歡迎頁(yè),點(diǎn)擊注冊(cè)-->進(jìn)入注冊(cè)頁(yè)面,輸入信息,點(diǎn)擊提交-->進(jìn)入注冊(cè)成功頁(yè)面,顯示用戶(hù)信息
- 業(yè)務(wù)邏輯實(shí)現(xiàn):
UserController類(lèi):
package org.vzard.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.vzard.domain.User;
import org.vzard.service.UserService;
/**
* Created by V-zar on 2017/8/25.
*/
@Controller
public class UserController {
// @Autowired(required = false)
//UserService userService;
@RequestMapping("/")
public String index() {
return "index";
}
@RequestMapping("/adduser")
public String addUser() {
return "adduser";
}
@RequestMapping(value = "/success")
public ModelAndView register(User user) {
//userService.creatUser(user);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("success");
modelAndView.addObject("user", user);
return modelAndView;
}
}
User類(lèi):
package org.vzard.domain;
/**
* Created by V-zar on 2017/8/25.
*/
public class User {
public String userName;
public String password;
public String realName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
}
前端界面引入了Bootstrap(然并卵,還是巨丑,懶得寫(xiě)界面):
index.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3個(gè)meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
<title>SpringMVC Demo 首頁(yè)</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" >
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>WELCOME</h1>
<form method="post" action="<c:url value="/adduser"/>">
<button class="btn btn-default" type="submit">
<span>注冊(cè)</span>
</button>
</form>
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
adduser.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3個(gè)meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
<title>SpringMVC Demo 首頁(yè)</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" >
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<form method="post" action="<c:url value="/success"></c:url> ">
<div class="input-group">
<span class="input-group-addon">用戶(hù)名</span>
<input type="text" name="userName" class="form-control" aria-label="Amount (to the nearest dollar)">
</div>
<div class="input-group">
<span class="input-group-addon">密碼</span>
<input type="text" name="password" class="form-control" aria-label="Amount (to the nearest dollar)">
</div>
<div class="input-group">
<span class="input-group-addon">姓名</span>
<input type="text" name="realName" class="form-control" aria-label="Amount (to the nearest dollar)">
</div>
<button type="submit" class="btn btn-default" aria-label="Right Align">提交</button>
</form>
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
success.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3個(gè)meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
<title>SpringMVC Demo 首頁(yè)</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" >
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>歡迎,${user.userName}</h1>
<h1>您的密碼是:${user.password}</h1>
<h1>您的真實(shí)姓名是:${user.realName}</h1>
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
運(yùn)行結(jié)果:



完整demo可在我的github上clone運(yùn)行:Demo
運(yùn)行環(huán)境&工具:
- IDEA
- JDK 1.8
- Tomcat 8.5