1. 程式人生 > >實現圖片上傳至OSS(阿里雲)

實現圖片上傳至OSS(阿里雲)

<------------------ Dto傳輸物件 --------------------->
package com.ksf.server.dto;
import com.ksf.server.consts.ResCode;
import com.wordnik.swagger.annotations.ApiModel;
import com.wordnik.swagger.annotations.ApiModelProperty;

/**
 * 描述: manager、web 端的請求引數 .
 * @author Idowww.
 * @date 2017/12/13
 */
@ApiModel
public class BaseRes<T> {

    @ApiModelProperty("請求結果編碼")
    private Integer code = ResCode.OK.getCode();

    @ApiModelProperty("請求結果描述")
    private String des = ResCode.OK.getDes();

    @ApiModelProperty("請求結果")
    private T response;

    public BaseRes<T> setRes(Integer code, String des) {
        this.setCode(code);
        this.setDes(des);
        return this;
    }
    public BaseRes<T> setRes(Integer code, String des,T response) {
        this.setCode(code);
        this.setDes(des);
        this.setResponse(response);
        return this;
    }
    public BaseRes<T> setCode(ResCode resCode) {
        this.code = resCode.getCode();
        this.des = resCode.getDes();
        return this;
    }
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getDes() {
        return des;
    }
    public void setDes(String des) {
        this.des = des;
    }
    public T getResponse() {
        return response;
    }
    public BaseRes<T> setResponse(T response) {
        this.response = response;
        return this;
    }
}

<-------------------- Controller Model層 ----------------------->
package com.ksf.server.controller.manager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ksf.server.consts.ResCode;
import com.ksf.server.dto.BaseRes;
import com.ksf.server.service.OssService;
import com.ksf.server.web.managermodulescheck.ModulesCheck;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;

@Controller
@RequestMapping("/manager/oss")
public class UploadImgToOssController {

@Autowired
private OssService ossService;

@ModulesCheck("actmanager")
@ApiOperation(value = "上傳圖片", notes = "上傳圖片", httpMethod = "POST")
@ResponseBody
@RequestMapping(value = "/uploadImg")
public BaseRes<String> uploadImg(@RequestParam @ApiParam("圖片") MultipartFile imgFile,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
BaseRes<String> res = new BaseRes<String>();
if (imgFile == null) {
return res.setRes(ResCode.ARGS_ERROR.getCode(), "請求引數不能為空");
}
String imgUrl = ossService.uploadImg(imgFile);
res.setResponse(imgUrl);
res.setCode(ResCode.OK.getCode());
res.setDes(ResCode.OK.getDes());
return res;
}
}


<--------------------  Service 業務層 ------------------>
package com.ksf.server.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.ksf.server.consts.BusinessCacheCode;
import com.ksf.server.consts.OSSFileDir;
import com.ksf.server.util.OssUtil;

@Service
public class OssService implements BusinessCacheCode {

@Autowired
private OssUtil ossUtil;

public String uploadImg(MultipartFile actImgFile) throws Exception {
      String filePath = ossUtil.uploadImg2Oss(OSSFileDir.ACT,actImgFile);
      return ossUtil.getPicRealmName() + filePath;
   }
}

<------------------------- Util工具類 ------------------------->
package com.ksf.server.util;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.ksf.server.consts.OSSFileDir;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

/**
 * @author Idowww.
 * @date 2017/05/18.
 */
@Component
public class OssUtil {

    private static final Logger LOG = LoggerFactory.getLogger(OssUtil.class);

    @Value("${oss.endpoint}")
    private String endpoint;
    @Value("${oss.accessKeyId}")
    private String accessKeyId;
    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;
    @Value("${oss.bucketName_yxym}")
    private String yxymBucketName;
    @Value("${oss.bucketName_yxym_public}")
    private String yxymBucketPublicName;

    @Value("${oss.picRealmName}")
    private String picRealmName;

    private volatile OSSClient ossClient;
    
    public String getPicRealmName() {
         return picRealmName;
    }
   public void setPicRealmName(String picRealmName) {
         this.picRealmName = picRealmName;
   }

