Spring Boot + Vue 前后端接口交互全流程详解_springboot和vue前后端交互
一、前后端交互架构概览
二、Spring Boot 后端接口实现
2.1 基础REST控制器
@RestController@RequestMapping(\"/api/users\")@CrossOrigin // 处理跨域,生产环境应配置具体域名public class UserController { @Autowired private UserService userService; // 获取用户列表 @GetMapping public ResponseEntity<List> getUsers( @RequestParam(required = false) String name) { List users = userService.findUsers(name); return ResponseEntity.ok(users); } // 获取单个用户 @GetMapping(\"/{id}\") public ResponseEntity getUser(@PathVariable Long id) { UserDTO user = userService.getUserById(id); return ResponseEntity.ok(user); } // 创建用户 @PostMapping public ResponseEntity createUser( @Valid @RequestBody UserCreateRequest request) { UserDTO newUser = userService.createUser(request); return ResponseEntity.status(HttpStatus.CREATED).body(newUser); } // 更新用户 @PutMapping(\"/{id}\") public ResponseEntity updateUser( @PathVariable Long id, @Valid @RequestBody UserUpdateRequest request) { UserDTO updatedUser = userService.updateUser(id, request); return ResponseEntity.ok(updatedUser); } // 删除用户 @DeleteMapping(\"/{id}\") public ResponseEntity deleteUser(@PathVariable Long id) { userService.deleteUser(id); return ResponseEntity.noContent().build(); }}
2.2 DTO设计示例
用户创建请求DTO:
@Datapublic 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 全局异常处理
@RestControllerAdvicepublic class GlobalExceptionHandler { // 处理验证异常 @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity handleValidationException( MethodArgumentNotValidException ex) { List 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 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.jsimport 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.jsimport 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组件中调用示例
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) } } }) } }}
四、接口交互关键点详解
4.1 请求参数传递方式
/users/123
@PathVariable Long id
/users?name=John&age=20
@RequestParam String name
{name:\"John\",age:20}
@RequestBody UserDTO user
FormData
对象@ModelAttribute UserForm form
headers: {Authorization: ...}
@RequestHeader String token
4.2 跨域解决方案
Spring Boot 配置类:
@Configurationpublic 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 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@EnableWebSecuritypublic 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 listProducts() { return productService.findAll(); }}
六、接口文档生成
6.1 Swagger集成
Spring Boot配置:
@Configuration@EnableSwagger2public 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> getUsers(String name) { // ... }}
七、性能优化建议
7.1 接口缓存策略
@Cacheable(value = \"users\", key = \"#id\")@GetMapping(\"/{id}\")public UserDTO getUser(@PathVariable Long id) { return userService.getUserById(id);}
7.2 分页查询优化
后端实现:
@GetMappingpublic PageResult getUsers( @RequestParam(defaultValue = \"1\") int page, @RequestParam(defaultValue = \"10\") int size) { Pageable pageable = PageRequest.of(page - 1, size); Page 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.ymlspring: 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可以实现高效、安全的前后端接口交互。实际开发中应根据项目需求选择合适的传参方式、安全策略和性能优化方案。