1、SpringMVC的优势
Spring框架提供了构建Web应用程序的全功能MVC模块——Spring MVC。Spring MVC框架提供了一个DispatcherServlet作用前端控制器来分派请求,同时提供灵活的配置处理程序映射、视图解析、语言环境和主题解析,并支持文件上传。Spring MVC还包含了多种视图技术,例如JSP、Velocity、Tiles、iText和POI等。Spring MVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
Spring MVC的特点:
(1)Spring MVC拥有强大的灵活性、非入侵性和可配置性。
(2)Spring MVC 提供了一个前端控制器DispatcherServlet,开发者无须额外开发控制器对象。
(3)Spring MVC分工明确,包含控制器、验证器、命令对象、模型对象、处理程序映射视图解析器,等等,每一个功能实现由一个专门的对象负责完成。
(4)Spring MVC可以自动绑定用户输入,并正确地转换数据类型。例如:Spring MVC能自动解析字符串,并将其设置为模型的int或float类型的属性。
(5)Spring MVC使用一个名称/值的Map对象实现更加灵活的模型数据传输。
(6)Spring MVC内置了常见的校验器,可以校验用户输入,如果校验不通过,则重定向回输入表单。输入校验是可选的,并且支持编程方式及声明方式。
(7)Spring MVC支持国际化,支持根据用户区域显示多国语言,并且国际化的配置非常简单。
(8)Spring MVC支持多种视图技术,最常见的有JSP技术以及其他技术,包括Velocity和FreeMarker。
(9)Spring 提供了一个简单而强大的JSP标签库,支持数据绑定功能,使得编写JSP页面更加容易。
2.1基于xml配置开发
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
servlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>/WEB-INF/springmvc-config.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
在许多的SpringMVC框架中,都包含一个用于调度控制的Servlet。Spring MVC 也提供了一个名为 org.springframework.web.servlet.DispatcherServlet的Servlet充当前端控制器,所有的请求驱动都围绕这个DispatcherServlet来分派请求。
(3)在Java目录下的src目录下新建包org.fkit.controller并且在包下建名为HelloController的类,如下所示:
package org.fkit.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
/**
* HelloController是一个实现Controller接口的控制器,
* 可以处理一个单一的请求动作
*/
public class HelloController implements Controller{
private static final Log logger = LogFactory
.getLog(SpringController.class);
/**
* handleRequest是Controller接口必须实现的方法。
* 该方法的参数是对应请求的HttpServletRequest和HttpServletResponse。
* 该方法必须返回一个包含视图路径或视图路径和模型的ModelAndView对象。
* */
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
logger.info("handleRequest 被调用");
// 创建准备返回的ModelAndView对象,该对象通常包含了返回视图的路径、模型的名称以及模型对象
ModelAndView mv = new ModelAndView();
// 添加模型数据 可以是任意的POJO对象
mv.addObject("message", "Hello World!");
// 设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面
mv.setViewName("/WEB-INF/content/welcome.jsp");
// 返回ModelAndView对象。
return mv;
}
}
在Spring MVC 中处理请求的Java类被称为Handle,在Spring2.5之前,开发一个Handle的唯一方法就是实现org.springframework.web.servlet.mvc.Controller接口。Controller接口必须实现一个方法,该方法签名:`ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception`。
Controller接口的实现类可以通过handleRequest方法传递的参数访问对应请求的HttpServletRequest和HttpServletResponse对象,处理完业务之后,必须返回一个包含模型对象和视图路径的ModelAndView对象。
(4)在WebContent路径下的WEB-INF目录下新建名为springmvc-config.xml文件的,内的代码如下所示:
<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-4.2.xsd">
<bean name="/hello" class="org.fkit.controller.HelloController"/>
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
beans>
(5)在WebContent路径下的WEB-INF目录下新建名为content的目录并且新建名为welcome.jsp的文件:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>欢迎页面title>
head>
<body>
${requestScope.message}
body>
html>
(6)然后部署到tomcat中,启动tomcat,在浏览器地址栏中输入:http://localhost:8080/SpringMVCTest/hello然后回车,页面最后显示为下图即可:
2.2基于注解开发
我们基于注解开发的例子是基于上面的例子的,只需要进行一些修改就可以的。
(1)将springmvc-config.xml,修改成如下代码所示即可:
<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-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="org.fkit.controller"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
beans>
这里面主要是添加了约束文件、包扫配置、类型处理映射器、类型处理适配器。
(2)将HelloController类改成如下所示即可,主要是去掉实现Controller接口,和实现里面的handleRequest方法。只是需要添加两个注解@Controller和@RequestMapping(value=”/hello”)即可。
package org.fkit.controller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* HelloController是一个基于注解的控制器,
* 可以同时处理多个请求动作,并且无须实现任何接口。
* org.springframework.stereotype.Controller注解用于指示该类是一个控制器
*/
@Controller
public class HelloController{
private static final Log logger = LogFactory
.getLog(HelloController.class);
/**
* org.springframework.web.bind.annotation.RequestMapping注解
* 用来映射请求的的URL和请求的方法等。本例用来映射"/hello"
* hello只是一个普通方法。
* 该方法返回一个包含视图路径或视图路径和模型的ModelAndView对象。
* */
@RequestMapping(value="/hello")
public ModelAndView hello(){
logger.info("hello方法 被调用");
// 创建准备返回的ModelAndView对象,该对象通常包含了返回视图的路径、模型的名称以及模型对象
ModelAndView mv = new ModelAndView();
//添加模型数据 可以是任意的POJO对象
mv.addObject("message", "Hello World!");
// 设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面
mv.setViewName("/WEB-INF/content/welcome.jsp");
// 返回ModelAndView对象。
return mv;
}
}
(3)在浏览器地址栏中输入http://localhost:8080/SpringMVCTest/hello即可访问,页面显示如下图即为成功。
3、Spring MVC应用的开发步骤
(1)在web.xml文件中定义前端控制器DispatcherServlet来拦截用户请求。
由于Web应用是基于请求响应架构的应用所以不管哪个MVC Web框架,都需要web.xml中配置该框架的核心Servlet或Filter,这样才可以让该框架介入Web应用中。
(2)如果需要以POST方式提交请求,则定义包含表单数据的JSP页面。如果仅仅只是以GET方式来发送请求,则无须经过这一步。
(3)定义处理用户请求的Handle类,可以实现Controller接口或使用@Controller注解。
这一步也是所有MVC框架中必不可少的,因为这个DispatcherServlet就是MVC中的C,也就是前端控制器,该控制器负责接收请求,并将请求分发给对应的Handle,即实现Controller接口的Java类,而该Java类负责调用后台业务逻辑代码来处理请求。
(4)配置Handle。
Java领域的绝大部分MVC框架都非常喜欢使用xml文件来进行配置管理,这在以前是一种思维定势。即配置哪个请求对应哪个Controller进行处理,从而让前端控制器根据该配置来创建合适的Controller实例,并调用该Controller的业务控制方法。
(5)编写视图资源。
当Handler处理用户请求结束后,通常会返回一个ModelAndView对象,该对象应该包含返回的视图名或视图名和模型,这个视图名就代表需要显示的物理视图资源。如果Handle需要把一些数据传给视图资源,则可以通过资源对象。
4、Spring MVC的执行流程
Spring MVC请求–>响应的完整工作流程如下:
(1)用户想服务器发送请求,请求被Spring的前端控制器DispatcherServlet截获。
(2)DispatcherServlet对请求URL进行解析,得到URL。然后根据该URL,调用HandlerMapping获得该Handler配置的所有相关对象,包括Handler对象以及Handler对应的拦截器,这些对象会被封装到一个HandlerExecutionChain对象当中返回。
(3)DispatcherServlet根据获得的handler,选择一个合适的HandlerAdapter。HandlerAdapter的设计符合面向对象中的单一职责原则,代码架构清晰,便于维护,最重要的是,代码可复用性高。HandlerAdapter会被用于处理多种Handler,调用Handler实际处理请求的方法。
(4)提取请求中的模型数据,开始执行Handler(Controller)。在填充Handler的入参过程中,根据配置,Spring将帮你做一些额外的工作。
消息转换:将请求消息(Json、xml等数据)转换成一个对象,将对象转换为指定的响应消息。
数据转换:对请求消息进行数据转换,如String转换成Integer、Double等。
数据格式化:对请求消息进行数据格式化,如将字符串转换成格式化数字或者格式化日期等。
数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
(5)Handler执行完成后,向DispatcherServlet返回一个ModelAndView对象,ModelAndView对象中包含视图名或视图名和模型。
(6)根据返回的ModelAndView对象,选择一个合适的ViewResolver(视图解析器)返回给DispatcherServlet。
(7)ViewResolver结合Model和View来渲染视图。
(8)将视图渲染结果返回给客户端。