  @PostConstruct
    public void init() {
        ClientConfiguration conf = new ClientConfiguration();
        conf.setProtocol(Protocol.HTTPS);
        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret, conf);
    }

    public String upload(MultipartFile file, String type, Date date) throws IOException {
        String originalFilename = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();
        return this.upload(inputStream, originalFilename, type, date);
    }

    public String upload(InputStream inputStream, String name, String type, Date date) throws IOException {
        // 修改名稱, 名稱加上毫秒數
        int pIdx = name.lastIndexOf(".");
        String preName = name.substring(0, pIdx);
        String subName = name.substring(pIdx).toLowerCase();
        name = preName + "_" + System.currentTimeMillis() + subName;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        SimpleDateFormat sdf2 = new SimpleDateFormat("dd");
        StringBuilder fn = new StringBuilder();
        fn.append(type).append("/").append(sdf.format(date)).append("/").append(sdf2.format(date))
                .append("/").append(name);

        String path = fn.toString();
        // TODO 這裡需要檢查md5的值
        uploadFile(inputStream, path);
        return path;
    }

    public String upload(InputStream inputStream, String type, Date date,String fileName) throws IOException {
        // 修改名稱, 名稱加上毫秒數
        String currentTimeMillis = "_"+System.currentTimeMillis();
        //pack/201707/26/20170726_0GJPW112_Z0GJPW1122017072600001_3000_1501077871359.zip
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        SimpleDateFormat sdf2 = new SimpleDateFormat("dd");
        StringBuilder fn = new StringBuilder();
        fn.append(type).append("/").append(sdf.format(date)).append("/").append(sdf2.format(date))
                .append("/").append(fileName).append(currentTimeMillis);

        String path = fn.toString();
        // TODO 這裡需要檢查md5的值
        uploadFile(inputStream, path);
        return path;
    }

    /**
     * 上傳到OSS伺服器 如果同名檔案會覆蓋伺服器上的
     * @param instream 檔案流
     * @param fileName 檔名稱 包括字尾名
     * @return 出錯返回"" ,唯一MD5數字簽名
     */
    private String uploadFile(InputStream instream, String fileName) throws IOException {
        // 小檔案上傳, 該值就是 md5 結果 .
        String ret = "";
        try {
            // 建立上傳Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
//          objectMetadata.setContentLength(instream.available()); // 這樣子獲取檔案大小不嚴謹
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
//           objectMetadata.setContentType(OSSClientUtil.getcontentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);

            // 上傳檔案
            PutObjectResult putResult = ossClient.putObject(yxymBucketName, fileName, instream, objectMetadata);
            ret = putResult.getETag();
        } finally {
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * 獲得臨時訪問url .
     * @param key
     * @return
     */
    public String getUrl(String key) {
        return getUrl(key, System.currentTimeMillis() + 1000l * 60 * 30);
    }

    /**
     * 獲得臨時訪問url .
     * @param key
     * @param expireAt
     * @return
     */
    public String getUrl(String key, Long expireAt) {
        URL url = ossClient.generatePresignedUrl(yxymBucketName, key, new Date(expireAt));
        if (url != null) {
            return url.toString();
        }
        return null;
    }

     /*----------------------------------OSSClientUtiles方法合併--------------------------------------------*/

    public String uploadImg2Oss(OSSFileDir ossFileDir, MultipartFile file) throws java.lang.Exception {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMM");
        String filedir = ossFileDir.getDir() + "/" + (sdf.format(new Date())) + "/";
        if (file.getSize() > 1024 * 1024) {
            throw new Exception("上傳圖片大小不能超過1M!");
        }
        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        Random random = new Random();
        String name = random.nextInt(10000) + System.currentTimeMillis() + substring;
        try {
            InputStream inputStream = file.getInputStream();
            this.uploadFile2OSS(filedir,inputStream, name);
            return filedir + name;
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("圖片上傳失敗");
        }
    }

    /**
     * 上傳到OSS伺服器 如果同名檔案會覆蓋伺服器上的 
     * @param instream 檔案流
     * @param fileName  檔名稱 包括字尾名
     * @return 出錯返回"" ,唯一MD5數字簽名
     */
    public String uploadFile2OSS(String filedir,InputStream instream, String fileName) {
        String ret = "";
        try {
            // 建立上傳Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setContentLength(instream.available());
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
            objectMetadata.setContentDisposition("inline;filename=" + fileName);
            // 上傳檔案
            PutObjectResult putResult = ossClient.putObject(yxymBucketPublicName, filedir + fileName, instream, objectMetadata);
            ret = putResult.getETag();
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
        } finally {
            try {
                if (instream != null) {
                    instream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * Description: 判斷OSS服務檔案上傳時檔案的contentType 
     * @param FilenameExtension   檔案字尾
     * @return String
     */
    public static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase("bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase("gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase("jpeg") || FilenameExtension.equalsIgnoreCase("jpg")
                || FilenameExtension.equalsIgnoreCase("png")) {
            return "image/jpeg";
        }
        if (FilenameExtension.equalsIgnoreCase("html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase("txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase("vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase("pptx") || FilenameExtension.equalsIgnoreCase("ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase("docx") || FilenameExtension.equalsIgnoreCase("doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase("xml")) {
            return "text/xml";
        }
        return "image/jpeg";
    }

}