背景
1. 我们应用服务是Spring boot项目,预览服务是我们另一个团队提供的用.net写的,最终使用的是office online来实现文件预览的功能。
2. 我们文件在阿里云OSS存储,我们需要预览文件需要将文件上传至预览服务器。
3. 计划使用RestTemplate将文件上传到OOS(Office Online Server)。
之前没有写过这种用流的方式进行上传,查询方法之后,一般两种方式:
1. 先下载到本地,然后本地再上传到OOS上(占存储,并且还需要上传完清理掉)
2. 直接使用流的方式,从OSS拿到流之后直接上传到OOS上(推荐)
开干
- RestTemplate使用配置
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplateBuilder builder = new RestTemplateBuilder();
return builder.build();
}
}
- 使用阿里云提供的OSS Java SDK
贴上阿里云文档的SDK截图
最重要的就是这句:
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
可以看到 阿里云OSS getObject 得到的是一个 OSSObject对象,我们看看他的源码
OSSObject.java
public class OSSObject extends GenericResult implements Closeable {
private String key;
private String bucketName;
private ObjectMetadata metadata = new ObjectMetadata();
private InputStream objectContent;
public OSSObject() {
}
public ObjectMetadata getObjectMetadata() {
return this.metadata;
}
public void setObjectMetadata(ObjectMetadata metadata) {
this.metadata = metadata;
}
public InputStream getObjectContent() {
return this.objectContent;
}
......
}
这里面的 objectContent其实就是我们需要的InputStream
搞清楚这个之后我们就要进行下一步了,将流上传到我们的预览服务器。
直接上代码,这里主要是使用RestTemplate的postForEntity方法上传文件到OOS。
// 获取OSS文件
ossObject = ossService.getOssObject(file.getPath());
InputStream fileInputStream = ossObject.getObjectContent();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
Long fileSize = ossObject.getObjectMetadata().getContentLength();
InputStreamResource resource = new InputStreamResource(fileInputStream) {
@Override
public String getFilename() {
return file.getName();
}
@Override
public long contentLength() {
return fileSize;
}
};
body.add("FileContent", resource);
HttpEntity<Object> httpEntity = new HttpEntity<>(body, headers);
registerRes = restTemplate.postForEntity("oos接口url", httpEntity, "接受类Class").getBody();
ossObject.close();
如上代码我使用的是InputStreamResource接受到OSS给到的InputStream流,重写了getFilename()方法,和contentLength()方法
注意:如果使用InputStreamResource,这俩方法必须得重写!!
至此,就上传成功了。。
这种方式不仅适用于OSS文件下载,也适用于用户上传一个文件上传之后,你的服务需要上传到另一个服务器,不用在你的服务器留存,直接使用流上传即可。