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
相关推荐
苹果醋335 分钟前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
盛派网络小助手1 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
∝请叫*我简单先生2 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
荆州克莱2 小时前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
zquwei3 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
dessler3 小时前
Docker-run命令详细讲解
linux·运维·后端·docker
武昌库里写JAVA3 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_19284999064 小时前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端