一篇文章带你搞懂Java restful 接口开发

目录
  • 1、RESTful 简介
    • a>资源
    • b>资源的表述
    • c>状态转移
  • 2、RESTful 的实现
  • 3、HiddenHttpMethodFilter
  • 4、RESTful 案例
    • 4.1、需求
    • 4.2、git 代码位置
    • 4.3、UserController
    • 4.4、添加 HiddenHttpMethodFilter
    • 4.5、测试效果
  • 总结

1、RESTful 简介

REST:Representational State Transfer,表现层资源状态转移。

a>资源

资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解。与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。一个 资源可以由一个或多个 URI 来标识。URI 既是资源的名称,也是资源在 Web 上的地址。对某个资源感兴趣的客户端应用,可以通过资源的 URI 与其进行交互。

b>资源的表述

资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器端之间转移(交换)。资源的表述可以有多种格式,例如 HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。

c>状态转移

状态转移说的是:在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。

2、RESTful 的实现

具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。

它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。

操作 传统方式 REST 风格
查询操作 getUserById?id=1 user/1-->get 请求方式
保存操作 saveUser user-->post 请求方式
删除操作 deleteUser?id=1 user/1-->delete 请求方式
更新操作 updateUser user-->put 请求方式

3、HiddenHttpMethodFilter

由于浏览器只支持发送 get 和 post 方式的请求,那么该如何发送 put 和 delete 请求呢?

SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们将 POST 请求转换为 DELETE 或 PUT 请求。

HiddenHttpMethodFilter 处理 put 和 delete 请求的条件:

  • 当前请求的请求方式必须为 post
  • 前请求必须传输请求参数_method

满足以上条件,HiddenHttpMethodFilter 过滤器就会将当前请求的请求方式转换为请求参数_method 的值,因此请求参数_method 的值才是最终的请求方式。

在 web.xml 中注册 HiddenHttpMethodFilter

<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filterclass>
</filter>
<filter-mapping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

使用注意:

目前为止,SpringMVC 中提供了两个过滤器:CharacterEncodingFilter 和 HiddenHttpMethodFilter

在 web.xml 中注册时,必须先注册 CharacterEncodingFilter,再注册 HiddenHttpMethodFilter

原因:

在 CharacterEncodingFilter 中通过 request.setCharacterEncoding(encoding) 方法设置字符集的

request.setCharacterEncoding(encoding) 方法要求前面不能有任何获取请求参数的操作而 HiddenHttpMethodFilter 恰恰有一个获取请求方式的操作:

String paramValue = request.getParameter(this.methodParam);

4、RESTful 案例

4.1、需求

通过 restfull 实现用户的增删改查,需要提供 5 个接口。

接口 method 描述
/user/list GET 获取用户列表
/user/{userId} GET 根据用户 id 获取用户信息
/user POST 新增用户信息
/user PUT 保存用户信息
/user/{userId} DELETE 删除用户信息

4.2、git 代码位置

https://gitee.com/javacode2018/springmvc-series

4.3、UserController

UserController 中实现了需求中提到的 4 个接口,大家重点看下每个接口的方法上用到的注解。

@RestController
public class UserController {
    private List<User> userList = new ArrayList<>();

    {
        userList.add(new User(1, "Spring高手系列"));
        userList.add(new User(2, "SpringMVC系列"));
    }

    @GetMapping("/user/list")
    public List<User> list() {
        System.out.println("list()");
        return userList;
    }

    @GetMapping("/user/{userId}")
    public User getUser(@PathVariable("userId") Integer userId) {
        System.out.println("getUser()");
        for (User user : userList) {
            if (user.getUserId().equals(userId)) {
                return user;
            }
        }
        return null;
    }

    @PostMapping(value = "/user", produces = "text/html;charset=UTF-8")
    public String add(User user) {
        System.out.println("add()");
        this.userList.add(user);
        return "新增成功";
    }

    @PutMapping(value = "/user", produces = "text/html;charset=UTF-8")
    public String modify(User user) {
        System.out.println("modify()");
        for (User item : userList) {
            if (item.getUserId().equals(user.getUserId())) {
                item.setName(user.getName());
            }
        }
        return "修改成功";
    }

    @DeleteMapping(value = "/user/{userId}", produces = "text/html;charset=UTF-8")
    public String delete(@PathVariable("userId") Integer userId) {
        System.out.println("delete()");
        Iterator<User> iterator = userList.iterator();
        while (iterator.hasNext()) {
            User user = iterator.next();
            if (user.getUserId().equals(userId)) {
                iterator.remove();
            }
        }
        return "删除成功";
    }

    public static class User {
        private Integer userId;
        private String name;

        public User() {
        }

        public User(Integer userId, String name) {
            this.userId = userId;
            this.name = name;
        }

        public Integer getUserId() {
            return userId;
        }

