Spring MVC之简单入门

一、Spring MVC简介:
1、什么是MVC
模型-视图-控制器(MVC)是一个众所周知的以设计界面应用程序为基础的设计模式。它主要通过分离模型(Model)、视图(View)及控制器(Control)在应用程序中的角色,从而将业务逻辑从界面中解耦。通常,模型负责封装应用程序数据在视图层展示。视图仅仅只是展示这些数据,不包含任何业务逻辑。控制器负责接收来自用户的请求,并调用后台服务(manager或者dao)来处理业务逻辑。处理后,后台业务层可能会返回了一些数据在视图层展示。控制器收集这些数据及准备模型在视图层展示。MVC模式的核心思想是将业务逻辑从界面中分离出来,允许它们单独改变而不会相互影响。
2、Spring MVC
Spring MVC是当前最优秀的MVC框架,自从Spring 2.5版本发布后,由于支持注解配置,易用性有了大幅度的提高。Spring 3.0更加完善,实现了对Struts 2的超越。现在越来越多的开发团队选择了Spring MVC。
Spring MVC也是服务到工作者模式的实现,但进行可优化。前端控制器是DispatcherServlet;应用控制器其实拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;页面控制器/动作/处理器为Controller接口(仅包含ModelAndView handleRequest(request, response) 方法)的实现(也可以是任何的POJO类);支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。
Struts2也是非常优秀的MVC构架,优点非常多比如良好的结构,拦截器的思想,丰富的功能。但这里想说的是缺点,Struts2由于采用了值栈、OGNL表达式、struts2标签库等,会导致应用的性能下降,应避免使用这些功能。而Struts2的多层拦截器、多实例action性能都很好。 
Spring MVC的优点:
---Spring MVC使用简单,学习成本低。学习难度小于Struts2,Struts2用不上的多余功能太多。
---Spring MVC很容易就可以写出性能优秀的程序,Struts2要处处小心才可以写出性能优秀的程序(指MVC部分)
---Spring MVC的灵活是你无法想像的,Spring框架的扩展性有口皆碑,Spring MVC当然也不会落后,不会因使用了MVC框架而感到有任何的限制。


二、Spring MVC的处理请求的基本流程

一个基本的流程图如下:


Spring MVC处理一个用户的请求的基本流程如下:
1、首先用户发送请求——>web服务器,此时web服务器已经根据web.xml的配置信息完成了相关初始化;
2、web服务器——>总控制器DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制; 
3、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为 HandlerExecutionChain 对象(包含一 个 Handler 处理器(页面控制器)对象、多个 HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新 的映射策略; 
4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处 理方法,完成功能处理;并返回一个 ModelAndView 对象(包含模型数据、逻辑视图名); 
5、ModelAndView 的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的 View,通过这种策略模式,很容易更换其他视图技术; 
6、View——>渲染,View 会根据传进来的 Model 模型数据进行渲染,此处的 Model 实际是一个 Map 数据结构,因此 很容易支持其他视图技术; 
7、返回控制权给 DispatcherServlet,由 DispatcherServlet 返回响应给用户,到此一个流程结束。
我们需要关心的核心开发步骤: 
---DispatcherServlet 需要在 web.xml 中的部署描述,从而拦截请求到 Spring MVC。 
---HandlerMapping 的配置,从而将请求映射到处理器。 
---HandlerAdapter 的配置,从而支持多种类型的处理器 
---ViewResolver 的配置,从而将逻辑视图名解析为具体视图技术 
---处理器(页面控制器)的配置,从而进行功能处理


三、实例演示
这里利用Spring MVC来实现一个查询员工信息的程序。
1、首先建立一个maven web工程,编辑pom.xml导入依赖。
pom.xml
<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>com.kang</groupId>
	<artifactId>SpringmvcTest</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>


	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>


		<!-- Spring MVC support -->


		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.1.4.RELEASE</version>
		</dependency>


		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.1.4.RELEASE</version>
		</dependency>


		<!-- Tag libs support for view layer -->


		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
			<scope>runtime</scope>
		</dependency>


		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
			<scope>runtime</scope>
		</dependency>


	</dependencies>
</project>






2、配置web.xml
配置 DispatcherServlet :DispatcherServlet 默认加载 /WEB-INF/<servletName>-servlet.xml 的 Spring 配置文件, 启动 WEB 层的 Spring 容器。可以通过 contextConfigLocation 初始化参数自定义配置文件的位置和名称。
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="taotao" version="2.5">
	<display-name>SpringmvcTest</display-name>


	<!-- 配置 DispatcherServlet -->
	<servlet>
	<!-- 
	这个Servlet的名字是spring,可以有多个DispatcherServlet,是通过名字来区分的。
	每一个DispatcherServlet有自己的WebApplicationContext上下文对象。
	同时保存在ServletContext中和Request对象中 
	-->
		<servlet-name>spring</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- load-on-startup标示的是启动顺序,让这个Servlet随Servlet容器一起启动 -->
		<load-on-startup>1</load-on-startup>
		<!--  
		配置 DispatcherServlet 的一个初始化参数: 配置 SpringMVC 配置文件的位置和名称
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		-->
		<!-- 这里采用默认配置, SpringMVC会在WEB-INF目录下寻找spring-servlet.xml
		(因为这里定义的servlet-name是spring)来完成初始化-->
	</servlet>






	<!-- 定义拦截哪些请求 -->
	<servlet-mapping>
	    <!-- 与上面定义的servlet-name保持一致 -->
		<servlet-name>spring</servlet-name>
	<!-- 
	url-pattern:表示哪些请求交给Spring Web MVC处理, “/” 是用来定义默认servlet映射的。
	也可以如“*.html”表示拦截所有以html为扩展名的请求。
	 -->
		<url-pattern>/</url-pattern>
	</servlet-mapping>


</web-app>  






3、配置spring的配置文件
上面配置好web.xml后,请求已交给Spring MVC框架处理,因此我们需要配置Spring的配置文件。我们需要在Spring配置文件中配置HandlerMapping、HandlerAdapter。注意此配置文件必须在WEB-INF目录下,且名为spring-servlet.xml。

spring-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:aop="http://www.springframework.org/schema/aop"
	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/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">


	<!-- 配置自定扫描的包 -->
	<context:component-scan base-package="com.kang"></context:component-scan>


    <!-- 
    Spring MVC 提供主要的 HanderMapping 有 DefaultAnnotationHandlerMapping, 
    SimpleUrlHandlerMapping 和  BeanNameUrlHandlerMapping。
     -->
	<bean
		class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
	<bean
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />


    <!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>




配置视图解析器中
InternalResourceViewResolver:用于支持Servlet、JSP视图解析;
prefix和suffix:查找视图页面的前缀和后缀(前缀[逻辑视图名]后缀),比如传进来的逻辑视图名为hello,则该该jsp视图页面应该存放在“WEB-INF/views/hello.jsp”;

4、编写实现代码


---建立员工模型信息:这个类作为MVC模式的模型。
EmployeeVO.java

package com.kang.model;


import java.io.Serializable;


public class EmployeeVO implements Serializable {
	private static final long serialVersionUID = 1L;


	private Integer id;
	private String firstName;
	private String lastName;


	public Integer getId() {
		return id;
	}


	public void setId(Integer id) {
		this.id = id;
	}


	public String getFirstName() {
		return firstName;
	}


	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}


	public String getLastName() {
		return lastName;
	}


	public void setLastName(String lastName) {
		this.lastName = lastName;
	}


	@Override
	public String toString() {
		return "EmployeeVO [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
	}
}






