前言
在之前的章节,我们已经用到了 Controller 的部分功能——外界通过 HTTP 请求,访问 SpringBoot 中的方法。这就是我们熟知的 Web 接口,是客户端与后端应用交互的重要方式之一。
那么在本章,我们就来整理下如何使用 @Controller 实现 RESTful Web 接口。
@Controller 的使用
基本介绍
@Controller
注解用于标识一个类,被标识的类就是个 SpringMVC Controller 对象,即一个控制器。SpringBoot 在启动时,会自动扫描被 @Controller
标记的类,并扫描该类中的方法。使用 @RequestMapping
标记的方法即为一个处理器,不同的请求会由分发器分发到对应的方法上。
创建 Controller 类
新建一个 controller
包,在包内创建一个 MyController1.java
类
@Controller
public class MyController1 {
@ResponseBody
@RequestMapping(value = "/test")
private String test() {
return "Hello world!";
}
}
- @Controller: 标记为一个控制器类。
- @ResponseBody: 标志返回值是实体内容,而不是返回一个界面。因为我们要做的是 RESTful 接口,所以这里需要的是直接返回参数内容。如果不标记
@ResponseBody
的话,将返回名为"Hello world!"的界面文件。 - @RequestMapping: 标记方法为控制器。后面会详细介绍该注解的用法。
启动项目,在浏览器中或 Web 调试工具(例如 PostMan)访问 http://127.0.0.1:8080/test,将得到"Hello world!"字符串。
用 @RestController 代替 @Controller 与 @ResponseBody
@RestController
的功能 = @Controller
+ @ResponseBody
。
在类上标注 @RestController
,就不需要在该类的每个方法上标注 @ResponseBody
了。
@RequestMapping 的使用
基本介绍
@RequestMapping
可以标识在类或者方法上,用于指明 Spring 用哪个类或者哪个方法来处理对应的请求。
当 @RequestMapping
标记在类上时,表示该类下的所有方法都被映射到其 value 属性所指示的路径下。
创建 MyController2.java
@RestController
@RequestMapping(value = "/controller2")
public class MyController2 {
@RequestMapping(value = "/test1")
private String test1() {
return "This is test1.";
}
@RequestMapping(value = "/test2")
private String test2() {
return "This is test2.";
}
}
这上面这两个方法的 URL 分别为:
@RequestMapping 相关属性
在 @RequestMapping
中,可以配置如下的属性:
- value: 用于将请求映射到指定的方法上。
- method: 规定请求的类型。支持的请求类型包括:
GET
、POST
、PUT
、DELETE
、OPTIONS
、PATCH
、HEAD
、TRACE
。如果不填,则默认支持所有请求类型。 - consumes: 规定请求的入参类型,即
Content-Type
。例如:text/xml
、application/json
、multipart/form-data
等。 - produces: 规定请求的出参类型,如果请求的
header
中设置了Accept
类型,则需要在 produces 中配置同样的类型才能返回出参。 - params: 规定请求中必须包含指定参数值时,方法才会处理该请求。
- headers: 规定请求头必须包含指定
header
值时,方法才会处理该请求。 - names: 给映射地址起个别名。
例如:
@RestController
@RequestMapping(value = "/controller3")
public class MyController3 {
@RequestMapping(value = "/test1", method = {RequestMethod.POST})
private String test1() {
return "This is test1.";
}
@RequestMapping(value = "/test2", consumes = "application/json")
private String test2() {
return "This is test2.";
}
@RequestMapping(value = "/test3", params = "id=1")
private String test3() {
return "This is test3.";
}
}
- http://127.0.0.1:8080/controller3/test1: 该请求的类型必须为 POST。
- http://127.0.0.1:8080/controller3/test2: 该请求
header
中必须指定Content-type = application/json
。 - http://127.0.0.1:8080/controller3/test3?id=1: 该请求,必须要传入
id = 1
参数,方法才会被执行。
如何获取入参
通常,我们需要在访问接口的同时向后台传入数据。关于入参的获取,有以下四种常见方式。
通过 HttpServletRequest 获取参数
HttpServletRequest
对象,包含了客户端一次 HTTP 请求中的请求消息头、请求消息体和请求消息行的所有内容。通过 API 可以获取请求中的信息。对于入参,我们可以使用 getParameter(String key)
方法获得参数值。
在 MyController4.java
中添加如下方法:
@RequestMapping(value = "/test1")
private String test1(HttpServletRequest httpServletRequest) {
int id = Integer.parseInt(httpServletRequest.getParameter("id"));
String name = httpServletRequest.getParameter("name");
return String.format("id:%d, name:%s", id, name);
}
访问 http://127.0.0.1:8080/controller4/test1?id=1&name=InterHorse,返回“id:1, name:InterHorse”。
通过 @RequestParam 获取参数
@RequestMapping(value = "/test2")
private String test2(@RequestParam("id") int id,
@RequestParam("name") String name) {
return String.format("id:%d, name:%s", id, name);
}
访问 http://127.0.0.1:8080/controller4/test2?id=1&name=InterHorse,返回“id:1, name:InterHorse”。
其中,@RequestParam
也有属性可以进行配置:
- name: 指定属性绑定的名称。
- value: name 的别名。所以 name 和 value 是等价的。
- required: 参数是否必须传。默认为 true。
- defaultValue: 如果某个属性的 required 设置为 false,则可以通过该属性配置某个参数的默认值。
例如
@RequestMapping(value = "/test5")
private String test5(@RequestParam(value = "id", required = false, defaultValue = "10") int id,
@RequestParam(value = "name", required = false, defaultValue = "Bill") String name) {
return String.format("id:%d, name:%s", id, name);
}
如果入参为空,则默认返回“id:10, name:Bill”。
通过 @PathVariable 获得入参
使用 @PathVariable
,可以直接将 URL 中的参数动态绑定到入参中。
@RequestMapping(value = "/test3/{id}/{name}")
private String test3(@PathVariable("id") int id,
@PathVariable("name") String name) {
return String.format("id:%d, name:%s", id, name);
}
请求 http://127.0.0.1:8080/controller4/test3/1/InterHorse,返回值为“id:1, name:InterHorse”。
通过实体获得入参
创建一个实体 InputAO.java
,包含 id 和 name 两个属性。SpringBoot 会自动根据入参的属性名称与实体中同名属性进行映射,将参数 set 到实体中。
public class InputAO {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@RequestMapping(value = "/test4")
private String test4(InputAO inputAO) {
int id = inputAO.getId();
String name = inputAO.getName();
return String.format("id:%d, name:%s", id, name);
}
请求 http://127.0.0.1:8080/controller4/test4?id=1&name=InterHorse,返回值为“id:1, name:InterHorse”。
如何返回参数
返回一个对象
在之前所有的演示中,我们已经在返回 String
类型的数据了,其他几种基本类型例如 int
、long
、boolean
也是一样,只需要修改方法的返回类型就可以返回不同类型的数据了。那么如何返回对象类型呢?非常简单,只需要将返回类型修改为需要返回的对象类型,那么 SpringBoot 就自动将实体序列化成 JSON
格式进行返回了。
创建实体 ResponseBO.java
public class ResponseBO {
private String code;
private String message;
private Object data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
在 MyController5.java
中添加如下方法
@RequestMapping(value = "/test1")
private ResponseBO test1(@RequestParam("id") int id,
@RequestParam("name") String name) {
ResponseBO res = new ResponseBO();
res.setCode("200");
res.setMessage("调用成功");
Map<String, Object> map = new HashMap<>(2);
map.put("id", id);
map.put("name", name);
res.setData(map);
return res;
}
访问 http://127.0.0.1:8080/controller5/test1?id=1&name=InterHorse ,返回
{
"code": "200",
"message": "调用成功",
"data": {
"name": "InterHorse",
"id": 1
}
}
设置 HTTP 参数
有时候,我们除了要返回数据内容之外,可能还要根据需要,设置 HTTP 的相关属性。例如,默认的 HTTP code 为 200,如果想修改成别的数值,需要怎么做呢?同样也非常简单。与 HttpServletRequest
类似,HttpServletResponse
对象为一次请求的响应对象,在方法的入参中添加 HttpServletResponse httpServletResponse
,通过其 API 即可对响应内容进行设置。
@RequestMapping(value = "/test2")
private ResponseBO test2(@RequestParam("id") int id,
@RequestParam("name") String name,
HttpServletResponse httpServletResponse) {
ResponseBO res = new ResponseBO();
res.setCode("200");
res.setMessage("调用成功");
Map<String, Object> map = new HashMap<>(2);
map.put("id", id);
map.put("name", name);
res.setData(map);
// 设置 HTTP code
httpServletResponse.setStatus(600);
return res;
}
访问 http://127.0.0.1:8080/controller5/test2?id=1&name=InterHorse,请求的 HTTP code 已设置为 600。
以上就是有关 SpringBoot 中 RESTful Web API 的常用实现方法。方法之多,适用为重。要根据实际的生产需要,选择适合自己的方法。
本章代码地址:GitHub
我是因特马,一个爱分享的斜杠程序员~
欢迎关注我的公众号:一只因特马
原文作者: 一只因特马
原文链接: https://www.matalking.com/a/463891276/
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-ND 许可协议。转载请注明出处!