在客户的环境中出现了文件上传失败的问题【开发环境是没有问题的】,受一些因素,这边是通过远程查看日志去解决的问题。
一、查看项目日志,定位bug问题
通过查看log文件,首先定位到异常方法的执行行:
以及请求的结果
还有查看OBS服务请求参数和结果
二、通过项目代码比对,定位
HweiYunOBSServiceImpl.fileUpload方法中第60行
PutObjectRequest request = new PutObjectRequest();
request.setBucketName(bucketName);
request.setObjectKey(objectKey);
request.setInput(uploadFile.getInputStream());
// 设置对象访问权限为公共读
request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
60行 PutObjectResult result = obsClient.putObject(request);
结合代码分析bug原因:发现报的错误来自OBS服务内部,这时查看OBS调用请求返回的参数,发现了411的错误code【只是可能解决问题的第一种尝试】
三、解决bug
1、首先了解OBS服务411原因
这里去华为云官网搜索了下,发现了可能解决问题的方法:
OBS服务端错误码_对象存储服务 OBS_SDK参考_Node.js_异常处理_华为云 (huaweicloud.com)
2、搜索OBS调用添加Content-Length的方法
通过代码的比对,猜测与PutObjectResult类有关,直接尝试
java PutObjectRequest 设置 Content-Length_百度搜索 (baidu.com)
浏览到适合的有用资源:
Java PutObjectRequest类代码示例 - 纯净天空 (vimsky.com)
3、修改代码
这里发现该OBS服务版本不一致,所以不能完全按照第2步搜到的资源进行修改【但主要思路有了】,需要结合版本进行修改,我当前使用的OBS版本为 esdk-obs-2.20.6.1.jar,PutObjectRequest构造函数只有三个参数
不要紧,我们在当前类下搜索 ObjectMetadata ,发现存在一个写入ObjectMetadata 的方法:
这时更改我们的代码
InputStream inputStream = uploadFile.getInputStream();
long contentLength = inputStream.available();//获取InputStream长度
PutObjectRequest request = new PutObjectRequest(bucketName,objectKey,inputStream);
// 解决上传图片请求OBS服务报411异常【必须要提供HTTP消息头中的Content-Length字段。】
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(contentLength);
request.setMetadata(objectMetadata);
// 设置对象访问权限为公共读
request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
PutObjectResult result = obsClient.putObject(request);
4、打包部署,验证结果
这边发现文件已经可以正常上传,即关闭bug