---编写模拟与数据库交互的DAO代码:这个类位于三层架构中的第三层,负责与底层的数据库存储进行交互。
EmployeeDAO.java

package com.kang.dao;


import java.util.List;


import com.kang.model.EmployeeVO;


public interface EmployeeDAO {
	public List<EmployeeVO> getAllEmployees();
}




EmployeeDAOImpl.java

package com.kang.dao;


import java.util.ArrayList;
import java.util.List;


import org.springframework.stereotype.Repository;


import com.kang.model.EmployeeVO;


@Repository
public class EmployeeDAOImpl implements EmployeeDAO {


	public List<EmployeeVO> getAllEmployees() {
		List<EmployeeVO> employees = new ArrayList<EmployeeVO>();


		EmployeeVO vo1 = new EmployeeVO();
		vo1.setId(1);
		vo1.setFirstName("xiaokang");
		vo1.setLastName("chen");
		employees.add(vo1);


		EmployeeVO vo2 = new EmployeeVO();
		vo2.setId(2);
		vo2.setFirstName("lei");
		vo2.setLastName("wang");
		employees.add(vo2);


		return employees;
	}
}






---编写DAO交互服务代码:这个类处于三层架构中的第二层,负责与DAO层交互。
EmployeeManager.java

package com.kang.service;


import java.util.List;


import com.kang.model.EmployeeVO;


public interface EmployeeManager {
	public List<EmployeeVO> getAllEmployees();
}




EmployeeManagerImpl.java
package com.kang.service;


import java.util.List;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.kang.dao.EmployeeDAO;
import com.kang.model.EmployeeVO;


@Service
public class EmployeeManagerImpl implements EmployeeManager {


	@Autowired
	EmployeeDAO dao;


	public List<EmployeeVO> getAllEmployees() {
		return dao.getAllEmployees();
	}
}






---编写控制代码:注解@RequestMapping在类级别和方法级别层面确定将被调用方法的URL。
EmployeeController.java

package com.kang.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


import com.kang.service.EmployeeManager;


@Controller
@RequestMapping("/employee-module")
public class EmployeeController {
	@Autowired
	EmployeeManager manager;


	@RequestMapping(value = "/getAllEmployees", method = RequestMethod.GET)
	public String getAllEmployees(Model model) {
		model.addAttribute("employees", manager.getAllEmployees());
		return "employeesListDisplay"; 
        //对应在WEB-INF/views的目录下应该有一个employeesListDisplay.jsp。


	}
}




5、编写jsp页面
首先写一个index.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Spring MVC Test</title>
</head>
<body>
<a href="employee-module/getAllEmployees">获取员工信息</a>
<!-- 以get的方式发送一个请求,名为employee-module/getAllEmployees -->
</body>
</html>




然后再正确的位置编写一个jsp页面来显示结果。其位置和名称都由之前的相关配置决定。
spring-servlet.xml中一下两句指明了视图的目录为/WEB-INF/views/,后缀名为.jsp。
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
EmployeeController.java中以下语句指定了这个视图的名为employeesListDisplay
return "employeesListDisplay";
综上,应该在/WEB-INF/views/目录下定义一个employeesListDisplay.jsp的文件。
employeesListDisplay.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>


<html>
<head>
<title>Spring MVC Hello World</title>
</head>


<body>
	<h2>All Employees in System</h2>


	<table border="1">
		<tr>
			<th>Employee Id</th>
			<th>First Name</th>
			<th>Last Name</th>
		</tr>
		<c:forEach items="${employees}" var="employee">
			<tr>
				<td>${employee.id}</td>
				<td>${employee.firstName}</td>
				<td>${employee.lastName}</td>
			</tr>
		</c:forEach>
	</table>


</body>
</html>






至此,整个项目构建完毕,完整目录结构如下:




6、测试
将项目部署到tomcat上,访问index.jsp,点击超链接,结果如下:






原文地址:https://www.cnblogs.com/kangsir/p/6653228.html