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
相关推荐
rOuN STAT21 分钟前
Skywalking介绍,Skywalking 9.4 安装,SpringBoot集成Skywalking
spring boot·后端·skywalking
赵丙双2 小时前
spring boot 排除自动配置类的方式和原理
java·spring boot·自动配置
bilI LESS2 小时前
Spring Boot接收参数的19种方式
java·spring boot·后端
Chan162 小时前
MCP 开发实战:Git 信息查询 MCP 服务开发
java·开发语言·spring boot·git·spring·java-ee·intellij-idea
web前端进阶者2 小时前
Rust初学知识点快速记忆
开发语言·后端·rust
七夜zippoe3 小时前
API设计规范:RESTful API设计与OpenAPI(Swagger)完整指南
后端·restful·设计规范
2601_949817724 小时前
Spring+SpringMVC项目中的容器初始化过程
java·后端·spring
青柠代码录4 小时前
【SpringBoot】集成 Knife4j
后端
杰克尼4 小时前
SpringCloud_day04
后端·spring·spring cloud
阿琳a_4 小时前
在github上部署个人的vitepress文档网站
前端·vue.js·github·网站搭建·cesium