SpringBoot和Vue接口调用传参方式

简单总结一下常用的传参方式,一些前后端分离项目接口调试时经常出现传参格式错误问题。

前后端进行交互时方法一般就分为get和post,至于后面的delete和put都是基于post进行封装而出的。

Http请求中不同的请求方式会设置不同的Content-Type,参数的传递方式就会不一样,主要分为以下三种:Query String ParametersForm DataRequest Payload

下面使用的axios请求都是经过封装的,文章最后有对应的封装方法

GET请求

我们发送get请求时,参数是通过url的形式进行传递,即url中?后面拼接的参数,以&做连接,参数直接表现在url中。

例如:http://localhost:8801/api/selectDetail?id=1&userName="zhang"

前端通过query String parameters 方式传参,axios中指明使用params

java 复制代码
export function selectList(params) {
  return request({
    url: 'api/xxx/selectList',
    method: 'get',
    params
  })
}

POST请求

Post请求有两种传递参数的形式:form datarequest payload的形式

发起post请求时若未指定content-type,则默认content-type为application/x-www-form-urlencoded,参数是在请求体中,参数以form data的形式传递,不会出现在请求的url中。

若content-type为application/json,则参数会以request payload的形式进行传递,数据格式为json形式,请求表单的参数在request payload中,不会出现在请求的url中,使用原生的Ajax post请求不指定请求头默认的参数就是出现在request payload中。

前端通过formData方式传参,axios中指明使用data

java 复制代码
export function selectList(data) {
  return request({
    url: 'api/xxx/selectList',
    method: 'post',
    data
  })
}

前端通过request payload方式传参

java 复制代码
export function selectList(data) {
  return request({
    url: 'api/xxx/selectList',
    method: 'post',
    data
  })
}

SpringBoot注解对应传参方式

@RequestParam() 默认接收application/x-www-form-urlencoded编码格式的参数
@RequestBody() 默认接收json格式的参数

  1. spring通过 @requestParam (queryParam)(路径传参-默认传参注解)接收的参数都是url拼接 将参数放到query String parameters,前端可以通过下面三种方式传参
    • params 传参 (推荐) -- params
    • formData传参 -- data (需要修改Content-Type)
    • Qs传参 -- data ,需要手动处理header "Content-Type": "application/x-www-form-urlencoded"

spring boot接口

java 复制代码
@GetMapping(value = "/hello")
    public ResponseEntity getUser(@RequestParam String username){  
}
//http://lcoalhost:8080/hello?username=1111

axios调用

javascript 复制代码
#params 传参
export function find(params){
  return request({
    url: `${API}/info/find`,
    method: 'get',
    params:params
  })
}
  1. spring通过@requestBody,通过post提交消息主体中参数,参数值为json格式,默认就是json格式不需要进行处理
  • 通过data传参

springboot 接口

java 复制代码
@PostMapping
public ResponseEntity<Record> add(@RequestBody Record record) {
    return ResponseEntity.ok(this.recordService.insert(record));
}

axios调用方法(这里的axios是经过封装后的)

javascript 复制代码
export function add(data){
  return request({
    url: `${API}/record/add`,
    method: 'post',
    data
  })
}

请求信息:

bash 复制代码
POST http://localhost:5138/record/
Content-Type: application/json
--- 参数内容
{
  "objective": 1.0,
  "objRate": 1.0,
  "objDate": "2022/1/8 12:05:00",
  "outputPrice": 1.0,
}
  1. @pathVariable(@pathParam)url路径中参数
  • 拼接url

springboot接口

java 复制代码
@DeleteMapping(value = "/job/{id}")
    public ResponseEntity delete(@PathVariable(value = "id", required = false, defaultValue = "0") Long id){
}
//http://localhost:8080/job/1

axios调用

javascript 复制代码
export function queryById(id){
  return request({
    url: `${API}/info/queryById/${id}`,
    method: 'get'
  })
}

axios对应的封装方法

javascript 复制代码
// 封装axios:使用请求与响应拦截器
import axios from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
// 引入qs
import qs from 'qs'
import useUserStore from '@/store/modules/user'

// 利用axios对象的create方法,创建axios实例(其他的配置:基础路径、超时时间)
const service = axios.create({
  //基础路径
  baseURL: '/',
  timeout: 5000, // 超时时间的设置
})
// 第二步:request实例添加请求与响应拦截器
service.interceptors.request.use((config) => {
  // 获取用户仓库内的token,登录成功后携带公共参数
  let userStore = useUserStore()
  if(userStore.token) {
    config.headers['Authorization'] = userStore.token
  }
  return config
})

