前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Restful API详解

Restful API详解

作者头像
用户7386338
发布于 2020-05-29 07:32:18
发布于 2020-05-29 07:32:18
2.4K00
代码可运行
举报
文章被收录于专栏:Java患者Java患者
运行总次数:0
代码可运行

Restful API介绍

Restful API是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义,它使用URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。

Restful API特点

  • 用URL描述资源。
  • 使用HTTP方法描述行为,使用HTTP状态码表示不同的结果。
  • 使用json交互数据。
  • Restful只是一种风格,并不是强制的标准。

Restful API的成熟模型

Level 0:使用HTTP作为传输方式。

Level 1:引入资源概念,每一个资源都有对应的URL。

Level 2:使用HTTP方法进行不同的操作,使用HTTP状态码来表示不同的结果。

Level 3:使用超媒体,在资源的表达中包含了链接信息。需要注意的是,在我们实际的工作中,并没有达到这个级别。

与传统请求方式对比

Restful API常用映射注解

  • @Controller:在一个类上添加@Controller注解,表明了这个类是一个控制器类。
  • @ResponseBody:表示方法的返回值直接以指定的格式写入Http response body中,而不是解析为跳转路径。
  • @RestController:相当于@Controller+@ResponseBody注解。
  • @RequestMapping:这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。
  • @GetMapping:这个注解是@RequestMapping的变体,可以接收GET的请求方式,在RestFul在处理获取资源的请求。
  • @PostMapping:这个注解是@RequestMapping的变体,可以接收Post的请求方式,在RestFul在处理创建资源的请求。
  • @PutMapping:这个注解是@RequestMapping的变体,可以接收Put的请求方式,在RestFul在处理修改资源的请求。
  • @DeleteMapping:这个注解是@RequestMapping的变体,可以接收Delete的请求方式,在RestFul在处理删除资源的请求。
  • @RequestParam:将请求参数绑定到你控制器的方法参数上。
  • @PathVariable:接收请求路径中占位符的值。
  • @RequestBody:用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)。

Restful API的测试用例

在我们实际开发中,需要对我们的接口进行测试,确保我们后端接口的可用,这时我们在不启动整个项目的情况下,可以利用到spring的测试框架辅助我们的开发。

在security-demo工程pom文件导入一下的依赖:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- 引入spring 的测试框架 -->
<dependency>
    <artifactId>spring-boot-starter-test</artifactId>
    <groupId>org.springframework.boot</groupId>
</dependency>

然后就可以在我们项目工程中的test目录下创建我们的测试用例了,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 如何运行测试用例
@RunWith(SpringRunner.class)
// 这是一个测试用例的类
@SpringBootTest
public class UserControllerTest {

    @Autowired
    private WebApplicationContext context;
    private MockMvc mockMvc;

    // 伪造mvc的环境,这样不会去启动我们的tomcat。提高测试速度。
    @Before
    public void setup(){
        mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
    }

