Spring学习(十六)-SpringMVC入门

SpringMVC框架围绕DispatcherServlet这个核心展开,DispatcherServlet是SpringMVC的总指挥,它负责截获请求并将其分配给其相应的处理器处理。SpringMVC框架包括注解驱动控制器、请求及响应的信息处理、视图解析、本地化解析、上传文件解析、异常处理以及表单标签绑定等内容。

体系结构

SpringMVC是基于model2实现的技术框架,model2是经典的MVC(model、view、control)模型在Web应用中的变体,这个改变主要源于HTTP协议的无状态性。model2的目的和MVC一样,也是利用处理器分离模型、视图和控制,达到不同技术层级间松散层耦合的效果,提高系统灵活性、复用性和可维护性。

从接收请求到返回响应,SpringMVC框架中各个组件相互配合,各司其职。在整个框架中,DispatcherServlet处于核心位置,它负责协调和组织不同组件来完成请求处理并返回响应的工作。SpringMVC通过一个前端Servlet接收所有的请求,并将具体工作委托给其他组件进行处理,DispatcherServlet就是SpringMVC的前端Servlet。

  1. 从客户端发送一个HTTP请求开始,Web应用服务器接收到这个请求,如果匹配DispatcherServlet的请求映射路径(在web.xml指定),Web容器将该请求转交给DispatcherServlet处理。
  2. DispatcherServlet接收到请求后,将根据请求的信息(URL、HTTP方法、请求报文头、请求参数、Cookie等)及HandlerMapping的配置找到处理请求的处理器(Handler)。
  3. 当DispatcherServlet根据HandlerMapping得到对应当前请求的控制器后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。HandlerAdapter是SpringMVC的框架级接口,HandlerAdapter是一个适配器,它用统一的接口对各种Handler方法进行调用。
  4. 处理器完成业务逻辑的处理后将返回一个ModelAndView给DispatcherServlet,ModelAndView包含了视图逻辑名和模型数据信息。
  5. ModelAndView中包含的是“逻辑视图名”而非真正的视图对象,DispatcherServlet借由ViewResolver完成逻辑视图名到真实视图对象的解析工作。
  6. 当得到真实视图对象View后,DispatcherServlet就是用这个View对象对ModelAndView中的模型数据进行视图渲染。
  7. 最终客户端得到响应信息,可能是一个普通的HTML页面,也可能是一个XML或JSON串,甚至是一张图片或一个PDF文档等不同的媒体形式。

SpringMVC简单例子

SpringMVC应用一般包括以下步骤:

  1. 配置web.xml,指定业务层对应的Spring配置文件,定义DispatcherServlet;
  2. 编写处理请求的控制器(处理器);
  3. 编写视图对象(JSP等视图对象);
  4. 配置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.xml的形式。在这里,Servlet名为demo,则在/WEB-INF目录下必须提供一个demo-servlet.xml的SpirngMVC配置文件,但这个配置文件无须通过web.xml的ContextLoaderListener上下文参数进行声明,因为SpringMVC的Servlet会自动将demo-servlet.xml和Spring其他配置文件进行拼装。

与此同时,对这个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页面有两个用处,既作为登录页面又作为登录失败后的响应页面。所以定义了,使用JSTL标签将登录错误返回的信息进行处理。JSTL标签中引用了error变量,这变量正是LoginController中返回的ModelAndView(“login”,“error”,“用户名或密码错误。”)对象所声明的error参数。其中,userName和password应该与实体类LoginCommand对应参数,这样才可以将请求参数按匹配入参。

login.jsp的登录表单提交到loginCheck.html,的JSTL标签会在URL前自动加上应用程序部署根目录。

由于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。

整个例子实现的过程:

  1. DispatcherServlet接收到客户端的/loginCheck.html请求;
  2. DispatcherServlet使用DefaultAnnotationHandlerMapping查找负责处理该请求的控制器为“/loginCheck.html”;
  3. DispatcherServlet将请求分发给名为“/loginCheck.html”的LoginController处理器;
  4. 处理器完成业务处理后,返回ModelAndView对象,其中View的逻辑名为“main”或“login”;
  5. DispatcherServlet调用InternalResourceViewResolver组件对ModelAndView中的逻辑视图名进行解析,得到真实的“/WEB-INF/jsp/login.jsp”或“/WEB-INF/jsp/main.jsp”视图对象;
  6. DispatcherServlet使用真实的视图对象对模型中的数据信息进行渲染;
  7. 返回响应页面给客户端。

你可能感兴趣的:(Spring,SpringMVC体系)