精华内容
下载资源
问答
  • Spring企业级程序设计 • 【第5章 Spring MVC快速入门】
    万次阅读 多人点赞
    2021-05-25 11:05:48

    全部章节   >>>>


    本章目录

    5.1 Spring MVC设计概述及其框架结构

    5.1.1 Spring MVC介绍

    5.1.1 Spring MVC优势

    5.1.2  Spring MVC工作原理

    5.1.3 手动搭建Spring MVC环境

    5.1.4 实践练习

    5.2 处理器映射器和适配器

    5.2.1 配置处理器映射器和适配器

    5.2.2   注解驱动

    5.2.3   @RequestMapping注解

    5.2.3 注解驱动

    5.2.4 实践练习

    5.3  Spring MVC简单类型数据绑定

    5.3.1 基本数据类型绑定

    5.3.2  POJO类型数据绑定

    5.3.3 Json类型数据交互

    5.3.4 实践练习

    5.4 Spring MVC复杂类型数据绑定

    5.4.1  List集合类型数据绑定

    5.4.2  Set集合类型数据绑定

    5.4.3  Map集合类型数据绑定

    5.4.4 实践练习

    总结


    5.1 Spring MVC设计概述及其框架结构

    5.1.1 Spring MVC介绍

     Spring MVC是目前最好的实现MVC设计模式的框架,是Spring框架的一个分支产品,以Spring IoC容器为基础,并利用容器的特性来简化它的配置。

    Spring MVC相当于Spring的一个子模块,可以很好地和Spring结合起来进行开发,是Java Web开发者应该要掌握的框架。

    5.1.1 Spring MVC优势

    • 清晰的角色划分
    • 分工明确
    • 无需继承框架特定API,可以使用命令对象直接作为业务对象。
    • 和Spring其他框架无缝集成
    • 可适配,通过HandlerAdapter可以支持任意的类作为处理器。
    • 可定制性,HandlerMapping、ViewResolver等能够非常简单的定制。
    • 功能强大的数据验证、格式化和绑定机制。
    • 利用Spring提供的Mock对象能够非常简单的进行Web层单元测试。
    • 本地化和主题的解析的支持,使我们更容易进行国际化和主题的切换。
    • 强大的JSP标签库,使JSP编写更容易。

    5.1.2  Spring MVC工作原理

    Spring MVC的设计是围绕DispatcherServlet展开的,DispatcherServlet负责将请求派发到特定的处理器。

    5.1.3 手动搭建Spring MVC环境

    示例:搭建SpringMVC开发环境 创建WEB工程。

    添加相关jar。

    在src目录下创建Spring MVC的核心配置文件springmvc.xml。

    在web.xml配置文件中配置Spring MVC的DispatcherServlet前端控制器。

    在WebContent目录下创建index.jsp文件。

    发布程序启动WEB服务器访问。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    		xmlns="http://www.springframework.org/schema/beans" 
    		xmlns:context="http://www.springframework.org/schema/context" 
    		xmlns:aop="http://www.springframework.org/schema/aop" 
    		xmlns:tx="http://www.springframework.org/schema/tx" 
    		xmlns:mvc="http://www.springframework.org/schema/mvc" 
    		xsi:schemaLocation="http://www.springframework.org/schema/beans 
    		http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 
    		http://www.springframework.org/schema/context 
    		http://www.springframework.org/schema/context/spring-context-4.2.xsd 
    		http://www.springframework.org/schema/aop 
    		http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
    		http://www.springframework.org/schema/tx 
    		http://www.springframework.org/schema/tx/spring-tx-4.2.xsd 
    		http://www.springframework.org/schema/mvc 
    		http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd ">
    	<!-- 此处输入内容 -->
    </beans>
    
    <!-- 配置前端控制器 -->
    <servlet>
    	<servlet-name>springmvc</servlet-name>
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	<!-- 指定Spring MVC的核心配置文件 -->
    	<init-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>classpath:springmvc.xml</param-value>
    	</init-param>
    	<load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    	<servlet-name>springmvc</servlet-name>
    	<!-- 拦截所有以do结尾的请求 -->
    	<url-pattern>*.do</url-pattern>
    </servlet-mapping>

    5.1.4 实践练习

     

    5.2 处理器映射器和适配器

    在Spring MVC中,处理器映射器和适配器这两个组件在Spring MVC整个的运行流程之中扮演一个很重要的角色。

    映射器和适配器两个组件的功能:

    • 映射器主要是跟在浏览器上输入的URL来映射对应的Handle,具体的映射规则需要根据使用哪一个映射器来决定
    • 适配器主要是决定调用哪个Handler来实现具体的业务逻辑。

    5.2.1 配置处理器映射器和适配器

    示例:配置官方推荐的处理器映射器和适配器,在页面中输出结果。

    <!-- 开启注解扫描功能 -->
    <context:component-scan base-package="com.mhys.demo"></context:component-scan>
    <!-- 配置处理器映射器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
    <!-- 配置处理器适配器 -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
    

    @RequestMapping注解将url请求与业务方法进行映射。

    ModelAndView对象的作用:设置转向地址和传递处理器中方法处理结果数据到结果页面。

    5.2.2   <mvc:annotation-driven />注解驱动

    手动配置处理器映射器和适配器比较麻烦,也不便于记忆。为了简化配置,官方提供了<mvc:annotation-driven />注解驱动标签来简化配置

    此标签会自动注册RequestMappingHandlerMapping和RequestMappingHandlerAdapter两个Bean,当然还简化了其他的一些配置信息。

    示例: 通过<mvc:annotation-driven />注解驱动标签来简化处理器映射器和适配器的配置。

    5.2.3   @RequestMapping注解

    Spring MVC通过@RequestMapping注解将url请求与业务方法进行映射。在Spring MVC框架中,@RequestMapping注解的使用频率很高,它可以添加在处理器类上以及方法上,在类定义处添加@RequestMapping注解,相当于多了一层访问路径。

    @RequestMapping注解有三个常用的属性:

    • value:指定url请求的实际地址,是@RequestMapping的默认值,可省略不写。
    • method:指定请求的类型,get、post、put和delete等,常用get和post类型请求。
    • params:指定请求中必须包含某些参数值,否则无法调用该方法。

    5.2.3 <mvc:annotation-driven />注解驱动

     示例:通过@RequestMapping完成GET和POST请求处理。

    @Controller
    @RequestMapping("/first")
    public class RequestMappingController {
    	@RequestMapping(value="/postTest",method=RequestMethod.GET)
    	public ModelAndView testMethod(){
    		ModelAndView model= new ModelAndView();
    		model.addObject("method", "get请求成功!");
    		model.setViewName("/WEB-INF/jsp/test.jsp");
    		return model;
    	}
    }
    

    @Controller
    @RequestMapping("/first")
    public class RequestMappingController {
    	@RequestMapping(value="/postTest",method=RequestMethod.POST)
    	public ModelAndView testMethod(){
    		ModelAndView model= new ModelAndView();
    		model.addObject("method", "get请求成功!");
    		model.setViewName("/WEB-INF/jsp/test.jsp");
    		return model;
    	}
    }
    

    5.2.4 实践练习

     

    5.3  Spring MVC简单类型数据绑定

    在开发中,经常需要用到的是在业务方法中获取url中的参数和前端页面中的参数。这个时候需要了解Spring MVC的数据绑定。数据绑定就是在后台业务方法中,直接获取前端HTTP请求中的参数。

    HTTP请求传输的参数都是String类型,但是Hanlder业务方法中的参数都是指定的数据类型,如int、Object等,所以需要处理参数的类型转换。

    此项工作不需要开发人员去完成,Spring MVC的HandlerAdapter组件会在执行Handler业务方法之前完成参数的绑定。

    5.3.1 基本数据类型绑定

    示例:使用@RequestParam来接收基本数据类型参数。

    @Controller
    @RequestMapping("/method")
    public class MethodController {
    	@RequestMapping("/items")
    	public String getParams(@RequestParam("ownerName") String ownerName,
    		 @RequestParam("itemName") String itemName, @RequestParam("itemPrice")  String itemPrice){
    		
    		System.out.println("ownerName:" + ownerName);
    		System.out.println("itemName:" + itemName);
    		System.out.println("itemPrice:" + itemPrice);
    		return "index.jsp";
    	}
    }
    
    <body>
    	<hr />
    	<h1>添加古董信息</h1><br/>
    	<form action="method/items.do" method="post">
    		宝贝任务:<input type="text" name="ownerName"><br/><br/>
    		宝贝名:<input type="text" name="itemName"><br/><br/>
    		宝贝价格:<input type="text" name="itemPrice"><br/><br/>
    		<input type="submit" value="添加">
    	</form>
    </body>
    

    5.3.2  POJO类型数据绑定

    示例:接收页面提交的参数实现对入参数据的封装。

    //地址实体类
    public class Address {
    		private String addressId;
    		private String addressName;
    		// set()方法和get()方法省略
    		@Override
    		public String toString() {
    			return "Address [addressId=" + addressId + ", addressName="
    				+ addressName + "]";
    		}
    }
    
    //用户实体类
    public class User {
    	private String username;
    	private int age;
    	private Address address;
    	// set()方法和get()方法省略
    		
    	@Override
    	public String toString() {
    		return "User [username=" + username + ", age=" + age + ", address="
    				+ address + "]";
    	}
    }
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    	@RequestMapping("/user")
    		// 进入用户注册页面
    	public ModelAndView intouser(User user){
    		ModelAndView model = new ModelAndView();
    		model.setViewName("/WEB-INF/jsp/user.jsp");
    		return model;
    	}
    	@RequestMapping("/info")
    	public String userInfo(User user){
    		System.out.println(user);
    		return null;
    	}
    }
    
    <body>
    	<form action="info.do" method="post">
    		姓名:<input type="text" name="username"/><br/><br/>
    		年龄:<input type="text" name="age"/><br/><br/>
    		地址编号:<input type="text" name="address.addressId"/><br/><br/>
    		地址:<input type="text" name="address.addressName"/><br/><br/>
    	<input type="submit" value="提交"/>
    	</form>
    </body>
    

    5.3.3 Json类型数据交互

    在前后端交互中,经常碰见Ajax请求后端业务方法并将Json格式的参数传到后端的情况。如果需要Spring MVC支持Json,必须加入Json的处理jar包。添加jar包。

    示例:将客户的账号和金额传到后端,然后将金额加100返回客户信息到前端。这里将使用@RequestBody注解和@ResponseBody注解来接收Json格式数据和返回Json格式数据。

    @Controller
    @RequestMapping("/customer")
    public class CustomerController {
    	@RequestMapping(value="/jsontest",method=RequestMethod.POST )
    	@ResponseBody
    	public Customer jsonTest(@RequestBody Customer customer ){
    		System.out.println(customer.getCustomerId()+"------"+customer.getMoney());
    		int money = customer.getMoney() + 100;
    		customer.setMoney(money);
    		return customer;
    	}
    	@RequestMapping("/json")
    	@ResponseBody
    		// 进入页面
    	public ModelAndView intoJson(){
    		ModelAndView model = new ModelAndView();
    		model.setViewName("/WEB-INF/jsp/customer.jsp");
    		return model;
    	}
    }
    
    <script type="text/javascript" language="javascript">
    	$(document).ready(function(){
    		var customer = {"customerId":"584135","money":105};
    		$("#json").click(function () {
    			$.ajax({
    				url:"<%=request.getContextPath() %>/customer/jsontest.do",
    		        data:JSON.stringify(customer), // 将Json对象转换成Json字符串
    		        contentType: "application/json;charset=UTF-8",
    		        type:"post",
    		        dataType:"json",
    		        success:function(data){
    		            alert(data.customerId+"---"+data.money);
    		        }
    			})
    		}); 
    	});
    </script>
    

    5.3.4 实践练习

     

    5.4 Spring MVC复杂类型数据绑定

    5.4.1  List集合类型数据绑定

    示例:在前台页面注册多个员工的信息,后台通过List集合数据绑定来获取员工集合信息。

    public class Employee {
    	private String id;
    	private String name;
    	
    	@Override
    	public String toString() {
    		return "Employee [id=" + id + ", name=" + name + "]";
    	}
    // set()方法和get()方法省略
    }
    
    @Controller
    public class EmployeeController {
    	@RequestMapping("/employeeList")
    	@ResponseBody
    	public String getEmployeeList(EmployeeList employeeList){
    		StringBuffer sbf = new StringBuffer();
    		for(Employee employee : employeeList.getEmployees()){
    			sbf.append(employee);
    		}
    		return "员工:" + sbf.toString();
    	}
    }
    
    <body>
    	<form action="employeeList.do" method="post">
    		员工1编号:<input type="text" name="employees[0].id"/>
    		员工1姓名:<input type="text" name="employees[0].name"/><br/><br/>
    		员工2编号:<input type="text" name="employees[1].id"/>
    		员工2姓名:<input type="text" name="employees[1].name"/><br/><br/>
    		员工3编号:<input type="text" name="employees[2].id"/>
    		员工3姓名:<input type="text" name="employees[2].name"/><br/><br/>
    		<input type="submit" value="List提交"/>
    	</form>
    </body>
    

    5.4.2  Set集合类型数据绑定

    示例:通过Set集合来完成员工信息集合的数据绑定。

    public class EmployeeSet {
    		private Set<Employee> employees = new HashSet<Employee>();
    
    		public EmployeeSet() {
    			employees.add(new Employee());
    			employees.add(new Employee());
    			employees.add(new Employee());
    		}
    		// set()方法和get()方法省略
    }
    
    @Controller
    public class EmployeeController {
    	// 原有代码省略
    	@RequestMapping("/employeeSet")
    	@ResponseBody
    	public String getEmployeeSet(EmployeeSet employeeSet){
    		StringBuffer sbf = new StringBuffer();
    		for(Employee employee : employeeSet.getEmployees()){
    			sbf.append(employee);
    		}
    		return "员工:" + sbf.toString();
    	}
    }
    
    <body>
    	<form action="employeeList.do" method="post">
    		员工1编号:<input type="text" name="employees[0].id"/>
    		员工1姓名:<input type="text" name="employees[0].name"/><br/><br/>
    		员工2编号:<input type="text" name="employees[1].id"/>
    		员工2姓名:<input type="text" name="employees[1].name"/><br/><br/>
    		员工3编号:<input type="text" name="employees[2].id"/>
    		员工3姓名:<input type="text" name="employees[2].name"/><br/><br/>
    		<input type="submit" value="List提交"/>
    	</form>
    </body>
    

    5.4.3  Map集合类型数据绑定

    示例:通过Map集合来完成员工信息集合的数据绑定。

    @Controller
    public class EmployeeController {
    	// 原有代码省略
    
    	@RequestMapping("/employeeMap")
    	@ResponseBody
    	public String getEmployeeMap(EmployeeMap employeeMap){
    		StringBuffer sbf = new StringBuffer();
    		for(String key:employeeMap.getEmployees().keySet()){
    	        		Employee employee = employeeMap.getEmployees().get(key);
    	     		 sbf.append(employee);
    	    	}
    		return "员工:" + sbf.toString();
    	}
    }
    
    <body>
    	<form action="employeeMap.do" method="post">
    		员工1编号:<input type="text" name="employees['a'].id"/>
    		员工1姓名:<input type="text" name="employees['a'].name"/><br/><br/>
    		员工2编号:<input type="text" name="employees['b'].id"/>
    		员工2姓名:<input type="text" name="employees['b'].name"/><br/><br/>
    		员工3编号:<input type="text" name="employees['c'].id"/>
    		员工3姓名:<input type="text" name="employees['c'].name"/><br/><br/> 
    		// 原有代码省略
    		&nbsp;&nbsp;&nbsp;&nbsp;<input type="submit" value="Map提交"/>
    	</form>
    </body>
    

    5.4.4 实践练习

     

    总结

    Spring MVC的主要组件:

    • DispatcherServlet前端控制器:作为前端控制器,整个流程控制的中心。
    • HandlerMapping处理器映射器:通过扩展处理器映射器实现不同的映射方式。
    • HandlAdapter处理器适配器:通过扩展处理器适配器,支持更多类型的处理器。
    • ViewResolver视图解析器:通过扩展视图解析器,支持更多类型的视图解析。

    @RequestMapping:用于处理请求URL映射的注解,可用于类或方法上。

    @RequestBody:注解实现接收HTTP请求的Json数据,将Json转换为java对象。

    @ResponseBody:注解实现将Conreoller处理器类中方法返回对象转化为Json对象响应给客户。

    更多相关内容
  • 精通Spring MVC 4

    2017-11-04 13:36:03
    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。Spring MVC4是当前zuixin的版本,在众多特性上有了进一步的提升。, 在精通Spring...
  • spring mvc

    2017-10-31 16:35:39
    spring mvc最小代码。spring mvc最小代码。spring mvc最小代码。spring mvc最小代码。
  • springmvc:Spring MVC教程

    2021-05-26 14:50:10
    Spring MVC教程 教程学习: 本教程完整地讲解了Spring MVC的每个知识点,包括独立运行的Demo示例,欢迎一起交流学习。Java学习交流群:239126529 教程软件版本说明: 1)Spring MVC框架:spring-framework-5.0.2....
  • Spring MVC+MYBatis企业应用实战,内涵PDF文档和课程的源码,PDF 含目录
  • 《Java EE企业级应用开发教程Spring+Spring MVC+MyBatis》配套源代码 Spring 4.3 + Spring MVC 4.3 + MyBatis 3 版本
  • Spring MVC 4.2.3

    2016-07-29 17:55:30
    Spring mvc jar包
  • 介绍Spring MVC框架以及使用套路
  • Spring MVCSpring框架中用于Web应用快速开发的一个模块,被广泛用作当今业界最主流的Web开发框架。内容细致、讲解清晰。
  • Spring MVC 学习指南(第2版)高清中文 Spring MVCSpring框架中用于Web应用快速开发的一个模块,其中的MVC是Model-View-Controller的缩写。作为当今业界最主流的Web开发框架,Spring MVC已经成为当前最热门的开发...
  • Java EE框架整合开发入门到实战:Spring+Spring MVC+MyBatis(微课版)
  • Spring MVC jar包

    2015-04-08 16:38:59
    关于构建Sping MVC的Jar包,包括Sping2.5.6和Hibernate3.6.8
  • Spring mvc整合redis实例(redis连接池) 将所有jedis 增删改进行事务的封装、查询单独做为有返回参数的封装。简化了很多代码
  • 通俗移动的Spring MVC入门书籍。请尊重版权,禁止用于商业目的。
  • spring mvc 框架示例

    2014-08-26 23:47:09
    Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,可以选择是使用内置的 Spring Web 框架还可以是...
  • 这是spring MVC的HelloWorld完整实例,包含jar包
  • spring mvc + spring + hibernate 全注解整合开发视频教程 11
  • Spring MVC AOP通过注解方式拦截Controller等实现日志管理demo版本2
  • 本毕业设计采用Java作为开发语言,使用了著名的开源框架Spring MVC、Hibernate、Spring、easyui进行开发,而后台的数据库采用MySQL。
  • 作为当今业界主流的Web开发框架,Spring MVC(有时也叫Spring Web MVC)的开发技能相当热门。本书即针对于想要学习如何通过Spring MVC开发基于Java的Web应用的开发人员。本书延续了学习指南系列的特点,通俗易懂,...
  • Spring MVC 配置 urlrewrite 实例

    热门讨论 2015-11-02 10:44:49
    Spring MVC 配置 urlrewrite 实例
  • spring MVC框架所需的所有jar包。(完整版)

    千次下载 热门讨论 2016-07-29 11:28:45
    该压缩包中包含了配置spring MVC框架所需的所有jar包。
  • 本文是spring mvc初学的记录,包括环境的搭建,前后台数据库交互,文件上传
  • Spring MVC 配置 druid 数据源实例
  • 5 分钟彻底理解 Spring MVC

    千次阅读 多人点赞 2021-10-10 14:22:45
    Sping MVC 正式的名字为 Spring Web MVC,是 Spring Framework 框架中的其中一个模块,基于 Servlet API 构建,同时使用 MVC 的架构模式,主要用以简化传统的 Servlet + JSP 进行 web 开发的工作。

    概述

    Sping MVC 正式的名字为 Spring Web MVC,是 Spring Framework 框架中的其中一个模块,基于 Servlet API 构建,同时使用 MVC 的架构模式,主要用以简化传统的 Servlet + JSP 进行 web 开发的工作。

    MVC 架构模式

    Spring MVC 基于 MVC 模式,因此理解 Spring MVC 需要先对 MVC 模式有所了解。

    传统 MVC 架构模式

    MVC 即 Model-View-Controller 是软件开发中一种常用的架构模式,将软件系统分为三层:模型(Model)、视图(View)、控制器(Controller),各部分根据职责进行分离,使程序的结构更为直观,增加了程序的可扩展性、可维护性、可复用性。可以用如下的图形来表示三者之间的关系。MVC 架构模式

    • 模型(Model):模型封装了数据及对数据的操作,可以直接对数据库进行访问,不依赖视图和控制器,也就是说模型并不关注数据如何展示,只负责提供数据。GUI 程序模型中数据的变化一般会通过观察者模式通知视图,而在 web 中则不会这样。
    • 视图(View):视图从模型中拉取数据,只负责展示,没有具体的程序逻辑。
    • 控制器(Controller):控制器用于控制程序的流程,将模型中的数据展示到视图中。

    Java Web MVC 架构模式

    上世纪 90 年代,随着互联网的发展,基于浏览器的 B/S 模式随之流行,最初浏览器向服务器请求的都是一些静态的资源,如 HTML,CSS 等,为了支持根据用户的请求动态的获取资源,Java 提出了 Servlet 规范。

    此时 Servlet 可以说是一个大杂烩,浏览器接收的 HTML 都是通过 Servelt 一行一行的输出,比较繁琐,并且写后端代码的程序员还要熟悉前端技术,为了解决这个问题,sun 公司又借鉴 ASP 提出了 JSP。

    JSP 和 HTML 相似,只是在 JSP 文件中可以嵌入 Java 代码,减少了直接使用 Servlet 产生的大量冗余代码。此时 JSP 同时充当模型、视图、控制器的角色,为了解决前后端代码仍然揉在一起的问题,Java Web MVC 模式后来被提出,JavaBean 充当模型、JSP 充当视图,Servlet 充当控制器,流程如下图所示。

    Java Web MVC
    浏览器的请求先经过 Servlet,Servlet 控制整个流程,使用 JavaBean 查询并存储数据,然后携带 JavaBean 中的数据到 JSP 页面中,这个就是 Java 中早期的 Web MVC 架构模式了。

    Spring MVC 架构模式

    Spring MVC 架构模式对 Java Web 中的 MVC 架构模式加以扩展,将控制器拆分为前端控制器 DispatcherServlet 和后端控制器 Controller,将 Model 拆分成业务层(Service) 和数据访问层(Respository),并且支持不同的视图,如 JSP、FreeMarker 等,设计更为灵活,请求处理流程如下。
    Spring Web MVC浏览器的请求先经过 DispatcherServlet,DispatcherServlet 负责分发请求,因此 DispatcherServlet 又被称为前端控制器。DispatcherServlet 其后的 Controller 又被称为后端控制器,Controller 可以选择性的调用 Service、Repository 实现业务逻辑,DispatcherServlet 拿到 Controller 提供的模型和视图后,进行渲染并返回给浏览器。当然了,这里只是为了方便理解 Spring MVC 描述的大概流程,具体流程会在后文介绍。

    Hello,Spring MVC

    虽然现在 SpringBoot 已经成为主流,但是我仍然想从单纯的 Spring MVC 讲起,因为 SpringBoot 也只是在 Spring Framework 其上添加了一些自动化的配置,这些自动化的配置会让我们忽略背后的技术原理。

    几年的 Spring 的教程中都会提出使用 Spring MVC 首先需要去 Spring 官网下载一大堆的依赖,而现在有了 maven 之后再也不必关系这些乱七八糟的依赖及其依赖关系。如果你不了解 maven,建议先去了解 maven 后再回头看下面的内容。

    Spring MVC 依赖引入

    新建 maven 项目,并引入 Spring MVC 的依赖,注意这里引入的版本号是 5.2.6,Spring Framework 5 开始对 JDK 版本的要求是 1.8 及以上。完整的 pom 内容如下。

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.zzuhkp</groupId>
        <artifactId>mvc-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <dependencies>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>4.0.1</version>
                <scope>provided</scope>
            </dependency>
    
        </dependencies>
    
        <build>
            <finalName>mvc-demo</finalName>
        </build>
    </project>
    

    DispatcherServlet 声明

    传统的 Java Web 项目使用 Servlet 处理请求,Spring MVC 遵循了 Servlet 规范,提供了一个名称为 DispatcherServlet 的 Servlet 类,使用 Spring MVC 需要先声明这个 Servlet。

    DispatcherServlet 整合了 IOC 容器,所有处理 Web 请求的组件都存至 IOC 容器中,然后使用这些 bean 处理控制整个请求过程。

    有两种声明 DispatcherServlet 的方式,第一种方式是直接在类路径下的/WEB-INF/web.xml文件中配置。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
              http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">
    
        <servlet>
            <servlet-name>dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>dispatcher</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    第二种方式基于 Servlet 3.0 提出的 ServletContainerInitializer 接口,Servlet 容器会从类路径中查找实现了这个接口的类,并在启动时回调这个接口中的方法,Spring MVC 已经将这个接口实现为 SpringServletContainerInitializer,在其内部调用了 WebApplicationInitializer 接口完成初始化,因此实现 WebApplicationInitializer 接口再添加 DispatcherServlet 也可以,和上述 xml 等效的 java 代码如下。

    public class MvcXmlInitializer implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
            XmlWebApplicationContext context = new XmlWebApplicationContext();
            DispatcherServlet dispatcher = new DispatcherServlet(context);
            Dynamic dynamic = servletContext.addServlet("dispatcher", dispatcher);
            dynamic.addMapping("/");
            dynamic.setLoadOnStartup(1);
        }
    }
    

    除了上述用户自定义的 WebApplicationInitializer,Spring 还自定义了一个支持注解配置的抽象实现类 AbstractAnnotationConfigDispatcherServletInitializer,这个类会自动向 Servlet 上下文中注册 DispatcherServlet,实现这个类然后指定配置类即可。

    public class MvcAnnotationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return null;
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{MvcConfig.class};
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }
    

    这里我们使用 web.xml 配置进行演示,我们配置的 DispatcherServlet 声明的映射路径是/,因此,所有的请求都会到达 DispatcherServlet,然后再分派给不同的处理器处理。

    Spring 上下文配置

    Spring MVC 使用 IOC 容器存储处理请求的组件,包括处理器在内的所有自定义的与 Web 请求有关的组件都需要添加到 Spring 的配置中。

    Spring 上下文配置文件指定

    DispatcherServlet 初始化时默认使用的容器是 XmlWebApplicationContext,虽然 Spring 预留了扩展点用于修改容器类型,非必要情况下还是建议不要修改,这个容器默认情况下会使用类路径下/WEB-INF/{servlet-name}-servlet.xml文件作为容器的配置文件,我们声明的 DispatcherServlet 名为 dispatcher,因此我们创建/WEB-INF/dispatcher-servlet.xml文件作为容器的配置。另外还可以使用 Servlet 的初始化参数 configLocation 指定 Spring 容器配置文件路径。

        <servlet>
            <servlet-name>dispatcher</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
    

    Spring 上下文配置文件内容

    Spring 配置文件内容如下。

    <?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.xsd">
    
        <bean id="/hellohandler" class="com.zzuhkp.mvc.handler.HelloSpringMVCHttpRequestHandler"/>
            
    </beans>
    

    这里声明了一个类型为 HelloSpringMVCHttpRequestHandler 的 bean,其 id 为请求路径/hellohandler,这个类的定义如下。

    public class HelloSpringMVCHttpRequestHandler implements HttpRequestHandler {
    
    
        @Override
        public void handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            response.getWriter().write("Hello,HelloSpringMVCHttpRequestHandler");
        }
    
    }
    

    这样配置的目的是希望当/hellohandler请求到达时,能够使用我们提供的 HelloSpringMVCHttpRequestHandler 处理请求。

    到了这里,将项目发布到 Tomcat,我这里使用的 Tomcat 版本号是 9.0.54,可以看到效果如下。
    HelloSpringMVCRequestHandler

    HandlerMapping 配置

    那为什么将处理器的 bean id 配置为请求路径就可以使用这个处理器进行处理呢?Spring MVC 为了灵活的查找处理器内部使用了 HandlerMapping 将请求映射到处理器,Spring 默认情况下会使用BeanNameUrlHandlerMapping映射请求,这个映射器将请求路径作为 id 查找处理器。除了默认情况下使用的这个映射器,我们还可以配置 SimpleUrlHandlerMapping 映射器,和上述等效的 Spring 配置如下。

    <?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.xsd">
    
        <bean id="hellohandler" class="com.zzuhkp.mvc.handler.HelloSpringMVCHttpRequestHandler"/>
    
        <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="urlMap">
                <map>
                    <entry key="/hellohandler" value-ref="hellohandler"/>
                </map>
            </property>
        </bean>
        
    </beans>
    

    处理器配置

    看到这里,细心的小伙伴可能会有疑问,说好的 DispatcherServlet 将请求分派给 Controller 呢?这里暂时不用着急,Controller 其实是 Spring MVC 的处理器类型之一,这里的 HttpRequestHandler 同样是 Spring MVC 的处理器。

    Spring 对多种处理器进行了支持,具体则是使用 HandlerAdapter 对处理器进行适配,Spring MVC 内部已经默认了一些适配器,HttpRequestHandler 的适配器是 HttpRequestHandlerAdapter,Controller 的适配器 SimpleControllerHandlerAdapter 也是 Spring MVC 默认支持的。

    默认的 HandlerAdapter 已经足够支持日常所需,一般不会自定义 HandlerAdapter。

    下面尝试使用 Controller 作为处理器处理请求,定义实现 Controller 接口的 HelloSpringMVCController 类如下。

    public class HelloSpringMVCController implements Controller {
    
        @Override
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("/WEB-INF/view/welcome.jsp");
            modelAndView.addObject("hello", "HelloSpringMVCController");
            return modelAndView;
        }
    }
    

    然后在 Spring 配置文件中添加这个类作为 bean。

    <bean id="/hellocontroller" class="com.zzuhkp.mvc.handler.HelloSpringMVCController"/>
    

    到了这里,终于可以看到 Controller 了,Controller 处理请求,返回了一个类型为 ModelAndView 的对象。

    ModelAndView 包含模型和视图,这里向模型中添加了属性 hello,并且指定了/WEB-INF/view/welcome.jsp 文件作为视图名,这个文件内容如下。

    <html>
    <body>
    <h2>Hello,${requestScope.hello}</h2>
    </body>
    </html>
    

    启动 Tomcat 访问 /hellocontroller 效果如下。
    HelloSpringMVCController成功将模型中的数据展示到视图。

    ViewResolver 配置

    为了支持不同的视图,如 JSP、FreeMarker 等,ModelAndView 中的视图名称被设计成虚拟的,具体的视图由视图解析器 ViewResolver 进行解析,默认情况下使用的视图解析器是 InternalResourceViewResolver ,这个视图解析器基于 URL 解析视图。同时也可以向应用上下文中配置自己的视图解析器。添加自定义的 InternalResourceViewResolver 到 Spring 配置文件。

        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/view"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    

    然后设置视图名时就可以忽略路径前缀/WEB-INF/view和后缀.jsp,配置前缀后缀后上述示例中 HelloSpringMVCController 就可以将视图名从 /WEB-INF/view/welcome.jsp 简化为 welcome

    DispatcherServlet 组件默认配置

    上述示例中使用了不少 DispatcherServlet 使用的组件,Spring MVC 默认情况下已经提供了一些,如果需要自定义,则将自定义的组件添加到上下文配置中接口,十分方便,那么 Spring 默认情况下使用了哪些组件处理请求呢?

    spring-webmvc 模块类路径下 org/springframework/web/servlet/DispatcherServlet.properties 文件定义了这些默认的配置,具体如下。
    在这里插入图片描述

    基于注解的 Spring WebMVC

    基于配置文件的 Spring Web MVC 项目在前些年确实比较流行,然而现在注解已经成为 Spring 开发的主流。下面通过纯注解的方式对上面的示例进行改造。

    pom 文件不需要进行变化,首先要提供 Spring 配置类。

    @ComponentScan("com.zzuhkp.mvc")
    public class MvcConfig {
    
    }
    

    这里只添加了组件扫描能力,Spring 会将给定包下标注了 @Component 的类作为 bean 进行处理。然后将将这个类设置为配置类即可,这里可以参见使用上述提供的 DispatcherServlet 第二种声明方式

    然后提供基于注解的控制器。

    @Controller
    public class HelloSpringMVCAnnotationController {
    
        @GetMapping("/helloAnnotationController")
        public String helloMVC(@RequestParam("hello") String hello, Model model) {
            model.addAttribute("hello", hello);
            return "/WEB-INF/view/welcome.jsp";
        }
    
    }
    

    基于注解的控制器不需要实现特定的接口,直接在类上添加 @Controller 注解即可,这里定义了一个处理 /helloAnnotationController 路径 GET 请求方式的方法,并且接收 hello 参数,存放至 model 中,然后返回了视图名。这里直接复用了上面示例中的视图。最终效果如下。
    在这里插入图片描述基于注解的控制器是 Spring MVC 中设计最为灵活的地方,这里可以先考虑下,Spring 是怎么适配用户自定义的控制器的?控制器方法中的参数如何赋值呢?如何将控制器方法的返回值解析为视图?Spring 如何支持 RESTFUL 风格的接口的?后面会写几篇文章继续分析。

    DispatcherServlet 请求处理流程

    DispatcherServlet 请求处理流程已经穿插在前面的示例中介绍,直接看前面的描述可能不是很直观,这里总结了一张图来梳理整个流程。
    DispatcherServlet 执行流程整个流程串联起来如下。

    1. DispatcherServlet 处理浏览器发起的请求。
    2. DispatcherServlet 根据用户或默认的配置使用 HandlerMapping 查找可处理请求的处理器。
    3. DispatcherServlet 拿到 HandlerMapping 返回的处理器链 HandlerExecutionChain。整个处理器链包含拦截器和处理。
    4. DispatcherServlet 将处理器适配为 HandlerAdapter。
    5. DispatcherServlet 使用拦截器进行请求前置处理。
    6. DispatcherServlet 使用处理器进行请求处理。
    7. DispatcherServlet 使用拦截器进行请求后置处理。
    8. DispatcherServlet 从拦截器或处理器中提取到模型及视图 ModelAndView。
    9. DispatcherServlet 使用视图解析器 ViewResolver 解析视图出视图 View。
    10. DispatcherServlet 渲染视图,响应请求。

    结束语

    本文先介绍 MVC 架构模式,然后通过示例的方式对 Spring MVC 的使用方式及执行流程进行介绍,最后还使用一个流程图总结。

    Spring MVC 中所有的扩展都基于 DispatcherServlet 处理请求的这个流程,可以说理解了这个流程图就理解了 Spring MVC 的原理,后面将会对这个流程进行细化,继续介绍 Spring MVC 的其他内容。感兴趣的小伙伴不妨点个关注。

    展开全文
  • 由浅入深-Spring MVC

    2020-12-21 06:05:20
    本文致力于由浅入深的去介绍,使用Spring MVC;细节比较多,希望能对正在观看的你有所帮助! 博主水平有限,难免存在缺陷和错误,欢迎大佬的指出与补充,谢谢! 0x01.认识Spring MVC 1.Spring MVC概述 Spring MVC...
  • 弹簧 mvc 演示 Spring MVC Demo 集成了 Spring Framework、Spring MVC 和 iBATIS。
  • Spring MVC: A Tutorial (Second Edition) by Paul Deck AZW3/MOBI/EPUB/PDF 多种版本 This is a tutorial on Spring MVC, a module in the Spring Framework for rapidly developing web applications. The MVC in...
  • 使用maven与MyEclipse整合ssm(Spring MVCSpring、Mabatis)三大框架并实现用户注册实例源码下载,里面包含一个src目录、pom.xml文件,以及readme.txt。请先阅读readme.txt里面的内容.
  • 精通Spring MVC 4 文字版 pdf 清晰 完整精通Spring MVC 4 文字版 pdf 清晰 完整精通Spring MVC 4 文字版 pdf 清晰 完整精通Spring MVC 4 文字版 pdf 清晰 完整

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 438,480
精华内容 175,392
关键字:

Spring mvc

友情链接: xiaoche.rar