        public void setUserId(Integer userId) {
            this.userId = userId;
        }

        public String getName() {
            return name;
        }

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

        @Override
        public String toString() {
            return "User{" +
                    "userId=" + userId +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
}

4.4、添加 HiddenHttpMethodFilter

HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();

4.5、测试效果

将项目发布到 tomcat,如下图,跑一下 UserController.http 中的 5 个用例,点击每个用户中的绿色箭头即可运行,注意下后面 3 个用例都是 POST 方式提交的,但是参数中多了一个_method 参数用来指定提交的类型,这个参数会被HiddenHttpMethodFilter 解析。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • 浅谈java调用Restful API接口的方式

    摘要:最近有一个需求,为客户提供一些RestfulAPI接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试RestfulAPI接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理.由于我也是首次使用Java调用restful接口,所以还要研究一番,自然也是查阅了一些资料. 分析:这个问题与模块之间的调用不同,比如我有两个模块frontend和backend,frontend提供前台展示,backend提供数据支

  • Java 调用Restful API接口的几种方式(HTTPS)

    摘要:最近有一个需求,为客户提供一些Restful API 接口,QA使用postman进行测试,但是postman的测试接口与java调用的相似但并不相同,于是想自己写一个程序去测试Restful API接口,由于使用的是HTTPS,所以还要考虑到对于HTTPS的处理.由于我也是首次使用Java调用restful接口,所以还要研究一番,自然也是查阅了一些资料. 分析:这个问题与模块之间的调用不同,比如我有两个模块front end 和back end,front end提供前台展示,back

  • Java进阶之走进RESTful接口

    一.什么是API API (应用程序编程接口) 两种用法 1.类似jar的使用:A软件将功能打包成组件(功能块:比如java中的jar),让B软件导入直接使用 2.http请求方式:A项目(系统)提供一个映射方法路径,B项目(系统)发起http请求得到对应功能 (应用请求方式) 应用接口:很多情况下,需要把系统的部分功能(组件)作为服务暴露给外部的其他应用使用,所以就需要把系统中的服务作为API接口暴露出去,一般分为公共接口和私用接口(公司内部) 二.了解Web技术的发展阶段 静态内容阶段:We

  • java调用Restful接口的三种方法

