当前位置: 代码网 > it编程>编程语言>Java > SpringBoot+Vue 前后端接口交互的项目实践

SpringBoot+Vue 前后端接口交互的项目实践

2025年07月03日 Java 我要评论
一、前后端交互架构概览二、spring boot 后端接口实现2.1 基础rest控制器@restcontroller@requestmapping("/api/users")@crossorigin

一、前后端交互架构概览

二、spring boot 后端接口实现

2.1 基础rest控制器

@restcontroller
@requestmapping("/api/users")
@crossorigin // 处理跨域,生产环境应配置具体域名
public class usercontroller {
    
    @autowired
    private userservice userservice;

    // 获取用户列表
    @getmapping
    public responseentity<list<userdto>> getusers(
            @requestparam(required = false) string name) {
        list<userdto> users = userservice.findusers(name);
        return responseentity.ok(users);
    }

    // 获取单个用户
    @getmapping("/{id}")
    public responseentity<userdto> getuser(@pathvariable long id) {
        userdto user = userservice.getuserbyid(id);
        return responseentity.ok(user);
    }

    // 创建用户
    @postmapping
    public responseentity<userdto> createuser(
            @valid @requestbody usercreaterequest request) {
        userdto newuser = userservice.createuser(request);
        return responseentity.status(httpstatus.created).body(newuser);
    }

    // 更新用户
    @putmapping("/{id}")
    public responseentity<userdto> updateuser(
            @pathvariable long id,
            @valid @requestbody userupdaterequest request) {
        userdto updateduser = userservice.updateuser(id, request);
        return responseentity.ok(updateduser);
    }

    // 删除用户
    @deletemapping("/{id}")
    public responseentity<void> deleteuser(@pathvariable long id) {
        userservice.deleteuser(id);
        return responseentity.nocontent().build();
    }
}

2.2 dto设计示例

用户创建请求dto

@data
public class usercreaterequest {
    @notblank(message = "用户名不能为空")
    @size(max = 50, message = "用户名最长50个字符")
    private string username;

    @notblank(message = "密码不能为空")
    @size(min = 6, max = 20, message = "密码长度6-20位")
    private string password;

    @email(message = "邮箱格式不正确")
    private string email;

    @pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    private string phone;
}

用户响应dto

@data
@jsoninclude(jsoninclude.include.non_null)
public class userdto {
    private long id;
    private string username;
    private string email;
    private string phone;
    @jsonformat(pattern = "yyyy-mm-dd hh:mm:ss")
    private localdatetime createtime;
}

2.3 全局异常处理

@restcontrolleradvice
public class globalexceptionhandler {

    // 处理验证异常
    @exceptionhandler(methodargumentnotvalidexception.class)
    public responseentity<errorresponse> handlevalidationexception(
            methodargumentnotvalidexception ex) {
        list<string> errors = ex.getbindingresult()
                .getfielderrors()
                .stream()
                .map(error -> error.getfield() + ": " + error.getdefaultmessage())
                .collect(collectors.tolist());
        
        errorresponse response = new errorresponse(
                "validation_failed", 
                "参数验证失败", 
                errors);
        
        return responseentity.badrequest().body(response);
    }

    // 处理业务异常
    @exceptionhandler(businessexception.class)
    public responseentity<errorresponse> handlebusinessexception(
            businessexception ex) {
        errorresponse response = new errorresponse(
                ex.getcode(), 
                ex.getmessage(), 
                null);
        return responseentity.status(ex.getstatus()).body(response);
    }
}

三、vue 前端接口调用

3.1 axios 封装

// src/utils/request.js
import axios from 'axios'
import { message } from 'element-ui'
import store from '@/store'
import router from '@/router'

