SpringMVC 第二篇【基于注册的框架解析】

本文简介

       在前一篇文章中给大家讲述了SpringMVC基本开发框架的搭建,相信看过的朋友已经可以搭建出SpringMVC开发环境了。在本篇文章中,本人将使用Web应用中最常见的注册功能作为引子给大家讲述一下SpringMVC框架的原理。让大家知道SpringMVC框架执行的完整流程。

      SpringMVC框架向大多数MVC框架一样基于请求驱动,设计围绕一个中心Servlet,把请求转发给控制器,提供其他功能,便于web应用程序的开发。然而,Spring的DispatcherServlet远远不止这些。这是完全与Spring IoC容器集成,从而允许你使用Spring拥有的其它功能。

 下图中所示的Spring Web MVC的DispatcherServlet的请求处理流程。精通设计模式的读者会认识到,DispatcherServlet的是“前端控制器设计模式”(这是一个模式,SpringMVC与许多其他领先的Web框架的所共有的)。

(此图源自Spring官方入门指南)   从图中可以看到,请求经过前端控制器也就是DispatcherServlet把请求委托给后台控制器(我们自己创建的Controller),控制器再处理请求,返回model到DispatcherServlet ,DispatcherServlet再解析根据对应的配置文件(servlet-context.xml)解析model为对应的视图返回给用户。 具体的详细流程为: 1.客户端发出Http请求,Web应用服务器接收到这个请求,如果匹配在web.xml中配置的DispatcherServlet请求路径,web容器将请求转交给DispatcherServlet处理。 2.DispatcherServlet接收到请求以后,根据请求的信息(包括URL、HTTP方法、请求头、请求参数、Cookie等)以及HandlerMapping的配置找到处理请求的Handler(我们定义的Controller,SpringMVC没有规定Controller需要继承或者实现相应的接口,这也为我们提供了很大的方便,任何Object都可以成为Controller). 3.DispatcherServlet根据HandlerMapping得到相应请求的Handler后,通过HandlerAdapter进行封装,再以统一的适配器接口调用Handler(HandlerAdapter.handle()  代码可以参见:DispatcherServlet.doDispatch()方法)。 4.HandlerAdapter.handle()方法返回的是ModelAndView,ModelAndView包含了视图逻辑名称以及模型数据信息。 5.DispatcherServlet根据ModelAndView里面的逻辑视图名称使用ViewResolver完成逻辑视图名称到真实视图对象的解析工作。 6.得到真实的视图对象View后,DispatcherServlet就使用后整个View对象对ModelAndView中的模型数据进行视图渲染。 7.最终用户得到的响应消息,可能是普通的HTML页面,也可能是XML或者JSON字符串,甚至是一张图片或者一个PDF文档。 流程讲完了,我们做一个登录功能给大家演示一下这个流程。 首先回顾一下SpringMVC应用开发的基本步骤: 1.配置web.xml 指定业务层对应的Spring配置文件,定义DispatcherServlet. 2.编写视图对象 3.编写请求的控制器 4.配置SpringMVC的配置文件,使控制器视图解析器生效。 在HelloWorld中1、4 我们已经做过了,这里继续使用上次的架子进行开发。           编写视图对象在webapp/WEB-INF/views/user/下面创建register.jsp页面  代码清单如下:  

 
 
  1. <%@ page language="java" contentType="text/html; charset=GBK"
  2. pageEncoding="GBK"%>
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=GBK">
  8. <title>SpringMVC 注册页面</title>
  9. </head>
  10. <body>
  11. <form action="user/register">
  12. <table>
  13. <c:if test="${!empty errorMsg}">
  14. <tr>
  15. <td colspan="2">
  16. <font color="red">${errorMsg}</font>
  17. </td>
  18. </tr>
  19. </c:if>
  20. <tr>
  21. <td>用户名:</td>
  22. <td><input type="text" name="username"/></td>
  23. </tr>
  24. <tr>
  25. <td>密码:</td>
  26. <td><input type="password" name="password"/></td>
  27. </tr>
  28. <tr>
  29. <td><input type="submit" value="注册"/></td>
  30. <td><input type="reset" value="重置"/></td>
  31. </tr>
  32. </table>
  33. </form>
  34. </body>
  35. </html>

在webapp/WEB-INF/views/user/下面创建register_ok.jsp页面  代码清单如下:

 

 
 
  1. <%@ page language="java" contentType="text/html; GBK"
  2. pageEncoding="GBK"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; GBK">
  7. <title>SpringMVC 注册成功</title>
  8. </head>
  9. <body>
  10. <h2>恭喜您,注册成功!用户名:${username}</h2><br>
  11. <a href="../">返回首页</a>
  12. </body>
  13. </html>