    目录 1,基本介绍 2,HttpURLConnection实现 3.HttpClient实现 4.Spring的RestTemplate 1,基本介绍 Restful接口的调用,前端一般使用ajax调用,后端可以使用的方法比较多, 本次介绍三种: 1.HttpURLConnection实现 2.HttpClient实现 3.Spring的RestTemplate 2,HttpURLConnection实现 @Controller public class RestfulAction { @Aut

  • Java基于rest assured实现接口测试过程解析

    背景 java程序员一般写的是后端服务是JavaWeb类型的项目,主要包括Http接口和dubbo接口,Http接口一般采用的rest风格,那么如何快速的对rest接口在第三方的测试框架上进行测试呢? rest-assured框架是一个不错的工具. 使用之前,需要熟悉一下最基础的使用方法,在写完几个接口的测试用例之后,好比你可以使用你的三棱军刺熟练的进行基础的攻击了. 快速的来一个hello world吧! 假设你写了一个接口:lotto,访问路径是: http://localhost:8080

  • Java 实现限流器处理Rest接口请求详解流程

    Maven依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>31.0.1-jre</version> </dependency> 代码 上代码,不废话. 首先是限流器代码. package com.huyi.csdn.tools.rate; import com.google.c

  • 一篇文章带你搞懂Java restful 接口开发

    目录 1.RESTful 简介 a>资源 b>资源的表述 c>状态转移 2.RESTful 的实现 3.HiddenHttpMethodFilter 4.RESTful 案例 4.1.需求 4.2.git 代码位置 4.3.UserController 4.4.添加 HiddenHttpMethodFilter 4.5.测试效果 总结 1.RESTful 简介 REST:Representational State Transfer,表现层资源状态转移. a>资源 资源是一种看待服

  • 一篇文章带你搞懂Java线程池实现原理

    目录 1. 为什么要使用线程池 2. 线程池的使用 3. 线程池核心参数 4. 线程池工作原理 5. 线程池源码剖析 5.1 线程池的属性 5.2 线程池状态 5.3 execute源码 5.4 worker源码 5.5 runWorker源码 1. 为什么要使用线程池 使用线程池通常由以下两个原因: 频繁创建销毁线程需要消耗系统资源,使用线程池可以复用线程. 使用线程池可以更容易管理线程,线程池可以动态管理线程个数.具有阻塞队列.定时周期执行任务.环境隔离等. 2. 线程池的使用 /** *

  • 一篇文章带你搞懂Python类的相关知识

    一.什么是类 类(class),作为代码的父亲,可以说它包裹了很多有趣的函数和方法以及变量,下面我们试着简单创建一个吧. 这样就算创建了我们的第一个类了.大家可以看到这里面有一个self,其实它指的就是类aa的实例.每个类中的函数只要你不是类函数或者静态函数你都得加上这个self,当然你也可以用其他的代替这个self,只不过这是python中的写法,就好比Java 中的this. 二.类的方法 1.静态方法,类方法,普通方法 类一般常用有三种方法,即为static method(静态方法),cl

  • 一篇文章带你搞懂Vue虚拟Dom与diff算法

    前言 使用过Vue和React的小伙伴肯定对虚拟Dom和diff算法很熟悉,它扮演着很重要的角色.由于小编接触Vue比较多,React只是浅学,所以本篇主要针对Vue来展开介绍,带你一步一步搞懂它. 虚拟DOM 什么是虚拟DOM? 虚拟DOM(Virtual   Dom),也就是我们常说的虚拟节点,是用JS对象来模拟真实DOM中的节点,该对象包含了真实DOM的结构及其属性,用于对比虚拟DOM和真实DOM的差异,从而进行局部渲染来达到优化性能的目的. 真实的元素节点: <div id="wr

  • 一篇文章带你搞懂JavaScript的变量与数据类型

    目录 前言: 温馨提示: 变量 1.声明 2.赋值 3.二个语法小细节 变量的命名规范 为什么需要数据类型? 简单数据类型(基本数据类型) 数字型 字符串型 String 什么是数据类型的转换 1.转换为字符串 2.转换为数字型(重点) 转化为布尔型 总结 前言: 我不是搞前端,而是搞后端的.本命编程语言是java.学习js的嘛,因为看到室友能做出动态网页,而我只能做出静态网页,再加上下个学期要学所以提前来学习学习. 温馨提示: java和javsScript没有半毛钱关系,只是javaScri

  • 一篇文章带你搞定JAVA反射

    目录 1.反射的概念 1.概念 2.获取字节码文件对象的方式 2.1 元数据的概念 2.2 获取class对象的方式 1.访问权限 2.获取方法 2.1 访问静态方法 2.2 访问类方法 3.获取字段,读取字段的值 4.获取实现的接口 5.获取构造函数,创建实例 6.获取继承的父类 7.获取注解 4.反射实例 5.总结 1.反射的概念 1.概念 反射,指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对任意一个对象,都能调用它的任意一个方法.这种动态获取信息,以及动态调用对象方法

  • 一篇文章带你搞定JAVA泛型

    目录 1.泛型的概念 2.泛型的使用 3.泛型原理,泛型擦除 3.1 IDEA 查看字节码 3.2 泛型擦除原理 4.?和 T 的区别 5.super extends 6.注意点 1.静态方法无法访问类的泛型 2.创建之后无法修改类型 3.类型判断问题 4.创建类型实例 7.总结 1.泛型的概念 泛型的作用就是把类型参数化,也就是我们常说的类型参数 平时我们接触的普通方法的参数,比如public void fun(String s):参数的类型是String,是固定的 现在泛型的作用就是再将St

  • 一篇文章带你搞定JAVA注解

    目录 1.注解是什么 2.jdk支持的注解有哪些 2.1 三种常用的注解: 2.2 元注解 3.注解实例 1.自定义注解 2.在对应的方法上增加注解 3.在项目启动的时候检查注解的枚举 4.总结 1.注解是什么 Java 注解用于为 Java 代码提供元数据,看完这句话也许你还是一脸懵逼,用人话说就是注解不直接影响你的代码执行,仅提供信息.接下我将从注解的定义.元注解.注解属性.自定义注解.注解解析JDK 提供的注解这几个方面再次了解注解(Annotation) 2.jdk支持的注解有哪些 2.

  • 一篇文章带你搞定JAVA Maven

    目录 1.maven是什么,为什么存在?项目结构是什么样子,怎么定位jar 2.Idea 的操作 1.新建maven项目 2.配置仓库 3.添加依赖,添加fastjson的依赖 4.打包项目 3.Maven坐标主要组成 4.maven生命周期 4.1 名词解释 4.2 生命周期 4.3 goal 的概念 4.4 生命周期和phase的关系 5.idea maven的配置 6.POM有2个很重要的关系:聚合.继承 一.聚合 二.继承 7.Maven 中的 profile 8.maven 插件 9.

  • 一篇文章带你搞懂Go语言标准库Time

    目录 前言 时间类型 时间戳 时间间隔 操作时间 Add Sub Equal Before After 定时器 时间格式化 解析字符串格式的时间 总结 前言 在编程过程中,我们经常会用到与时间和日期相关的各种需求,下面来介绍 Go 语言中有关时间的一些基本用法. 时间类型 time.Time 类型表示时间.可以通过 time.Now() 函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息. 示例代码如下: func main() { now := time.Now() //获取当前时间

随机推荐