// 第三步:配置相应拦截器
service.interceptors.response.use(
  (response) => {
    // 获取返回成功数据的状态码code和错误信息message
    const { code, message } = response.data;
    if(code) {
      // 有状态码判断是否为200,除此皆为异常响应
      if(code == 200) {
       return response.data
      }
      else if (code < 200 || code > 300) {
        ElMessage({
          message: message || '系统出错',
          type: 'error'
        });
        return Promise.reject('error')
      }
      else {
        // 其他类型的状态码
        ElMessage.error(message)
        return Promise.reject(response.data)
      }
    } else {
      // 未返回状态码直接返回响应信息
      ElMessage.error('系统服务连接失败')
      return Promise.reject(response)
    }
  },
  (error) => {
    // 失败的回调:处理http网络错误
    //定义一个变量:存储网络错误信息
    let message = ''
    if(error.code === 'ECONNABORTED') {
      message = '连接超时中止,请稍后重试!'
    } else {
      // http状态码
      const status = error.response.status
      switch (status) {
        case 401:
          message = '无权访问'
          break
        case 404:
          message = '请求地址错误'
          break
        default:
          message = '网络出现问题'
          break
      }
    }
    // 提示错误信息
    ElMessage({
      type: 'error',
      message,
    })
    return Promise.reject(error)
  },
)


// 利用axios对象的create方法,创建axios实例(其他的配置:基础路径、超时时间)
interface ReqParamsType {
  url:string
  data?: any
  params?:any
  method?:string,
  type?:string
  timestamp?:boolean
  timeout?:number
}
const request = ({
   url,
   data,
   params,
   method= 'post',
   type='json',
   timestamp = false,
   timeout,
 }:ReqParamsType): Promise<T> => {
  let config = {
    method,
    url,
    baseURL: '/',
    withCredentials: true,
    responseType: 'json',
    headers: {
      'Access-Control-Allow-Origin': '*',
      'X-Requested-With': 'XMLHttpRequest'
    },
    timestamp: timestamp,
    timeout: timeout
  };
  if (method === 'get') {
    if (timestamp) {
      config.url += config.url.indexOf('?') > 0 ? '&' : '?';
      config.url += `timestamp=${+new Date()}`;
    }
    Object.assign(config, {
      params
    });
  }
  else {
    if (type === 'form') {
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
      Object.assign(config, {
        data: qs.stringify(data)
      });
      config.url = config.url+'?'+qs.stringify(data)
    } else if (type === 'json') {
      config.headers['Content-Type'] = 'application/json';
      Object.assign(config, {
        data: data
      });
    } else if (type === 'formData') {
      let formData = new FormData();
      for (let i in data) {
        if(data[i] != null) {
          formData.append(i, data[i]);
        }
      }
      config.headers['Content-Type'] = 'multipart/form-data';
      Object.assign(config, {
        data: formData
      });
    }else if(type === 'picture'){
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
      Object.assign(config, {
        data: data
      });
    }
    if(timestamp) {
      const code = `${(new Date()).getTime()}_${Math.round(Math.random()*10000)}`
    }
  }
  return new Promise((resolve, reject) => {
    service(config).then((response) => {
      resolve(response);
    }, (error) => {
      reject(error);
    }).catch((error) => {
      reject(error);
    });
  });
}
// 对外暴露
export default request
相关推荐
摇滚侠2 小时前
JAVA 项目教程《苍穹外卖-12》,微信小程序项目,前后端分离,从开发到部署
java·开发语言·vue.js·node.js
wb043072013 小时前
使用 Java 开发 MCP 服务并发布到 Maven 中央仓库完整指南
java·开发语言·spring boot·ai·maven
nbwenren4 小时前
Springboot中SLF4J详解
java·spring boot·后端
helx825 小时前
SpringBoot中自定义Starter
java·spring boot·后端
rleS IONS6 小时前
SpringBoot获取bean的几种方式
java·spring boot·后端
lifewange6 小时前
Go语言-开源编程语言
开发语言·后端·golang
白毛大侠6 小时前
深入理解 Go:用户态和内核态
开发语言·后端·golang
R***z1017 小时前
Spring Boot 整合 MyBatis 与 PostgreSQL 实战指南
spring boot·postgresql·mybatis
王码码20357 小时前
Go语言中的数据库操作:从sqlx到ORM
后端·golang·go·接口
星辰_mya7 小时前
雪花算法和时区的关系
数据库·后端·面试·架构师