SpringBoot 开发实践(4):使用 @Controller 实现 RESTful Web 接口

前言

在之前的章节,我们已经用到了 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: 规定请求的类型。支持的请求类型包括:GETPOSTPUTDELETEOPTIONSPATCHHEADTRACE。如果不填,则默认支持所有请求类型。
  • consumes: 规定请求的入参类型,即 Content-Type。例如:text/xmlapplication/jsonmultipart/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.";
    }
}

如何获取入参

通常,我们需要在访问接口的同时向后台传入数据。关于入参的获取,有以下四种常见方式。

通过 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 类型的数据了,其他几种基本类型例如 intlongboolean 也是一样,只需要修改方法的返回类型就可以返回不同类型的数据了。那么如何返回对象类型呢?非常简单,只需要将返回类型修改为需要返回的对象类型,那么 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 许可协议。转载请注明出处!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章