SpringMVC笔记(4)-SpringMVC中的RESTful与Ajax
RESTful
简介
RESTful是一种网络应用程序的设计风格和开发方式。REST全称为Representational State Transfer,表现层资源状态转移。在这种风格下,一切皆资源。它将服务器看作由很多离散的资源组成,每个资源是服务器上一个可命名的抽象概念,我们可以通过一个路径访问。而我们对于资源的操作,可能有增删改查等,则对应到HTTP协议中不同的请求方式。
简单来说,我们通过路径来表示我们需要访问的资源,而通过请求方式来表示对一个资源的不同操作。前面我们也提到,REST风格中,将传统意义上的参数用路径来表示,也符合其利用路径表示资源的思想。在HTTP协议中,我们可以使用的请求方式包括:GET获取资源、POST新建资源、PUT更新资源、DELETE删除资源,结合不同路径来决定操作含义:
操作 | 传统方式 | REST风格 |
---|---|---|
查询 | /getUserById?id=1 | get: /user/1 |
保存 | /saveUser | post: /user |
删除 | /deleteUser?id=1 | delete: /user/1 |
更新 | /updateUser | put: /user |
HiddenHttpMethodFilter
浏览器仅支持发送get和post的请求,如果要想要在SpringMVC中发送put和delete方式的请求,需要利用它提供的HiddenHttpMethodFilter类。这是SpringMVC提供的一个类,可以帮助我们将POST请求转换为DELETE或者PUT请求。
要使用它,我们需要先在web.xml
中注册HiddenHttpMethodFilter
:
1 |
|
注意,一般情况下我们也配置了SpringMVC的编码过滤器
CharacterEncodingFilter
,编码过滤器应该要配置在所有过滤器的前面。
要想经过HiddenHttpMethodFilter
的请求,我们需要符合它的规则:
- 当前请求的请求方式必须为POST
- 当前请求必须传输请求参数
_method
,该参数的值为需要被转换为的请求方式,如put
、delete
等
例如我们可以在前端设置下面的表单,这样实际传输的时候,会得到一个put请求方式的请求:
1 |
|
静态资源
回顾前面的操作,我们在SpringMVC的配置文件中配置了前端处理器DispatcherServlet
,并且配置了它能够处理的请求路径为/
,希望它能够匹配所有请求路径。但是在Tomcat的web.xml
中,也配置了一个Servlet,它的url-pattern也是/
,具体代码如下:
1 |
|
可以看到,我们配置的SpringMVC前端控制器DispatcherServlet
与Tomcat中的默认配置器DefaultServlet
配置的url-pattern相同,我们工程中的配置会覆盖掉Tomcat中的配置,也就是说所有的请求都会经过DispatcherServlet
来处理。但是在Tomcat中,静态资源是通过DefaultServlet
来处理的,而我们配置的前端控制器无法处理静态资源,因此我们在使用到静态资源的时候应该做相应的配置,需要在SpringMVC的配置文件中增加如下的配置:
1 |
|
上面配置包括配置默认的Servlet,以及开启注解驱动。如果我们只配置了default-server-handler
,则所有请求都会交给DefaultServlet
来处理;而如果我们同时配置了注解驱动annotation-driven
,那么所有的请求先交给DispatcherServlet
处理,如果处理不了,例如静态资源等,则再交给DefaultServlet
处理。
AJAX
ajax是一种重要的异步请求技术,SpringMVC中也提供了处理ajax的相关方法。我们主要关注的就是SpringMVC如何获取ajax请求中的参数,以及如果向前端响应相关数据,下面我们将分别介绍。
获取json请求参数
这里首先介绍axios携带参数的方式。axios在发送请求的时候,如果需要携带参数则可以指定使用参数params
或data
,它们两者有所区别:
params
:表示以name1=value1&name2=value2
的方式发送请求参数,不管使用的方式是get还是post,请求参数会被拼接到请求地址后。此种方式的参数可以通过request.getParameter()
来获取,也可以用SpringMVC封装后形参的方式获取(见SpringMVC笔记(2)-@RequestMapping与请求参数获取 - EverNorif)data
:表示以json格式发送请求参数,请求参数会被保存到请求报文的请求体中,传输到服务器。这类参数的获取需要先获取请求体中的数据,这会是一个json字符串,处理字符串的过程可以通过jar包,也可以通过SpringMVC的封装
这里我们主要关注后者,即如果获取json格式的数据。这部分数据以json的格式被保存在请求体中,我们无法通过前面的方式获取。而SpringMVC为我提供了方式来获取请求体信息,即@RequestBody
注解。将该注解标注在字符串形参上,则该参数的内容即为请求体中的内容:
1 |
|
通过上面的方式,我们实际上已经可以获取到请求体中的json字符串,后面需要做的就是对json字符串进行解析。这一步我们可以使用现成的包来完成,例如fastJson等,但是SpringMVC也帮我们进行了一步封装,我们只需要指定承接RequestBody形参的类型不同,SpringMVC会自动帮我们进行转换,包括json转换为Map,json转换为实体类等。
要想开启对应的功能,我们需要先引入jackson的相关依赖:
1 |
|
然后在SpringMVC的配置文件中开启mvc的注解驱动:
1 |
|
之后,我们只需要指定承接对象的类型即可:
1 |
|
返回json数据
在前面的项目中,我们写的每个控制器方法返回的都是一个视图,要么是字符串表示对应的视图名称,要么是ModelAndView对象,总之最后达到的都是页面跳转的方式。而在实际的场景中,我们的控制器方法更多的是作为一个数据的提供API,需要返回数据而不是网页。
类似JavaWeb中提到的,我们可以设置返回值为void,然后利用Response
对象获取到字符输出流,然后向其中写入我们需要返回的数据,如下所示:
1 |
|
上面是通过字符输出流实现的数据返回,实际上SpringMVC也给提供了相关注解来简化操作,即@ResponseBody
。该注解用于标识控制器方法,表示将该方法的返回值作为响应报文的响应体响应到浏览器。此时的字符串返回值不再是表示视图名称,而是直接作为返回数据
1 |
|
在实际场景中,我们一般会以json格式向前端返回数据。通过上面的方式我们已经可以向前端返回数据了,所以我们只需要将需要返回的数据转化为json字符串的格式,然后向前端返回即可。转化为json字符串的工作可以通过现有的包来完成。当然,在SpringMVC中,@ResponseBody
也帮我们进行了多一步的封装。我们可以在控制器方法中指定字符串之外的类型,在返回给前端的时候,会自动转化为json的格式。
当然如果要开启这个功能,也需要导入jackson的依赖,然后开启mvc的注解驱动。
1 |
|
@RestController
:这个注解是SpringMVC提供的一个复合注解,标识在控制器的类上,相当于为类添加了@Controller
注解,同时为其中的每个方法都添加了@ResponseBody
注解