    @Test
    public void whenQuerySeccess() {
        // perform是执行的意思
        try {
            mockMvc.perform(
                    // 构建一个get请求
                    MockMvcRequestBuilders.get("/user")
                            // 添加我们的请求参数
                            .param("userName","hzh")
                            // 设置utf8的contentType
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                            )
                    // 执行上面的请求结果后,我们对请求结果的期望是返回的结果是ok(200)
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    // 返回的结果是集合,集合的长度是3
                    .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
        } catch (Exception e) {
            e.printStackTrace();
        }
}

注意:由于存在大量静态方法,我们之后的讲解使用jdk1.5的静态方法导入特性。简化我们的代码。

接下来实现我们的第一个控制器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
@RequestMapping("user")
public class UserController {
    @GetMapping
    public List<User> query(@RequestParam(required = false, name = "userName", defaultValue = "hzh") String nickName) {
        List<User> users = new ArrayList<>();
        users.add(new User());
        users.add(new User());
        users.add(new User());
        return users;
    }
}

在上面的代码中,@RequestMapping定义了这个控制器的请求前缀,而@RequestParam对请求参数进行规范,name属性定义了请求参数名为username获取需要的参数值,若不设置name的值,默认会按照我们的方法参数名称去获取对相应的值。required和default属性定义了这个参数是可以省略的,若省略,默认值“hzh”。

写好我们的控制器后,我们可以运行从我们的测试用例去请求我们的控制器,而无需去把整个项目启动了。

使用对象接收请求的参数

若一个请求需要传递多个参数,我们直接在方法参数上写接受的参数,这样会造成我们代码的繁琐和不美观。这时候,我们可以考虑用定义一个对象去接收我们的请求的参数。若是一个分页的功能,我们还可以使用spring为我们提供好的Pageable对象接收分页参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  @GetMapping
  public List<User> query(UserQueryCondition condition, Pageable pageable) {
      System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
      System.out.println(ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
      List<User> users = new ArrayList<>();
      users.add(new User());
      users.add(new User());
      users.add(new User());
      return users;
  }

这时候我们可以把测试用例写成这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  try {
      String result = mockMvc.perform(
              // 构建一个get请求
              get("/user")
                      // 普通的参数
                      .param("userName", "hzh")
                      .param("age", "18")
                      .param("ageTo", "60")
                      .param("xxx", "yyy")
                      // 分页参数相关
                      // size表示每页显示数目
                      .param("size", "10")
                      // page表示第几页
                      .param("page", "3")
                      // sort表示排序的方式
                      .param("sort", "age.desc")
                      // 设置utf8的contentType
                      .contentType(MediaType.APPLICATION_JSON_UTF8))
              // 执行上面的请求结果后,我们对请求结果的期望是返回的结果是ok(200)
              .andExpect(status().isOk())
              // 返回的结果是集合,集合的长度是3
              .andExpect(jsonPath("$.length()").value(3))
              // 获取返回的数据
              .andReturn().getResponse().getContentAsString();
      System.out.println(result);
  } catch (Exception e) {
      e.printStackTrace();
}

@PathVariable的使用

由于在Restful API中,有时候需要把参数直接放在URL中,那么我们该如何映射到我们的参数上呢?

下面我们以一个获取用户信息为例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  @RequestMapping(value = "/user/{id:\\d+}", method = RequestMethod.GET)
  public User getUserInfo(@PathVariable(name = "id") String id){
      User user = new User();
      user.setName("hzh");
      return user;
  }

我们使用到的正是@PathVariable的注解来获取url中的数据,并且为了规范我们的id只能是数字,我们还可以在@RequestMapping的value中加入正则表达式进行校验。

下面是我们的测试用例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  @Test
  public void whenGenInfoSuccess() {
      try {
          String result = mockMvc.perform(get("/user/1")
                  .contentType(MediaType.APPLICATION_JSON_UTF8))
                  .andExpect(status().isOk())
                  // 返回的json中有一个值为hzh的username
                  .andExpect(jsonPath("$.name").value("hzh"))
                  // 获取返回的数据
                  .andReturn().getResponse().getContentAsString();
          System.out.println(result);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

如果我们发送一个错误的请求,那么可以使用以下的方式说明这个请求是错误的,并且测试运行时控制台不会不爆红。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  @Test
  public void whenGenInfoFail() {
      try {
          mockMvc.perform(get("/user/a")
                  .contentType(MediaType.APPLICATION_JSON_UTF8))
                  // 判断服务端返回的是一个4xx的状态码
                  .andExpect(status().is4xxClientError());
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

@JsonView的使用

在某一些请求返回的JSON中,我们并不希望返回某些字段,而在另一些请求中需要返回某些字段。比如我们在上面的代码中我们希望调用查询user集合只返回name,而查询每一个user返回的是name和password。我们可以在User类中使用接口的方式定义过个返回的视图。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class User {

    public interface UserSimpleView{}
    // 继承的方式,简化视图字段的定义
    public interface UserDetailView extends UserSimpleView{}

    private String name;

    @NotBlank
    private String password;

    @JsonView(UserSimpleView.class)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @JsonView(UserDetailView.class)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

并在Controller的方法上面也指定视图,这样就会自动过滤不需要返回的字段。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/user", method = RequestMethod.GET)
@JsonView(User.UserSimpleView.class)
public List<User> query(UserQueryCondition condition, Pageable pageable) {}
    
@RequestMapping(value = "/user/{id:\\d+}", method = RequestMethod.GET)
@JsonView(User.UserDetailView.class)
public User getUserInfo(@PathVariable(name = "id") String id){}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java患者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Gazebo與ROS版本說明
Gazebo Ubuntu包 安装Gazebo的最简单的方法是使用软件包。 Gazebo包有两个主要的仓库:一个是packages.ros.org,另一个是packages.osrfoundation.org。在写作时:     packages.ros.org         Indigo:主机Gazebo版本2.x包。         Jade:主机Gazebo版本5.x包。     packages.osrfoundation.org         gazebo 5.x系列(包名称gazebo5)         gazebo 6.x系列(包名称gazebo6)         gazebo 7.x系列(包名称gazebo7) 这意味着,包含osrfoundation存储库不是绝对需要得到Gazebo Ubuntu包。它可以从ros存储库安装。 Gazebo从源建造 如果你从源码编译了Gazebo版本,注意,根据使用的存储库分支(gazebo6,gazebo7,...)你的Gazebo将与gazebo_ros_pkgs(和所有其他ROS包编译在Gazebo顶部)二进制兼容只有主要版本匹配您的本地分支存储库和您的ROS发行版中使用的Gazebo版本。例如,如果您从Gazebo分支gazebo_2.0进行编译,则可以使用Indigo中的gazebo_ros_pkgs(使用gazebo2系列)。
zhangrelay
2022/11/30
1.1K0
ROS资料----工业机器人 ROS-I Kinetic 培训课程
全部资料幻灯片和示例代码:http://download.csdn.net/detail/zhangrelay/9772491 
zhangrelay
2019/01/23
1.9K0
ROS机器人操作系统新发布软件包摘录--(2018.03)
1 https://wiki.ros.org/vtec_ros 2 https://github.com/lukscasanova/vtec_ros 。
zhangrelay
2022/04/29
1.4K0
ROS机器人操作系统新发布软件包摘录--(2018.03)
ROS机器人操作系统资料与资讯(2018年5月)
之后,全部教程将结合Python、C++和Matlab进行撰写,在高校课程中应用双语教学目标。
zhangrelay
2019/01/23
1.1K0
离线ROS API文档(Zeal或Dash)
版权声明:本文为zhangrelay原创文章,有错请轻拍,转载请注明,谢谢... https://blog.csdn.net/ZhangRelay/article/details/78474756
zhangrelay
2019/07/01
2.3K0
离线ROS API文档(Zeal或Dash)
ROS工业机器人和工业自动化竞赛Agile Robotics for Industrial Automation Competition (ARIAC)
ARIAC要求参与者完成以工业场景为中心的一系列测试,这些测试基于由特定部件组成的建筑工具。机器人系统将在“工作环境”部分指定的环境中工作。
zhangrelay
2022/04/28
7490
ROS工业机器人和工业自动化竞赛Agile Robotics for Industrial Automation Competition (ARIAC)
ROS机器人虚拟仿真挑战赛本地电脑环境配置记录
上述过程是一个详细的步骤列表,用于在ROS Noetic环境中设置并运行Tianbot的Tianracer项目。这个过程涉及多个方面,包括更新软件包、安装ROS包、克隆源代码、构建工作空间、配置环境以及启动仿真。以下是对整个过程的详细总结:
zhangrelay
2024/05/25
2420
ROS机器人虚拟仿真挑战赛本地电脑环境配置记录
在Ubuntu 18.04 LTS安装ROS Melodic版机器人操作系统(2019年10月更新MoveIt! 1.0 ROS 2.0 Dashing)
ROS Melodic版本在2018年5月23日推出正式版,这是ROS第三款长期支持版本,前2版LTS分别为:indigo(14.04);kinetic(16.04)。此版本有windows版已经推出,无需更换Linux,一小时安装完成:
zhangrelay
2022/04/29
8750
ROS资讯(201801)
很多使用ROS的用户都在用Gazebo仿真,不过我个人感觉Virtual Robot Experimentation Platform(V-Rep)也非常不错的,如下:
zhangrelay
2022/04/29
1.2K0
ROS资讯(201801)
Ubuntu与ROS的Docker桌面系统与ROS在线练习课程(在线Linux虚拟机)
https://www.shiyanlou.com/courses/854 邀请码 U23ERF8H
zhangrelay
2019/01/23
5.9K0
ROS 2.0-SPRINGER-机器人学工具科研和教学重要参考书-机器人操作系统(ROS)-THE COMPLETE REFERENCE
版权声明:本文为zhangrelay原创文章,有错请轻拍,转载请注明,谢谢... https://blog.csdn.net/ZhangRelay/article/details/90200680
zhangrelay
2019/05/17
1.2K0
ROS 2.0-SPRINGER-机器人学工具科研和教学重要参考书-机器人操作系统(ROS)-THE COMPLETE REFERENCE
ROS机器人高效编程(原书第3版)勘误、问题及资料汇总
补充一行代码装ROS,适用于14.04LTS(indigo)和16.04LTS(Kinetic):
zhangrelay
2019/01/23
9870
如何保护你的开源项目免遭供应链攻击
过去一年可谓是供应链安全年。如果你是一个开源维护者,当你了解了项目的攻击面以及项目整个供应链的威胁载体,你可能会感到不知所措,甚至觉得无法克服。好消息是,2021 年也是供应链安全解决方案年。虽然还有很多工作要做,现有的解决方案也有很大的改进空间,但已经可以对项目进行预防性控制,以强化供应链,免受安全威胁。
深度学习与Python
2022/04/19
6630
如何保护你的开源项目免遭供应链攻击
在Ubuntu 18.04 LTS安装ROS Melodic版机器人操作系统
ROS Melodic版本在5月23日推出正式版,这是ROS第三款长期支持版本,前2版LTS分别为:indigo;kinetic。
zhangrelay
2019/01/23
5K0
ROS 2 Foxy Fitzroy:为生产和开发机器人设定新标准
作者:Matt Hansen,Aaron Blasdel和Camilo Buscaron (机器翻译)
zhangrelay
2022/03/14
1.4K0
ROS 2 Foxy Fitzroy:为生产和开发机器人设定新标准
一篇文章了解CI/CD管道全流程
从CI/CD过程开始,包含所有阶段并负责创建自动化和无缝的软件交付的一系列步骤称为CI/CD管道工作流。使用CI/CD管道,软件发布工件可以从代码提交阶段到测试、构建、部署和生产阶段在管道中移动和前进。这个概念非常强大,因为一旦指定了一个管道,它的一部分或全部就可以实现自动化,从而加快流程并减少错误。换句话说,CI/CD管道使企业更容易一天自动多次交付软件。
陈哥聊测试
2021/04/15
4.1K0
一篇文章了解CI/CD管道全流程
ROS Noetic Ninjemys遇见Ubuntu 20.04
同时安装了ROS1Noetic和ROS2Foxy,可以参考如下代码进行默认环境选择:
zhangrelay
2020/08/02
1.4K0
ROS 2 ardent apalone安装和使用说明
 I . ROS 1(代表indigo/kinetic):http://wiki.ros.org/
zhangrelay
2019/01/23
1.6K0
OWASP TOP10 OSS 风险:开源软件安全指南
在最近的一些暴露的漏洞和风险之后,对开源软件 (OSS)的安全和使用方式进行批判性审视的呼声越来越高,特别是 XZ Utils(用于压缩和解压缩 XZ 文件) 事件,揭示了一个后门是如何插入到广泛使用的系统中。
星尘安全
2024/12/03
1560
OWASP TOP10 OSS 风险:开源软件安全指南
Gazebo和ROS2的使用说明(部分翻译)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
zhangrelay
2019/09/18
2.6K0
Gazebo和ROS2的使用说明(部分翻译)
推荐阅读
相关推荐
Gazebo與ROS版本說明
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验