SpringMVC框架围绕DispatcherServlet这个核心展开,DispatcherServlet是SpringMVC的总指挥,它负责截获请求并将其分配给其相应的处理器处理。SpringMVC框架包括注解驱动控制器、请求及响应的信息处理、视图解析、本地化解析、上传文件解析、异常处理以及表单标签绑定等内容。
SpringMVC是基于model2实现的技术框架,model2是经典的MVC(model、view、control)模型在Web应用中的变体,这个改变主要源于HTTP协议的无状态性。model2的目的和MVC一样,也是利用处理器分离模型、视图和控制,达到不同技术层级间松散层耦合的效果,提高系统灵活性、复用性和可维护性。
从接收请求到返回响应,SpringMVC框架中各个组件相互配合,各司其职。在整个框架中,DispatcherServlet处于核心位置,它负责协调和组织不同组件来完成请求处理并返回响应的工作。SpringMVC通过一个前端Servlet接收所有的请求,并将具体工作委托给其他组件进行处理,DispatcherServlet就是SpringMVC的前端Servlet。
SpringMVC应用一般包括以下步骤:
配置XML文件:
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
demo
org.springframework.web.servlet.DispatcherServlet
2
demo
*.html
index.jsp
在XML中声明了一个Servlet,SpringMVC也拥有一个Spring配置文件,该配置文件的文件名和此处定义的Servlet名有一个契约:即采用
与此同时,对这个Servlet的URL路径映射进行定义,在这里让所有以.html为后缀的URL都被demo Servlet截获,进而转由SpringMVC框架进行处理。
请求被SpringMVC截获后,首先根据请求的URL查找到目标的处理控制器,并将请求参数封装成一个对象一起传给控制器处理,控制器调用Spring容器中的业务Bean完成业务处理工作并返回结果视图。
编写控制器:
.....
@Controller//标注称为一个Spring MVC的Controller
public class LoginController {
@Autowired
private UserService userService;
//负责处理index.html的请求
@RequestMapping(value="/index.html")
public String loginPage(){
return "login";
}
//负责处理loginCheck.html的请求
@RequestMapping(value="/loginCheck.html")
public ModelAndView loginCheck(HttpServletRequest request,LoginCommand loginCommand){
boolean isValidUser = userService.hasMatchUser(loginCommand.getUserName(), loginCommand.getPassword());
if(!isValidUser){
return new ModelAndView("login","error","用户名或密码错误。");
}else{
User user = userService.findUserByUserName(loginCommand.getUserName());
user.setLastIp(request.getRemoteAddr());
user.setLastVisit(new Date());
userService.loginSuccess(user);
request.getSession().setAttribute("user", user);
return new ModelAndView("main");
}
}
}
通过SpringMVC的@Controller注解可以将任何一个POJO的类标注为SpringMVC的控制器,处理HTTP的请求。当然标注了@Controller的类首先会是一个Bean,所以我们可以使用@Autowired进行Bean的注入。
一个控制器可以拥有多个对应不同的HTTP请求路径的处理方法,通过@RequestMapping指定方法如何映射请求路径。
请求的参数会根据参数名称默认契约自动绑定到响应方法的入参中,在loginCheck(HttpServletRequest request,LoginCommand loginCommand)方法中,请求参数会按名称匹配绑定到loginCommand的入参中。
请求响应方法可以返回一个ModelAndView,或直接返回一个字符串,SpringMVC会解析之并转向目标响应页面。ModelAndView对象既包括了视图信息又包括了视图渲染所需的模型数据信息。控制器根据登录处理结果分别返回ModelAndView(“login”,“error”,“用户名或密码错误。”)和ModelAndView(“main”)。ModelAndView的第一个参数代表视图的逻辑名,第二和第三个参数分别为数据模型名称和数据模型对象,数据模型对象将以数据模型名称为参数名放置到request的属性中。
编写视图对象:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
登录首页
" method="post">
用户名:
密码:
login.jsp页面有两个用处,既作为登录页面又作为登录失败后的响应页面。所以定义了
login.jsp的登录表单提交到loginCheck.html,
由于login.jsp放置在WEB-INF/jsp目录下,无法直接通过URL进行调用,它由LoginController控制类中标注了@RequestMapping(value="/index.html")的loginPage()进行转发。
配置SpringMVC文件:
我们需要在demo-servlet.xml中声明该控制器,扫描Web路径,指定SpringMVC的视图解析器。通过InternalResourceViewResolver为视图逻辑名添加前后缀的方式进行解析。如视图逻辑名为“login”将解析为/WEB-INF/jsp/login.jsp,名为“main”的视图解析为/WEB-INF/jsp/main.jsp。
整个例子实现的过程: