Springboot 集成阿里短信 ClassNotFound的坑

本文讲述了在Springboot项目中集成阿里短信服务时遇到的ClassNotFound异常。问题出现在IDEA环境下运行正常,但在服务器上部署后出现异常。通过查看IDEA的依赖和打包后的Jar包确认GSON包已存在。为解决问题,作者参照网上的建议,显式在POM文件中添加GSON依赖,以此规避Springboot的潜在bug,最终解决了问题。

问题描述

使用Springboot 在IDEA开发中正常,在服务器上报ClassNotFound。

问题定位

后台报错误日志如下

017-08-08 17:59:46.527 ERROR 22612 --- [nio-8083-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: com/go
### Spring Boot 集成阿里云 OSS 实现文件操作 #### 1. 添加依赖项 为了使 Spring Boot 应用程序能够与阿里云 OSS 进行交互,需在 `pom.xml` 中引入相应的 Maven 依赖。 ```xml <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency> ``` 此部分确保应用程序可以调用阿里云 SDK 提供的方法来处理对象存储服务中的资源[^1]。 #### 2. 修改配置文件 编辑项目的 application.yml 或者 application.properties 文件,在其中加入如下所示的 Aliyun OSS 参数设置: ```yaml aliyun: oss: endpoint: https://oss-cn-beijing.aliyuncs.com # 更改为实际使用的区域地址 accessKeyId: LTAI4GJr... # 用户自己的 Access Key ID accessKeySecret: ... # 用户自己的 Secret bucketName: my-bucket-name # 存储空间名称 ``` 这些参数用于建立客户端连接并验证身份认证信息,从而允许应用访问指定的 Bucket 资源[^4]。 #### 3. 编写工具类 创建名为 `OssUtil.java` 的 Java 类作为辅助函数集合,以便简化对 OSS API 的调用过程。以下是该类的部分实现代码片段: ```java package com.example.demo.utils; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class OssUtil { private final String endpoint; private final String accessKeyId; private final String accessKeySecret; private final String bucketName; public OssUtil(@Value("${aliyun.oss.endpoint}") String endpoint, @Value("${aliyun.oss.accessKeyId}") String accessKeyId, @Value("${aliyun.oss.accessKeySecret}") String accessKeySecret, @Value("${aliyun.oss.bucketName}") String bucketName) { this.endpoint = endpoint; this.accessKeyId = accessKeyId; this.accessKeySecret = accessKeySecret; this.bucketName = bucketName; } /** * 获取OSS实例 */ protected OSS getOssClient() { return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); } } ``` 此类封装了获取 OSS 客户端实例的功能,并通过构造器注入的方式读取配置属性值。 #### 4. 开发控制器接口 定义 RESTful Web Service 接口以支持前端发起请求完成具体的业务逻辑操作。下面是一个简单的例子展示如何构建这样的 Controller 层组件: ```java package com.example.demo.controller; import com.example.demo.utils.OssUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.IOException; @Slf4j @RestController @RequestMapping("/api/oss") public class FileController { @Resource private OssUtil ossUtil; /** * 文件上传至OSS服务器 * * @param file 待上传文件 * @return 返回JSON格式的结果集 */ @PostMapping("/upload") public ResponseEntity<String> uploadFile(@RequestParam MultipartFile file) throws IOException { try (final var client = ossUtil.getOssClient()) { // 将文件流保存到目标路径下 client.putObject(ossUtil.getBucketName(), "test/" + file.getOriginalFilename(), file.getInputStream()); log.info("Upload success."); return ResponseEntity.ok("{\"status\":\"success\"}"); } catch (Exception e) { log.error(e.getMessage(), e); throw new RuntimeException("Failed to upload file.", e); } } /** * 下载文件从OSS服务器 * * @param fileName 文件名 * @return 响应实体含二进制数据 */ @GetMapping("/download/{fileName}") public byte[] downloadFile(@PathVariable String fileName) { try (var client = ossUtil.getOssClient(); var inputStream = client.getObject(ossUtil.getBucketName(), "test/" + fileName).getObjectContent()) { return inputStream.readAllBytes(); } catch (IOException | RuntimeException ex) { log.warn(ex.getMessage()); throw new IllegalArgumentException("Could not find the specified object", ex); } } /** * 删除单个文件 * * @param fileName 文件名 * @return 成功与否的状态码 */ @DeleteMapping("/{fileName}") public ResponseEntity<Void> deleteFile(@PathVariable String fileName) { try (var client = ossUtil.getOssClient()) { boolean exists = client.doesObjectExist(ossUtil.getBucketName(), "test/" + fileName); if (!exists) { return ResponseEntity.notFound().build(); } client.deleteObject(ossUtil.getBucketName(), "test/" + fileName); return ResponseEntity.noContent().build(); } } /** * 列举当前目录下的所有文件列表 * * @return JSON字符串形式的对象数组 */ @GetMapping("/list") public List<OSSObjectSummary> listFiles() { try (var client = ossUtil.getOssClient()) { ObjectListing listing = client.listObjects(new ListObjectsRequest(ossUtil.getBucketName()).withPrefix("test/")); return listing.getObjectSummaries(); } } } ``` 上述代码实现了四个主要的操作方法:上传、下载、删除以及列举特定前缀下的全部条目。每个 HTTP 请求都会触发相应的行为并与远程 OSS 服务进行通信[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值