// 创建axios实例
const service = axios.create({
  baseurl: process.env.vue_app_base_api,
  timeout: 10000
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 添加token
    if (store.getters.token) {
      config.headers['authorization'] = 'bearer ' + store.getters.token
    }
    return config
  },
  error => {
    return promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    const res = response.data
    
    // 业务错误处理
    if (res.code && res.code !== 200) {
      message({
        message: res.message || 'error',
        type: 'error',
        duration: 5 * 1000
      })
      
      // 特定状态码处理
      if (res.code === 401) {
        // 跳转登录
      }
      return promise.reject(new error(res.message || 'error'))
    } else {
      return res
    }
  },
  error => {
    // http错误处理
    message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return promise.reject(error)
  }
)

export default service

3.2 api模块化封装

// src/api/user.js
import request from '@/utils/request'

// 获取用户列表
export function getusers(params) {
  return request({
    url: '/api/users',
    method: 'get',
    params
  })
}

// 获取用户详情
export function getuser(id) {
  return request({
    url: `/api/users/${id}`,
    method: 'get'
  })
}

// 创建用户
export function createuser(data) {
  return request({
    url: '/api/users',
    method: 'post',
    data
  })
}

// 更新用户
export function updateuser(id, data) {
  return request({
    url: `/api/users/${id}`,
    method: 'put',
    data
  })
}

// 删除用户
export function deleteuser(id) {
  return request({
    url: `/api/users/${id}`,
    method: 'delete'
  })
}

3.3 vue组件中调用示例

<template>
  <div>
    <el-table :data="userlist">
      <!-- 表格内容 -->
    </el-table>
    
    <el-dialog :visible.sync="dialogvisible">
      <el-form :model="userform" :rules="rules" ref="userform">
        <!-- 表单内容 -->
      </el-form>
    </el-dialog>
  </div>
</template>

<script>
import { getusers, createuser } from '@/api/user'

export default {
  data() {
    return {
      userlist: [],
      dialogvisible: false,
      userform: {
        username: '',
        password: '',
        email: '',
        phone: ''
      },
      rules: {
        username: [
          { required: true, message: '请输入用户名', trigger: 'blur' },
          { max: 50, message: '长度不超过50个字符', trigger: 'blur' }
        ],
        // 其他验证规则...
      }
    }
  },
  created() {
    this.fetchusers()
  },
  methods: {
    // 获取用户列表
    async fetchusers() {
      try {
        const { data } = await getusers({ name: this.searchname })
        this.userlist = data
      } catch (error) {
        console.error('获取用户列表失败:', error)
      }
    },
    
    // 提交表单
    submitform() {
      this.$refs.userform.validate(async valid => {
        if (valid) {
          try {
            await createuser(this.userform)
            this.$message.success('创建成功')
            this.dialogvisible = false
            this.fetchusers() // 刷新列表
          } catch (error) {
            console.error('创建用户失败:', error)
          }
        }
      })
    }
  }
}
</script>

四、接口交互关键点详解

4.1 请求参数传递方式

参数类型前端传递方式后端接收方式
url路径参数/users/123@pathvariable long id
url查询参数/users?name=john&age=20@requestparam string name
请求体json参数{name:"john",age:20}@requestbody userdto user
表单参数formdata对象@modelattribute userform form
请求头参数headers: {authorization: ...}@requestheader string token

4.2 跨域解决方案

spring boot 配置类

@configuration
public class corsconfig implements webmvcconfigurer {
    @override
    public void addcorsmappings(corsregistry registry) {
        registry.addmapping("/api/**")
                .allowedorigins("http://localhost:8080", "https://yourdomain.com")
                .allowedmethods("get", "post", "put", "delete", "options")
                .allowedheaders("*")
                .allowcredentials(true)
                .maxage(3600);
    }
}

4.3 文件上传处理

后端接收

@postmapping("/upload")
public responseentity<string> uploadfile(
        @requestparam("file") multipartfile file) {
    if (file.isempty()) {
        throw new businessexception("文件不能为空");
    }
    
    string filename = filestorageservice.storefile(file);
    return responseentity.ok(filename);
}

前端上传

// 使用formdata上传文件
const formdata = new formdata()
formdata.append('file', file)

uploadfile(formdata).then(response => {
  // 处理响应
})

