华为云OBS文件服务

华为云OBS文件服务

准备工作

先获取OBS的SK,AK,终端节点。然后创建桶
将以上四个值存放在Nacos中

	/**
     * 取值为所创建的桶名
     */
    @Value("${obs.bucketName}")
    private String bucketName;

    /**
     * 取值为获取的AK
     */
    @Value("${obs.accessKey}")
    private String accessKey;

    /**
     * 取值为获取的SK
     */
    @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 Map<String, String> 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<String, String> 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;
    }

OBS下载服务

下载主题类

此处还需要改进。下载的文件名如果是带有中文,文件名会乱码。目前测试过很多转码,解码方式。均未成功。

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

	/**
     * 从obs下载文件
     * @param httpClient 连接
     * @param sysFile 文件实体
     * @return 文件流
     */
    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类型列表

你可能感兴趣的:(笔记,华为,java)