开发前后端交互规范与请求封装

news2025/7/18 0:58:53

开发前后端交互规范与请求封装

  • 一,背景说明
  • 二,Axios请求封装
  • 三,数据对象封装
    • 1,前端封装
    • 2,后端封装
  • 四,总结
  • 五,Axios拦截器
  • 七,Restful请求
    • 1,Restful的由来
    • 2,Restful方法说明
    • 3,Restful请求实例

一,背景说明

假设要实现系统登录的功能,用户输入用户名和密码,点击发送,后端接收到请求,拿到输入的数据,并对输入的数据进行验证,如果账号密码都正确返回正确标识,错误则返回失败标识。这里涉及到三个需要考虑的地方,数据对象的封装,前后端交互采用哪种方式,前端请求如何发送。

二,Axios请求封装

在这里插入图片描述
Axios是一个基于promise的网络请求库,作用于node.js和浏览器中,在Vue项目中使用前需先安装

npm install axios --save --在生产环境中安装
import axios from 'axios'
// import ElementUI from 'element-ui'
const caseRequest = axios.create({
  baseURL: 'http://localhost:7080/tick_tack',
  headers: { 'Content-Type': 'application/json' }
  // timeout: 5000
})
export default caseRequest

三,数据对象封装

1,前端封装

前端数据假设只有账号,密码两个字段,业务比较复杂可以再新加验证码这些。数据对象采用模块化的方式,方便后期管理和维护,在Vue项目的views文件夹下新建一个sign-in文件夹,用来实现用户的登录功能。也可以建在component下,只是component中一般存放组件等功能相对通用的模块。
在这里插入图片描述
login-user-system.class.js:存放字段信息,可引入Vue文件中使用

class UserInSystemClass {
  constructor (userAccount, userName) {
    this.userAccount = userAccount
    this.password = password
  }
}
export default UserInSystemClass

login-to-system.service.js:caseRequest是对axios请求的封装

import caseRequest from '@/request/request'

const loginToSystem = {
  queryPerson (data) {
    // 因为params是添加到url的请求字符串中的,用于get请求。
    // data是添加到请求体(body)中的, 用于post请求。
    return caseRequest.request({
      url: '/loginUser',
      method: 'POST',
      data
    })
  }
}

login-to-system.vue:

<template>
 <div>
  <el-form ref="form" :model="loginUserSystemForm" label-width="80px">
   <el-form-item label="用户名">
    <el-input v-model="loginUserSystemForm.userAccount"></el-input>
   </el-form-item>
   <el-form-item label="密码">
    <el-input v-model="loginUserSystemForm.password"></el-input>
   </el-form-item>
   <el-form-item>
    <el-button type="primary" @click="login()">登录</el-button>
   </el-form-item>
  </el-form>
 </div>
</template>

