1.SpringMVC 的 DispatcherServlet
SpringMVC框架提供了一个DispatcherServlet 作用前端控制器来分派请求,同时提供灵活的配置处理程序映射、视图解析、语言环境和主题解析,并支持文件上传。SpringMVC还包含多种视图技术,例如JSP、Velocity、Tiles、POI等。SpringMVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
SpringMVC 提供了一个名为 org.springframework.web.servlet.DispatcherServlet 的Servlet 充当前端控制器,所有的请求驱动都围绕这个 DispatcherServlet 来分派请求。
DispatcherServlet 是一个Servlet (它继承自 HttpServlet 基类),因此使用时需要把它配置在Web应用的部署描述符web.xml文件中,配置信息如下:
<servlet>
<!--Servlet的名称-->
<servlet-name>SpringMVC</servlet-name>
<!--Servlet对应的java类-->
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--该Servlet的参数信息-->
<init-param>
<!--contextConfigLocation是参数名称,该参数值包含SpringMVC的配置文件路径-->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
<!--在web应用启动时立即加载Servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--Servlet映射声明-->
<servlet-mapping>
<!--请求对应的Servlet的名称-->
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
以上是标准JavaEE Servlet的配置。配置了一个DispatcherServlet,该Servlet在Web应用程序启动时立即加载,DispatcherServlet加载时会需要一个SpringMVC的配置文件,默认情况下,应用会去应用程序文件夹的WEB-INF下查找对应的[servlet-name]-servlet.xml 文件,例如本例的<servlet-name>是SpringMVC,默认查找的就是/WEB-INF/SpringMVC-servlet.xml。
但也可以讲SpringMVC的配置文件放到应用程序文件夹的任何地方,用servlet 元素的 init-param子元素进行描述,本例的 param-name 元素的值 contextConfigLocation 表示参数名称,param-value 元素的值 /WEB-INF/springmvc-config.xml 则表示 SpringMVC 的配置文件路径和名称。则DispatcherServlet 会查找/WEB-INF/springmvc-config.xml 文件作为 SpringMVC 的配置文件,解析该文件内容并根据文件配置信息创建一个WebApplicationContext 容器对象,也称为上下文环境。WebApplicationContext继承自ApplicationContext 容器,WebapplicationContext 需要 ServletContext 实例,也就是说,它必须在拥有Web容器的前提下才能完成启动SpringWeb 应用上下文的工作。
2.基于Controller 接口的控制器
DispatcherServlet 在 Spring 当中充当一个前端控制器的角色,它的核心功能是分发请求。请求会被分发给对应处理的 Java 类,SpringMVC 中称为 Handle。在 Spring2.5 版本以前,开发一个 Handle 的唯一方法是实现 org.springframework.web.servlet.mvc.Controller 接口。 Controller 接口必须实现一个方法,该方法的签名如下:
ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response)throws Exception
Controller 接口的实现类可以通过 handleRequest 方法传递的参数访问对应请求的 HttpServletRequest 和 HttpServletResponse 对象,处理完业务请求后,必须返回一个包含模型对象和视图路径的 ModelAndView对象。
接下来我们演示一个基于 Controller 接口的 SpringMVC 控制器的 Web 应用,以便展示 SpringMVC 是如何工作的
①增加Spring的支持
首先使用Eclipse新建一个 Dynamic Web Project ,也就是新建一个动态Web 项目,命名为 SpringMVCTest。
为了让Web 应用具有Spring 支持的功能,将 spring-framework-4.2.0.RELEASE 解压文件夹吓所以Spring 框架的class文件的JAR包和Spring 所依赖的commons-logging-1.2.jar复制到Web 应用的lib 文件夹下,也就是 SpringMVCTest\WebContent\WEB-INF\lib 路径下。
②配置DIspatcherServlet
打开WebContent\WEB-INF\web.xml文件,配置信息和上文的DispatcherServlet 配置一样。
③配置SpringMVC 的Controller
接下来是SpringMVC 的配置文件,配置信息如下:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!--配置 Handle,映射"/test" 请求-->
<bean name="/test" class="com.controller.TestController"/>
<!--处理映射器将bean 的 name 作为url 进行查找,需要在配置Handle 时指定name (即url)-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--配置处理适配器,所有处理适配器都要实现 HandlerAdapter 接口-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
</beans>
springmvc-config.xml文件声明了TestController 业务控制器类,并将其映射到/test 请求。
此处配置了一个处理映射器、处理适配器、视图解析器,但在Spring4.0之后,如果不配置处理映射器、处理适配器、视图解析器,也会默认的完成Spring内部的MVC工作。
④Controller 类的实现
TestController 类实现了 Controller 接口,用来处理/test 请求,示例代码如下:
package com.springmvcTest.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;
public class TestController implements Controller{
private static final Log logger= LogFactory.getLog(TestController.class);
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception{
logger.info("handleRequest 被调用");
//创建准备返回的ModelAndView 对象,该对象通常包含了返回视图名、模型的名称及模型对象
ModelAndView mv=new ModelAndView();
//添加模型对象
mv.addObject("message","Hello World!");
//设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面
mv.setViewName("/WEB-INF/content/welcome.jsp");
return mv;
}
}
⑤View页面
<%@ 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>welcome</title>
</head>
<body>
${requestScope.message }
</body>
</html>