在上一节home.jsp页面上加上 <a href="user/toRegister">注册新用户</a>   用于跳转

 

    编写控制器

创建com.yubai.springmvc.web.UserController控制器 用于处理所有与用户有关的操作,代码如下:

 
 
  1. package com.yubai.springmvc.web;
  2.  
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.util.StringUtils;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.servlet.ModelAndView;
  9.  
  10. import com.yubai.springmvc.entity.User;
  11.  
  12. //此注解表明当前类为控制器
  13. @Controller
  14. // 此注解表明 此控制器负责处理来自/user的请求
  15. @RequestMapping("/user")
  16. public class UserController {
  17. private final static Logger logger = LoggerFactory
  18. .getLogger(UserController.class);
  19.  
  20. /**
  21. * 跳转到注册页面
  22. *
  23. * @return
  24. */
  25. // 此注解表示处理/user/toRegister 请求
  26. @RequestMapping("/toRegister")
  27. public String toRegister() {
  28. // 视图解析器会在/user目录下 找到register.jsp页面返回
  29. logger.debug("跳转到注册页面");
  30. return "/user/register";
  31. }
  32.  
  33. /**
  34. * 注册
  35. *
  36. * @param user
  37. * @return
  38. */
  39. // 此注解表示处理/user/register 请求
  40. @RequestMapping("/register")
  41. public ModelAndView register(User user) {
 
 
  1. //User对象SpringMVC自动注入进来的
  2. logger.debug("注册……");
  3. ModelAndView mv = new ModelAndView();
  4. if (StringUtils.isEmpty(user.getUsername())
  5. || StringUtils.isEmpty(user.getPassword())) {
  6. logger.warn("用户名或者密码为空,注册失败");
  7. mv.setViewName("/user/register");
  8. mv.addObject("errorMsg", "用户名或密码不能为空");
  9. } else {
  10.  
  11. mv.setViewName("/user/register_ok");
  12. mv.addObject("username", user.getUsername());
  13. logger.debug("注册成功");
  14. }
  15. return mv;
  16. }
  17. }

 运行注册模块

  

流程解析

对于注册这一过程,再简单的解析一下。   

1.DispatcherServlet接收到客户端的user/toRegister请求 ,使用DefaultAnnotationHadnlerMapping查询负责处理请求的处理器为user/toRegister。

2.DispatcherServlet将请求分发给名称user/toRegister的UserController处理器。

3.处理器处理完后返回ModelAndView 其中视图名称为/user/register,DispatcherServlet调用InternalResourceViewResolver组件对ModelAndView中的逻辑视图名称进行解析,得到真是的/WEB-INF/view/user/register.jsp页面。

4.返回响应页面给客户端。

5. ......同上面

知识点解析

 @Controller:在POJO类定义处标注此注解,再通过<context:component-scan/>扫描响应的类包,即可使POJO成为一个能处理HTTP请求的控制器。 你可以创建很多个控制器,每个控制器用来处理不同的业务方法。如何将请求对应到控制器的任务由@RequestMapping注解承担。  @RequestMapping:在控制器的定义处以及方法的定义出都可以标注@RequestMapping注解。类的定义处标注此注解提供请求的初步映射信息,方法提供进一步的详细映射信息(也可以不在类定义出定义,在那定义的好处是省略了后面重复的定义路径同时也限制死了 当前控制器只能处理当前请求路径下的请求。) 下面一节将详细讲述强大的SpringMVC请求映射规则。 注意:此节我们使用了JSTL标签所以需要增加两个jar包 jstl-api-1.2.jar  jstl-1.2.jar  我已经将jar包放在项目lib路径下了。其它jar包已经在第一篇文章中提供,不予以重复上传。使用MAVEN的同学可以无需理会,MAVEN配置文件中已经增加着两个jar包的依赖。

结束语

      在本节大家已经大致了解了SpringMVC的内部运作机制,其内部实现代码暂不作剖析。注册功能还很不完善,如AJAX请求校验,SpringMVC自带的校验处理 本节均为涉及。后面章节会专门作出讲解。

      下一讲我们将学习Spring的映射规则已经参数的绑定,URL映射、请求参数映射、请求方法映射、请求头映射等。通过下节大家可以看到Spring强大而又灵活的映射方法为我们的开发带来了很多好处。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值