先获取OBS的SK,AK,终端节点。然后创建桶
将以上四个值存放在Nacos中
@Value("${obs.bucketName}")
private String bucketName;
@Value("${obs.accessKey}")
private String accessKey;
@Value("${obs.secretKey}")
private String securityKey;
@Value("${obs.endpoint}")
private String endpoint;
然后加入两个工具类
public class Signature {
public static String signWithHmacSha1(String sk, String canonicalString) throws UnsupportedEncodingException {
try {
SecretKeySpec signingKey = new SecretKeySpec(sk.getBytes("UTF-8"), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
return base64.getEncoder().encodeToString(mac.doFinal(canonicalString.getBytes("UTF-8")));
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
public class DateUtils {
public static String formatDate(long time)
{
DateFormat serverDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
serverDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
return serverDateFormat.format(time);
}
}
OBS上传服务
当上传的文件名带有中文时,需要对文件名进行转码处理。否则会导致长度过长或者其他原因上传出错。
public MapOBS下载服务 下载主题类putObjectToBucket(MultipartFile file) { // 获取文件名 String originalFilename = null; try { originalFilename = URLEncoder.encode(Objects.requireNonNull(file.getOriginalFilename()),"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // 处理文件名 String fileName = originalFilename != null ? originalFilename.substring(0, originalFilename.lastIndexOf(46)) + "_" + System.currentTimeMillis() + originalFilename.substring(originalFilename.lastIndexOf(46)) : null; CloseableHttpClient httpClient = HttpClients.createDefault(); String requestTime = DateUtils.formatDate(System.currentTimeMillis()); HttpPut httpPut = new HttpPut(endpoint + "/" + fileName); httpPut.addHeader("Date", requestTime); //根据请求计算签名 String contentMD5 = ""; String contentType = ""; String canonicalizeHeaders = ""; String canonicalizeResource = "/" + bucketName + "/" + fileName; // Content-MD5 、Content-Type 没有直接换行, data格式为RFC 1123,和请求中的时间一致 String canonicalString = "PUT" + "n" + contentMD5 + "n" + contentType + "n" + requestTime + "n" + canonicalizeHeaders + canonicalizeResource; System.out.println("StringToSign:[" + canonicalString + "]"); try { InputStream inputStream = file.getInputStream(); String signature = Signature.signWithHmacSha1(securityKey, canonicalString); // 上传的文件 InputStreamEntity entity = new InputStreamEntity(inputStream); httpPut.setEntity(entity); // 增加签名头域 Authorization: OBS AccessKeyID:signature httpPut.addHeader("Authorization", "OBS " + accessKey + ":" + signature); CloseableHttpResponse httpResponse = httpClient.execute(httpPut); // 打印发送请求信息 System.out.println("Request Message:"); System.out.println(httpPut.getRequestLine()); for (Header header : httpPut.getAllHeaders()) { System.out.println(header.getName() + ":" + header.getValue()); } System.out.println(httpResponse.getStatusLine().getStatusCode()); // 判断响应结果是否成功,此处返回文件在OBS中存储的路径及经过处理之后的文件名用来存入库 if (httpResponse.getStatusLine().getStatusCode() == 200) { Map map = new HashMap<>(); if (fileName != null){ map.put("fileName", URLDecoder.decode(fileName,"utf-8")); map.put("path",endpoint + "/" + fileName); return map; } return null; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } return null; }
此处还需要改进。下载的文件名如果是带有中文,文件名会乱码。目前测试过很多转码,解码方式。均未成功。
public void download(@RequestParam("fileId")String fileId, HttpServletRequest request, HttpServletResponse response) {
try {
CloseableHttpClient httpClient = HttpClients.createDefault();
SysFile sysFile = mapper.getPathAndFileName(fileId);
if (sysFile == null){
return;
}
String fileName = sysFile.getFileName();
HttpResponse httpResponse = utils.fileDownload(httpClient, sysFile);
InputStream inputStream = httpResponse.getEntity().getContent();
// 缓冲文件输出流
BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
// 为防止 文件名出现乱码
final String userAgent = request.getHeader("USER-AGENT");
// IE浏览器
if (StringUtils.contains(userAgent, "MSIE")) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
// google,火狐浏览器
if (StringUtils.contains(userAgent, "Mozilla")) {
fileName = new String(fileName.getBytes(), "ISO8859-1");
} else {
// 其他浏览器
fileName = URLEncoder.encode(fileName, "UTF-8");
}
}
response.setContentType("application/x-download");
// 设置让浏览器弹出下载提示框,而不是直接在浏览器中打开
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
IOUtils.copy(inputStream, outputStream);
outputStream.flush();
inputStream.close();
outputStream.close();
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
下载工具类
下载其实就是将上传到额httpPut请求改成httpGet
public CloseableHttpResponse fileDownload(CloseableHttpClient httpClient,SysFile sysFile) {
String requestTime = DateUtils.formatDate(System.currentTimeMillis());
HttpGet httpGet = new HttpGet(sysFile.getPath());
httpGet.addHeader("Date", requestTime);
// 根据请求计算签名
String contentMD5 = "";
String contentType = "";
String canonicalizeHeaders = "";
String canonicalizeResource = null;
try {
canonicalizeResource = "/" + bucketName + "/" + URLEncoder.encode(sysFile.getFileName(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// Content-MD5 、Content-Type 没有直接换行, data格式为RFC 1123,和请求中的时间一致
String canonicalString = "GET" + "n" + contentMD5 + "n" + contentType + "n" + requestTime + "n" + canonicalizeHeaders + canonicalizeResource;
System.out.println("StringToSign:[" + canonicalString + "]");
try {
String signature = Signature.signWithHmacSha1(securityKey, canonicalString);
httpGet.setHeader("Authorization", "OBS " + accessKey + ":" + signature);
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
// 打印发送请求信息和收到的响应消息
System.out.println("Request Message:");
System.out.println(httpGet.getRequestLine());
for (Header header : httpGet.getAllHeaders()) {
System.out.println(header.getName() + ":" + header.getValue());
}
System.out.println("Response Message:");
System.out.println(httpResponse.getStatusLine());
for (Header header : httpResponse.getAllHeaders()) {
System.out.println(header.getName() + ":" + header.getValue());
}
return httpResponse;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
此处放一个常见下载格式的链接
常见MIME类型列表