五、接口安全增强

5.1 jwt认证实现

spring security配置

@configuration
@enablewebsecurity
public class securityconfig extends websecurityconfigureradapter {
    
    @override
    protected void configure(httpsecurity http) throws exception {
        http.csrf().disable()
            .authorizerequests()
                .antmatchers("/api/auth/**").permitall()
                .anyrequest().authenticated()
            .and()
            .addfilter(new jwtauthenticationfilter(authenticationmanager()))
            .addfilter(new jwtauthorizationfilter(authenticationmanager()))
            .sessionmanagement()
                .sessioncreationpolicy(sessioncreationpolicy.stateless);
    }
}

vue前端处理

// 登录示例
login({ username, password }).then(response => {
  const { token } = response.data
  commit('set_token', token)
  localstorage.setitem('token', token)
  // 设置axios默认携带token
  axios.defaults.headers.common['authorization'] = `bearer ${token}`
})

5.2 接口限流防护

@restcontroller
@requestmapping("/api/products")
public class productcontroller {
    
    @ratelimiter(value = 10, key = "'product_list'") // 10次/秒
    @getmapping
    public list<product> listproducts() {
        return productservice.findall();
    }
}

六、接口文档生成

6.1 swagger集成

spring boot配置

@configuration
@enableswagger2
public class swaggerconfig {
    @bean
    public docket api() {
        return new docket(documentationtype.swagger_2)
                .select()
                .apis(requesthandlerselectors.basepackage("com.example.controller"))
                .paths(pathselectors.any())
                .build()
                .apiinfo(apiinfo());
    }
    
    private apiinfo apiinfo() {
        return new apiinfobuilder()
                .title("电商系统api文档")
                .description("前后端接口定义")
                .version("1.0")
                .build();
    }
}

6.2 接口注释示例

@api(tags = "用户管理")
@restcontroller
@requestmapping("/api/users")
public class usercontroller {
    
    @apioperation("获取用户列表")
    @apiimplicitparams({
        @apiimplicitparam(name = "name", value = "用户名", paramtype = "query")
    })
    @getmapping
    public responseentity<list<userdto>> getusers(string name) {
        // ...
    }
}

七、性能优化建议

7.1 接口缓存策略

@cacheable(value = "users", key = "#id")
@getmapping("/{id}")
public userdto getuser(@pathvariable long id) {
    return userservice.getuserbyid(id);
}

7.2 分页查询优化

后端实现

@getmapping
public pageresult<userdto> getusers(
        @requestparam(defaultvalue = "1") int page,
        @requestparam(defaultvalue = "10") int size) {
    pageable pageable = pagerequest.of(page - 1, size);
    page<userdto> userpage = userservice.findusers(pageable);
    return new pageresult<>(userpage.getcontent(), userpage.gettotalelements());
}

前端调用

getusers({ page: this.currentpage, size: this.pagesize }).then(response => {
  this.userlist = response.data.list
  this.total = response.data.total
})

八、常见问题解决方案

8.1 日期时间处理

后端配置

# application.yml
spring:
  jackson:
    time-zone: gmt+8
    date-format: yyyy-mm-dd hh:mm:ss

前端处理

import moment from 'moment'

// 格式化日期
moment(user.createtime).format('yyyy-mm-dd hh:mm:ss')

8.2 大数字精度丢失

后端处理

@jsonserialize(using = tostringserializer.class)
private long id;

8.3 接口版本管理

@restcontroller
@requestmapping("/api/v1/users")
public class usercontrollerv1 {
    // v1版本接口
}

@restcontroller
@requestmapping("/api/v2/users")
public class usercontrollerv2 {
    // v2版本接口
}

通过以上方案,spring boot和vue可以实现高效、安全的前后端接口交互。实际开发中应根据项目需求选择合适的传参方式、安全策略和性能优化方案。

到此这篇关于springboot+vue 前后端接口交互的项目实践的文章就介绍到这了,更多相关springboot vue 前后端接口交互内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com