![SpringMVCOutline](/2021/05/26/SpringMVC/SpringMVCOutline.png)
很多应用程序在处理业务数据和显示业务业务数据的视图之间存在紧耦合。为了对业务数据处理和视图进行解耦,WebMVC应运而生。SpringMVC则是基于java的一种WebMVC的实现。SpringMVC实现了M与V的解耦。
1、SpringMVC
1.1、SpringMVC简介
Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从一开始就已包含在 Spring Framework 中。正式名称“ Spring Web MVC”来自其源模块的名称(spring-webmvc),但更通常称为“ Spring MVC”。
作用:分离了控制器、模型对象。
版本支持:Netty,Undertow和Servlet 3.1+容器等服务器。
1.2、什么是MVC
![MVC](/2021/05/26/SpringMVC/MVC.png)
经典MVC三层模式——Model模块层,View视图层,Controller控制层。实现M与V的隔离,分工明确。
M:数据模型,提供要展示的数据。
V:负责进行模型的展示。例:html页面
C:接受用户的请求,委托给模型进行处理。
maven导入Servlet、jstl、Spring、Junit:
1 | <dependencies> |
1.3、SpringMVC优点
- 可以支持各种视图技术,不仅仅局限于JSP
- 与Spring框架集成(如IoC容器、AOP等)
- 清晰的角色分配
- 支持各种请求资源的映射策略
2、DispatcherServlet
DispatcherServlet(servlet调度员),表示前置控制器、前端控制器。是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求。
![DispatcherServlet](/2021/05/26/SpringMVC/DispatcherServlet.png)
DispatcherServlet是一个HttpServlet,接收客户的请求进行转发,在Javaweb时,需要写非常多的servlet进行处理,在SpringMVC中DispatcherServlet就可以进行分发。
![JSPAndSpringMVC](/2021/05/26/SpringMVC/JSPAndSpringMVC.png)
3、HelloController
1、注解创建
1.创建web框架
web
WEB-INF
- web.xml
index.html
2.修改web.xml文件
1 |
|
在web.xml文件注册DispatcherServlet类,该类可读取xml文件以获取Controller类或@Controller注解的类。
3.创建springmvc-servlet.xml
1 |
|
经典的spring的xml注入方式,需要对处理器、适配器、映射器、视图解析器进行创建。DispatcherServlet会将它们进行自动装配。
4.创建Controller
1 |
|
@RequestMapping(“/hello”)用于路径解析,在@RequestMapping有详细介绍
2、类创建
1、创建web框架
- web
- WEB-INF
- web.xml
- index.html
- WEB-INF
2、修改web.xml文件
3、创建springmvc-servlet.xml
1 |
|
4、创建Controller类
1 | public class HelloController implements Controller { |
实现Controller接口的handleRequest()方法,该方法返回ModelAndView用于视图解析。
4、SpringMVC原理
![SpringMVC](/2021/05/26/SpringMVC/SpringMVC.png)
步骤:
- 用户发送请求到DispatcherServlet(前端控制器)
- DispatcherServlet接收到后,请求处理器映射器(HandlerMapping)查找(通过xml或注解)
- 处理映射器返回执行链(HandlerExecutionChain)
- DispatcherServlet调用处理适配器(HandlerAdapter)去执行处理器(Handler)
- HandlerAdapter执行Handler
- Handler执行完成,HandlerAdapter返回ModelAndView
- DispatcherServlet请求视图解析器(ViewResolver)进行视图解析
- ViewResolver向DispatcherServlet返回视图
- DispatcherServlet对视图进行渲染
- 将视图返回给用户
5、Controller
什么是Controller?
- 控制器负责提供访问应用程序的行为,通常通过接口定义或注解定义俩种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型
- 在SpringMVC中,一个控制器可以包含多个方法
- 在SpringMVC中,对于Controller的配置方法有很多种
1、Controller接口
1 |
|
可以看到这是个函数式接口(只有一个抽象方法),可以用lambda表达式。
2、Controller注解
1 |
|
可以了解到,@Controller注解在类上使用。Spring扫描包时,发现@Controller类将其加载到bean工厂。
还有一个变形的Controller:
1 |
|
@RestController在Spring4.01时添加的注解,表示子方法不走视图解析器,会直接返回一个字符串(多用于前后端分离)。
6、@RequestMapping
1、@RequestMapping
源码如下:
1 |
|
@RequestMapping注解用于路径解析,属性value和属性path互为别名,使用这俩个是一致的。例:
1 |
|
@RequestMapping注解也可以用在类上,子方法都要加上这个路径前缀
1 |
|
@RequestMapping还有请求属性,该属性类型为RequestMethod。
1 | public enum RequestMethod { |
分别表示Get、post等请求,,传递该参数,对不同类型请求进行不同处理。
@RequestMapping和其变种都具有produces,其用于表示传输类型(html、json等)。
2、其他Mapping
这些根据不同的请求进行处理的Mapping:
1 | //get请求 |
3、总结
@RequestMapping注解可以在类上或方法上进行不同请求的路径映射,它也派生出许多的Mapping用于处理各种请求。
7、RestFul风格
1、URI与URL
统一资源标志符URI就是在某一规则下能把一个资源独一无二地标识出来。
URL是URI的子集,通过定位的方式实现URI。
2、什么是RestFul风格
RestFul是一种架构风格,提供了一组设计原则和规范。
Rest(Representational State Transfer,简称REST),2000年,HTTP规范编写者之一首次提出。
普通的URL
1 | http://www.jiuzhao73.com?a=1&b=2 |
RestFul风格的URL(a、b为传递的参数值)
1 | http://www.jiuzhao73.com/a/b |
3、RestFul风格优点
- 轻量级
- 面向资源
- 数据描述简单
- 无状态
- 简单、低耦合
4、在SpringMVC中的实现
1 |
|
如“@RequestMapping(“/h1/{a}/{b}”)”所示,可以使用”{变量名}”进行RestFul风格设计。在方法中,方法可以使用与变量名相同的变量名作为参数,进行变量的获取。对于限定了类型的a、b变量当URL传递类型错误的参数时会报http400错误。
![RestFul400ERROR](/2021/05/26/SpringMVC/RestFul400ERROR.png)
8、重定向与转发
在现实开发中,我们经常需要对请求进行转发或重定向。
1、重定向与转发区别
引用一下以前学JavaWeb时的图片:
转发:
![redirected](/2021/05/26/SpringMVC/redirected.png)
重定向:
![redire](/2021/05/26/SpringMVC/redire.png)
A表示用户,B表示A访问的资源,C表示转发或重定向后获取的资源。
转发和重定向可能是因为资源的迁移,对原有访问并没有禁止。转发,直接帮用户访问资源,再返回给用户。重定向,直接告诉用户现在的资源地址,让用户对其访问。
总结:转发不改变URL,重定向改变URL。
2、SpringMVC中的实现
在SpringMVC中,转发与重定向有很好的实现。
转发:
1 | public class ForwardController { |
重定向:
1 |
|
转发(forward)是SpringMVC的默认实现可写可不写。重定向(redirect)必须写。
在没有视图解析器时,返回”域名/路径”。
转发:”forward:路径”
重定向:”redirect:路径”
9、数据处理
9.1、接收前端传递的参数
9.1.1、@PathVariable与@RequestParam
@PathVariable用于RestFul风格的URL,是用来获得请求url中的动态参数的。
@PathVariable:
1 | public PathVariable { |
@PathVariable的参数:
- name、value:参数名称,即入参的请求参数名称,如name表示请求的参数区中的名字为name的参数的值将传入;
- required:是否必须,默认为true。
除了@PathVariable获取动态参数,还有俩种获取参数的方式:
- 一种是request.getParameter(“name”),
- 另外一种是用注解@RequestParam直接获取。
@RequestParam声明这是个参数,它的参数:
- value、name:参数名字,即入参的请求参数名字;
- required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报404错误码;
- defaultValue:默认值,表示如果请求中没有同名参数时的默认值。
@RequestParam:
1 |
|
注:在不使用@PathVariable与@RequestParam注释时,SpringMVC也会对参数进行自动识别。
下面的例子绝大部分使用RestFul风格,因此使用@PathVariable注解;当不使用RestFul风格时,可以使用@RequestParam。
9.1.2、请求参数与处理方法的参数名一致
1 |
|
在传参时可以使用注解,也可以不使用注解(RestFul风格参数除外),SpringMVC会自动映射。但是仍建议使用,这样对代码的维护(使用该注解开发人员知道这是个请求参数)和传参的严格性(使用注解,会使没有传参的请求报404错误)有更好的作用。
9.1.3、请求参数与处理方法的参数名不一致
1 |
|
不一致时,使用name或value属性的值进行映射。
9.1.4、提交的是一个对象
1 |
|
SpringMVC会对bean对象进行识别进行自动装配,本例中User类拥有俩个属性与set方法,分别是name与age。
9.2、向前端传参数
像前端传递参数方式有:
- ModelAndView
- ModelMap
- Model
- HttpResponse(与之前相同,就不再介绍了)
9.2.1、ModelAndView
1 |
|
ModelAndView使用addObject()设置需要返回的值,addObject()有几个不同参数的方法,可以默认和指定返回对象的名字。
9.2.2、ModelMap
1 |
|
继承自LinkedHashMap<String, Object>,是个散列表,因此对键值对的处理较为高效。
9.2.3、Model
1 |
|
使用addAttribute()设置返回值。方法单一,职责简单。
10、乱码问题
1、自定义Filter
1 |
|
过滤类实现接口Filter的三个方法。在web.xml中注册,在web容器开启时,对过滤器进行装载。
实现之后需在web.xml中注册,以便过滤器装载。
1 | <filter> |
2、SpringMVC中的CharFilter
对于乱码问题,SpringMVC很贴心的为我们实现了一个类CharacterEncodingFilter,该类对于解码和编码很是强大,对于目前的学习也是够用了。
使用:
1 | <filter> |
我们只需在web.xml中将过滤器注册即可。
11、Json
1、什么是Json
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。——百度百科
- Json是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度。
- Json就是一串使用特定规则符号的字符串。
- Json具有自我描述性,更易理解。
Json语法
- 数据在名称/值对中
- 数据由逗号分隔
- 大括号 {} 保存对象
- 中括号 [] 保存数组,数组可以包含多个对象
例:
1 | { "name":"久曌" , "url":"www.jiuzhao73.com" } |
2、@RestController与@ResponseBody
我们先来看看它们的源码:
@RestController
1 |
|
@ResponseBody
1 |
|
一般情况下@RestController标注类、@ResponseBody标注方法。看源码易得@RestController是一个@Controller,当一个类被其标注时,这个类的URL映射方法(@RequestMapping等注解)都会直接返回字符串,而不是进行页面跳转。而@ResponseBody标注一个方法直接返回字符串,与URL映射方法搭配使用。
3、jackson
Java生态圈中有很多处理JSON类库,Jackson是其中比较著名的一个。
1 | <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> |
3.1、ObjectMapper
对于一个javabean,我们需要ObjectMapper对其进行序列化与反序列化。
![jacksonResult](/2021/05/26/SpringMVC/jacksonResult.png)
3.2、乱码问题
3.2.1、手动配置
@RequestMapping和其变种都具有produces,其用于表示传输类型(html、json等)。将其设置为:
1 |
3.2.2、自动配置
1 | <mvc:annotation-driven> |
4、fastJson
fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。
github:https://github.com/alibaba/fastjson
maven依赖:
1 | <dependency> |
参考文献
尽管这不是一个详尽的清单,但还是希望对大家有所启示。
[1]Rod Johnson, Juergen Hoeller, Keith Donald, Colin Sampaleanu, Rob Harrop, Thomas Risberg, Alef Arendsen, Darren Davison, Dmitriy Kopylenko, Mark Pollack, Thierry Templier, Erwin Vervaet, Portia Tung, Ben Hale, Adrian Colyer, John Lewis, Costin Leau, Mark Fisher, Sam Brannen, Ramnivas Laddad, Arjen Poutsma, Chris Beams, Tareq Abedrabbo, Andy Clement, Dave Syer, Oliver Gierke, Rossen Stoyanchev, Phillip Webb, Rob Winch, Brian Clozel, Stephane Nicoll, Sebastien Deleuze, Jay Bryant, Mark Paluch.Web on Servlet Stack[EB/OL]:[2021-04-15]
[2]菜鸟教程.FastJson简明教程[EB/OL]:[未知]