<script>
import loginToSystemService from '@/views/sign-in/login-to-system.service'
import LoginUserSystemClass from '@/views/sign-in/class/login-user-system.class'
const resource = loginToSystemService.resource
export default {
  name: 'LoginToSystem',
  data () {
   return {
      loginUserSystemForm: new LoginUserSystemClass()
  },
  methods:{
   async login () {
        const result = await resource.loginToSystem.queryPerson(this.loginUserSystemForm)
        if (result.code === '200') {
          this.$message.success('登录成功')
          this.$router.push('/front/home')//路由跳转
        } else {
          this.$message.error('Failure')
        }
    }
  }
</script>

2,后端封装

后端数据对象封装,简单点假设只有两个字段,账号和密码

public class LoginUser{
    private String userAccount;
    private String password;
}

Controller方法

    @PostMapping("/loginUser")
    //@RequestBody:将前端传过来的json转成后端的对象
    public Result loginSystem(@RequestBody LoginUser user) {
        if (StringUtils.isBlank(user.getUserAccount())||StringUtils.isBlank(user.getPassword())){
            return Result.error(Constants.CODE_400, "参数错误");
        }
        //校验用户输入的信息,此处可以自行发挥即可
        LoginUser loginUser = loginService.loginSystem(user);
        return Result.success(loginUser);
    }

Result接口统一返回包装类

@Data
@NoArgsConstructor //无参构造
@AllArgsConstructor //有参构造
public class Result {
    private String code;//状态码
    private String msg;//返回信息
    private Object data;//返回数据参数
    //无参请求成功
    public static Result success(){
        return new Result(Constants.CODE_200,"",null);
    }
    //有参数返回请求成功
    public static Result success(Object object){
        return new Result(Constants.CODE_200,"",object);
    }
    //返回错误信息
    public static Result error(String code,String msg){
        return new Result(code, msg, null);
    }
    //返回简单的错误信息
    public static Result error(){
        return new Result(Constants.CODE_500, "系统错误", null);
    }
}

接口中定义变量

  • 接口中定义的变量都是静态变量
  • 接口中定义的变量都默认加上public static final关键字,可以直接使用,无需初始化
  • 接口中的变量可起到在多个类中共享变量的效果
public interface Constants {
    String CODE_200 = "200";//成功
    String CODE_401 = "401";//权限不足
    String CODE_400 = "400";//参数错误
    String CODE_500 = "500";//系统错误
    String CODE_600 = "600";//其它业务异常
}

四,总结

在前端和后端定义相同类型的对象,且约定好状态码的意义,例如200代表成功,500是系统错误,401是权限不足。前端通过Axios发送请求,后端接收到请求后进行业务处理,返回相应的状态码,说明信息,以及响应的参数,前端拿到后端返回的数据后,根据不同的状态码进行对应的操作,例如赋值,或是报错信息的提示。
在开发过程中应该运用模块化的思想,高内聚,低耦合,这在后期的维护和扩展中是相当有益的。

五,Axios拦截器

对Axios进行封装,发送请求时调用封装后的类还有一个好处就是可以进行拦截操作,只需在封装处做拦截,其它调用的地方不用再做重复的操作。

import axios from 'axios'
import ElementUI from 'element-ui'
const caseRequest = axios.create({
  baseURL: 'http://localhost:7080/test_demo',
  headers: { 'Content-Type': 'application/json' }
  // timeout: 5000
})

// request拦截器
// 可以在请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
caseRequest.interceptors.request.use(config => {
  config.headers['Content-Type'] = 'application/json;charset=utf-8'
  //此处是将token信息放入了浏览器的localStorage中,通过getItem()方法取出
  let user = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : null
  if (user) {
    config.headers['token'] = user.token// 设置请求头
  }
  return config
}, error => {
  return Promise.reject(error)
})

// response响应拦截器
caseRequest.interceptors.response.use(
  response => {
    let res = response.data
    // 如果返回的是文件
    if (response.config.responseType === 'blob') {
      return res
    }
    // 兼容服务端返回的字符串数据
    if (typeof res === 'string') {
      // JSON.parse是从一个字符串中解析出json
      // JSON.stringify是从一个对象中解析出字符串
      res = res ? JSON.parse(res) : res
    }
    // 当权限验证不通过的时候给出提示
     if (res.code === '401') {
       ElementUI.Message({
         message: '权限校验未通过',
         type: 'error'
       })
     }
    return res
  }
)

export default caseRequest

七,Restful请求

1,Restful的由来

  • 在Restful之前的操作:
URL说明
http://localhost:7080/test_demo/user/query/1GET 根据用户id查询用户数据
http://localhost:7080/test_demo/savePOST 新增用户
http://localhost:7080/test_demo/user/update POST修改用户信息
http://localhost:7080/test_demo/user/delete/1GET/POST 删除用户信息
  • RESTful用法:
URL说明
http://localhost:7080/test_demo/user/1GET 根据用户id查询用户数据
http://localhost:7080/test_demo/userPOST 新增用户
http://localhost:7080/test_demo/userPUT 修改用户信息
http://localhost:7080/test_demo/userDELETE 删除用户信息

之前的操作其实也没什么问题,query表示查询,以Get的方式,save表示保存,以POST方式发送,但是有的大神觉得这样不太好,太繁琐了,比如Get请求,再加个id,那就是要做查询操作,没必要路径里面还要加个query,保存操作也是,POST方式就是要保存数据,没必要再加个save,在这种情况下,Restful规范诞生了。这里也说了,Restful是一种规范,建议大家能够遵守,如果不遵守那也没事,只是会产生很多多余的URL,不方便接口的维护和文档的维护。

2,Restful方法说明

http方法资源操作幂等性安全性
GETSELECT
POSTINSERT
PUTUPDATE
DELETEDELETE

幂等性:对同一接口的多次访问,得到的资源状态是相同的
安全性:对该REST接口访问,不会使服务器端资源的状态发生改变。

3,Restful请求实例

前端Axios请求

import caseRequest from '@/request/request'
//将userAccount拼接在URL后端,类似于http://localhost:7080/test_demo/user?userAccount=2
queryParam (userAccount) {
    return caseRequest.request({
      url: '/user/param?userAccount=' + userAccount,
      method: 'GET'
    })
  },
  //将userAccount拼接在URL上,类似于http://localhost:7080/test_demo/user/2
  query (userAccount) {
    return caseRequest.request({
      url: '/user/' + userAccount,
      method: 'GET'
    })
  },
save(data) {
    return caseRequest.request({
      url: '/user',
      method: 'POST',
      data
    })
  },
 update (data) {
    return caseRequest.request({
      url: '/user',
      method: 'PUT',
      data
    })
  },
delete (userId) {
    return caseRequest.request({
      url: '/user/' + userId,
      method: 'DELETE'
    })
  }

后端Controller代码

@RestController
@RequestMapping("/user")
public class UserController {
    @GetMapping("/param")
    public Result queryParam(@RequestParam String userAccount){
       User user= userService.query(userAccount);
       return Result.success(user);
    }
    @GetMapping("/{userAccount}")
    public Result query(@PathVariable String userAccount){
       User user= userService.query(userAccount);
       return Result.success(user);
    }
    @DeleteMapping("/{userId}")
    //@PathVariable:取路径中传过来的值
    public boolean delete(@PathVariable Integer userId) {
        return userService.delete(userId);
    }

    @PostMapping
    //通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上
    public boolean save(@RequestBody User user) {
        return userService.save(user);
    }

    @PutMapping
    public boolean update(@RequestBody User user) {
        return userService.save(user);
    }
}

说明:
1.@PathVariable 注解:参数拼接在url上,value的方式入参

http://localhost:7080/test_demo/user/2

2.@RequestParam 注解:参数拼接在url上(只能用Params方式,不能用Body),以key=value的方式入参

http://localhost:7080/test_demo/user?userAccount=2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17682.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亲测好用的开发工具【1】 RuoYi-MT

亲测好用的开发工具【1】 文章目录亲测好用的开发工具【1】RuoYi-MT1 问题引入2 RuoYi-MT3 使用RuiYi-MTRuoYi-MT 1 问题引入 没错&#xff0c;又是若依&#xff0c;今天遇到一个需求&#xff0c;就是用若依打底&#xff0c;做一个自己的前后端分离的后台管理系统。 但是吧&…

电科大离散数学-1-集合论基础

目录 1.1 集合的初见 1.1.1 集合的定义 1.1.2 集合的表示方法 1.1.3 集合的基数 1.2 特殊集合与集合间关系 1.2.1 空集 1.2.2 全集 1.2.3 集合的相等关系 1.2.4 包含关系 1.2.5 幂集 1.3 集合的运算 1.3.1 并运算 1.3.2 交运算 1.3.3 补运算 1.3.4 差运算 1.3.…

使用VUE3.0版本搭建H5模板

使用VUE3.0版本搭建H5模板 仓库地址&#xff0c;有需要的可以参考参考 https://gitee.com/young_frivolous/vue3-app-template/tree/master为了方便每次写项目都要去搭建一个框架&#xff0c;今天使用vue3.0从0开始实行一个开箱即用移动端模板&#xff0c;基于vue3.0全家桶 v…

Windows安装和完全卸载MySQL8(以MySQL8.0.31版本为例) 之 Zip 方式(超详细教程)

文章目录一. 前言二. 安装1.下载MySQL2. 安装MySQL3.小结&#xff1a;4.修改环境变量3.完全卸载一. 前言 MySQL8相比之前版本改动还是挺大&#xff0c;主要有以下几点&#xff1a; MySQL8之后并不需要my.ini&#xff0c;会自动的生成data文件夹在解压之后的文件&#xff0c;端…

ArcGIS水文分析工具

Fill 填洼 凹陷点是指未定义流域方向的像元&#xff1b;其周围的像元均高于它。倾泻点是汇流区域中具有最低高程的边界像元。如果凹陷点中充满了水&#xff0c;则水将从该点倾泻出去。Arcpy代码&#xff1a; Fill(in_surface_raster, {z_limit})Flow accumulation 流量 通过流…

某邮储银行数据归集系统在HTAP场景下的选型与实践

导语&#xff1a;面对HTAP能力的需求与云原生时代的趋势&#xff0c;以及国产化的浪潮&#xff0c;某邮储银行携手OceanBase打造了云原生时代下的国产分布式数据库场景实践体验。以下内容整理自某邮储银行运维方DBA的自述。 业务痛点 我们有一套针对业务内部的运营数据归集系统…

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.12 ES 简介

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇4 数据层解决方案4.12 ES 简介4.12.1 介绍4.12.2 全文搜索工作原理4.…

C++学习笔记(Ⅳ):C++提高编程

1 模板 1.1 模板的概念 建立通用的模板&#xff0c;提高代码复用性 1.2 函数模板 c还有一种利用模板的泛型编程 1. 语法 建立函数&#xff0c;其返回值类型和形参类型用虚拟类型代表 template<typename T> // 函数模板 template<typename T> // 声明一…

使用token登录提交到github

首先从GitHub上clone自己的仓库 git clone https://github.com/ljx2/SunnyWeather.git 修改一些文件 然后 git add ./ git commit -m ‘first commit’ 然后 git push origin main 提示输入用户名密码来验证 输完之后又提示需要创建token来上传&#xff0c;由于安全&#x…

M41T62Q6F 一款具有报警功能的低功耗串行实时时钟(RTC)芯片

M41T62Q6F是一款带有 32.768 kHz 振荡器的低功耗串行实时时钟(RTC)。8 个寄存器用于提供 时钟/日历功能&#xff0c;配置为二进制编码的十进制&#xff08;BCD&#xff09;格式。另有 8 个寄存器提供报警&#xff08;闹 铃&#xff09;、32 KHz 输出、校准以及看门狗功能的状态…

《树莓派项目实战》第七节 使用声音传感器检测声音

目录 7.1 引脚介绍 7.2 工作原理 7.3 连接到树莓派 7.4 编写代码检测声音有无 在本节&#xff0c;我们将学习如何使用声音传感器检测声音&#xff0c;该项目设计到的材料有&#xff1a; 树莓派 * 1面包板 * 1杜邦线若干声音传感器 * 17.1 引脚介绍 声音传感器一共有3个引脚…

噪声系数与插入损耗

目录噪声系数定义Friis噪声级联公式无源器件的噪声系数插入损耗&#xff1f;S参数文件能用来仿真噪声系数吗在计算射频链路的级联噪声时&#xff0c;我们会输入每一级的噪声系数以及增益&#xff0c;即可计算出整个射频链路的噪声系数&#xff0c;用于系统评估。但是有同学问我…

尚医通 (二十五) --------- 医院上传接口

目录一、医院系统模拟接口1. 服务部署2. 操作说明3. 上传接口与回调接口① 业务术语② 安全控制③ 业务接口④ 平台接口⑤ 医院接口二、集成 MongoDB三、添加医院基础类四、上传医院五、参数签名六、图片 Base64 编码一、医院系统模拟接口 1. 服务部署 ① 找到资源文件夹下面…

ArcGIS pro导出地图删除右下角小字制作者服务许可

ArcGIS pro导出地图删除右下角小字制作者服务许可 ArcGIS pro具有强大的制图功能&#xff0c;提供了丰富的底图。 研究者在使用这些底图出图时&#xff0c;发现地图右下角有__制作者名单、服务许可、来源&#xff1f;__ &#xff08;我也不知道它叫什么&#xff09;如下图 就…

【深入浅出Spring6】第六期——手写Spring框架与Spring IoC注解式开发

一、手写Spring框架 $ 准备工作 创建新的模块 myspring我们采用边测试边写框架的方式&#xff0c;所以还需要我们提供待测试的类 一号嘉宾——User类&#xff1a;用于一般类型传值测试 package com.powernode.myspring.bean; /*** author Bonbons* version 1.0*/ public clas…

【面试题】CSS响应式

1. rem是什么&#xff1f; rem&#xff0c;CSS3新增的一个相对单位&#xff08;root em&#xff0c;根em&#xff09;&#xff0c;相对于根元素&#xff0c;常用于响应式布局em&#xff0c;相对长度单位&#xff0c;相对于父元素&#xff0c;不常用px&#xff0c;像素&#xf…

中兴通讯完成基于低频 5G 商用基站的通感融合测试验证

11 月 16 日消息&#xff0c;今年 11 月&#xff0c;在 IMT-2020&#xff08;5G&#xff09;推进组的指导下&#xff0c;中兴通讯使用 4.9GHz 低频 5G 商用基站&#xff0c;完成了室外无人机、车辆和行人感知测试验证以及室内场景下呼吸感知的测试验证。验证结果显示&#xff0…

api-ms-win-crt-runtime-l1-1-0.dll文件加载失败是怎么造成的?怎么修复?

电脑中是含有大量不同类型的软件程序的&#xff0c;这些软件程序为用户们提供了丰富的功能&#xff0c;用户们使用这些软件的时候虽然看上去比较简单&#xff0c;但是电脑系统内部却是会调用大量文件的&#xff0c;在软件执行命令的过程中无论哪个环节出现了问题&#xff0c;都…

DDD系列 实战一 应用设计案例 (golang)

DDD系列 实战一 应用设计案例 (golang) 基于 ddd 的设计思想, 核心领域需要由纯内存对象基础设施的抽象的接口组成 独立于外部框架: 比如 web 框架可以是 gin, 也可以是 beego独立于客户端: 比如客户端可以是 web, 可以是移动端, 也可以是其他服务 rpc 调用独立于基础组件: 比如…

数据结构计算二叉树的深度和节点个数

2022.11.19 计算二叉树的深度和节点个数任务描述相关知识编程要求测试说明C/C代码任务描述 本关任务&#xff1a;给定一棵二叉树&#xff0c;计算该二叉树的深度、总节点个数和叶子节点个数。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.二叉树深度概念…