[빠른 시작 시리즈] Qiniu Cloud + webuploader를 사용하여 객체 클라우드 스토리지(OSS) 실현

[빠른 시작 시리즈] Qiniu Cloud + webuploader를 사용하여 객체 클라우드 스토리지(OSS) 실현

단계

1. Qiniu 클라우드 구성

1. 새로운 저장 공간 생성

Qiniu Cloud에 들어가 등록 및 로그인하고 콘솔에 들어가 개체 저장소 Kodo를 선택합니다.

공간 관리 선택 - 새 공간 만들기(30일 동안 무료)

사진 설명을 추가해주세요

작성 후 확인 클릭

사진 설명을 추가해주세요

2. AccessKey 및 SecretKey 얻기

오른쪽 상단 모서리에서 계정을 클릭하고 키 관리를 클릭합니다.

사진 설명을 추가해주세요

나만의 ak와 sk를 볼 수 있고, 저장하세요.

사진 설명을 추가해주세요

또한 자신의 공간 이름과 도메인 이름도 저장해야 합니다(도메인 이름에는 만료 시간이 있습니다).

도메인 이름은 그림과 같습니다.

사진 설명을 추가해주세요

둘째, webuploader 구성 요소를 사용하십시오.

1. 다운로드

webuploader 공식 웹사이트에서 구성 요소 다운로드: http://fex.baidu.com/webuploader/

최신버전을 다운받으시면 됩니다

사진 설명을 추가해주세요

2. 사용: 두 가지 방법

프로젝트 구조: 다운로드한 webuploader 구성 요소를 아래와 같이 넣습니다(및 jquery).

사진 설명을 추가해주세요

전후단이 분리되지 않는 방식과 전후단이 분리되는 방식으로 나뉘는데, 두 방식에 대해서는 뒤에서 자세히 설명한다.

다음으로 백엔드 테스트를 먼저 수행하십시오.

먼저 index.html 코드를 작성합니다(경로가 변경됨).

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>webuploader上传</title>
	<script type="text/javascript" src="js/jquery-3.6.0.js" charset="UTF-8"></script>
	<!--引入WebUploader文件上传的CSS-->
	<link rel="stylesheet" type="text/css" href="css/webuploader.css" media="screen" />	
	<!--引入WebUploader文件上传的JS-->
	<script type="text/javascript" src="js/webuploader.js"></script>
	
	</head>
	<body>
		<!--用来存放文件信息-->
		<div class="uploader-demo">
		    <!--存放图片的预览图-->
		    <div id="imgs" style="border: 1px solid black;width: 460px;height: 150px;margin-bottom: 10px;padding: 10px;overflow:scroll;
					 white-space: nowrap;">
		       <!-- <img src="xxx" style="width: 100px;height: 130px;margin-right: 10px"/>-->
		    </div>
		    <div class="btns">
		    	<input type="hidden" id="imgs_path" name="gimage"/>
		        <div id="filePicker">选择图片</div>
		        <button id="ctlBtn" class="mybutton" onclick="upload_imgs()">开始上传</button>
				<marquee id="msrcoll" width="235px" direction="right" style="display:none">
					图片正在上传,请稍作等待...
				</marquee>
			</div>

		</div>

	</body>

<!-- js代码 -->
<script type="text/javascript">
    var uploader;
    $(function(){
      
      
        //初始化Web Uploader,每上传一个文件都会创建一个uploader对象,同时选择多个文件时,则会创建多个uploader对象。
        uploader = WebUploader.create({
      
      
            // 选完文件后,是否自动上传。
            auto: false,     //true时,选择文件后自动上传。
            // swf文件路径
            swf: 'js/Uploader.swf',
            // 文件接收服务端。
            server: '/这里是访问你后端controller层的路径',
            // 选择文件的按钮。可选。
            pick: '#filePicker',
            // 只允许选择图片文件。
            accept: {
      
      
                title: 'Images',
                extensions: 'gif,jpg,jpeg,bmp,png',
                mimeTypes: 'image/*'
            }
        });
        
        //给webuploader绑定事件    fileQueued 当文件被加入队列后触发。  file参数表示当前文件对象
        uploader.on('fileQueued',function (file) {
      
      
            //生成图片的缩略图   ret表示缩略图的路径
            //makeThumb( file, callback, width, height ) 
            uploader.makeThumb(file,function (error, ret ) {
      
      
                if (error){
      
      
                    alert(file.name+"缩略图生成失败!");
                } else{
      
      
                    //将缩略图放入div容器中
                    var img="<img src=\""+ret+"\" style=\"width: 100px;height: 130px;margin-right: 10px\"/>";
                    $("#imgs").append(img);
                }
            }, 100, 130)
        });
        
         //给webuploader绑定上传成功事件
        uploader.on("uploadSuccess",function (file,response) {
      
      
            var value= $("#imgs_path").val();
            if(value.length>0){
      
      
                value+="|";
            }
            value+=response.uploadPath;
            $("#imgs_path").val(value);
			if (response.status == 1 && value.length>0) {
      
      
				alert("上传成功")
				$("#msrcoll").css("display","none");
			} else {
      
      
				alert("上传失败")
				$("#msrcoll").css("display","none");
			}
        });
    })

    //上传图片
    function upload_imgs() {
      
      
        if (uploader){
      
      
            uploader.upload();
			$("#msrcoll").css("display","block");
        }
    }
</script>

</html>

완료 후 이 페이지는 다음과 같습니다.

사진 설명을 추가해주세요

백엔드 코드
백엔드 테스트 수행

백엔드 프로젝트에 필요한 Maven 종속성:

pom.xml

<!--七牛云-->
<!-- https://mvnrepository.com/artifact/com.qiniu/qiniu-java-sdk -->
<dependency>
    <groupId>com.qiniu</groupId>
    <artifactId>qiniu-java-sdk</artifactId>
    <version>7.11.0</version>
</dependency>

<!--七牛云的上传工具类-->
<!--OKHTTP-->
<!--        <dependency>-->
<!--            <groupId>com.squareup.okhttp3</groupId>-->
<!--            <artifactId>okhttp</artifactId>-->
<!--            <version>3.6.0</version>-->
<!--        </dependency>-->

<!--上传-->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.11.0</version>
</dependency>

<dependency>
    <groupId>com.qiniu</groupId>
    <artifactId>happy-dns-java</artifactId>
    <version>0.1.6</version>
    <scope>test</scope>
</dependency>

<!--解析json-->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.5</version>
    <scope>compile</scope>
</dependency>

<!--springboot-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>


<!--如果只是测试,不连数据库下面的不用导-->
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.0</version>
</dependency>
<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

프로젝트 구조(프런트엔드와 백엔드가 분리된 웹앱 없음)

사진 설명을 추가해주세요

QiniuCloud 도구 클래스 QiniuCloudUtil.java

팁: 위에 저장된 네 가지 매개변수를 해당 XXXXXXXXXX에 넣습니다.

package com.example.util;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;


/**
 * 七牛云上传文件工具类
 * 官方
 */
public class QiniuCloudUtil {
    
    

    // 设置需要操作的账号的AK和SK					(AK和SK均在七牛云中获得,以下会说明)
    private static final String ACCESS_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    private static final String SECRET_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

    // 要上传的空间								(刚刚新建空间的名称)
    private static final String bucketname = "XXXXXXXXXXXXXXXXXXXXXX";

    // 密钥
    private static final Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);

    //地区分布实例化
    private static final Configuration cfg = new Configuration(Region.huadongZheJiang2());

    //新建空间时,七牛云分配出的域名 (自己可在万网购买域名解析后,绑定到加速域名)
    private static final String DOMAIN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

    public static String getUpToken() {
    
    
        //如果希望只能上传指定key的文件,并且不允许修改,那么可以将下面的 insertOnly 属性值设为 1。
        return auth.uploadToken(bucketname, null, 3600, new StringMap().put("insertOnly", 1));
    }

    /**
     * 上传文件使用
     *
     * @return
     */
    public static UploadManager init() {
    
    
        //构造一个带指定 Region 对象的配置类

        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
        UploadManager uploadManager = new UploadManager(cfg);
        return uploadManager;
    }

    /**
     * 本地上传
     */
    public static void addLocalImage() {
    
    


        //如果是Windows情况下,格式是 D:\\qiniu\\test.png
        String localFilePath = "E:\\imgs\\logo1.jpg";
        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = null;

        Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
        String upToken = auth.uploadToken(bucketname);

        try {
    
    
            UploadManager uploadManager = init();
            Response response = uploadManager.put(localFilePath, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
        } catch (QiniuException ex) {
    
    
            Response r = ex.response;
            System.err.println(r.toString());
            try {
    
    
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
    
    
                //ignore
            }
        }

    }

    /**
     * 通过字节数组传播
     */
    public static DefaultPutRet addByBytesImage(byte[] bytes) {
    
    

        DefaultPutRet putRet = null;
        try {
    
    
//            byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
            Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
            String upToken = auth.uploadToken(bucketname);

            //默认不指定key的情况下,以文件内容的hash值作为文件名
            String key = null;
            UploadManager uploadManager = init();
            try {
    
    
                Response response = uploadManager.put(bytes, key, upToken);
                //解析上传成功的结果
                putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
                return putRet;

            } catch (QiniuException ex) {
    
    
                Response r = ex.response;
                System.err.println(r.toString());
                try {
    
    
                    System.err.println(r.bodyString());
                } catch (QiniuException ex2) {
    
    
                    //ignore
                }
            }
        } catch (Exception e) {
    
    
            //ignore
        }
        return putRet;
    }


    /**
     * @param key 图片的文件名
     * @Explain 删除空间中的图片
     */
    public static void delete(String key) {
    
    
        BucketManager bucketManager = new BucketManager(auth, cfg);
        try {
    
    
            bucketManager.delete(bucketname, key);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    /**
     * 查找指定文件信息
     *
     * @param key
     * @return
     */
    public static FileInfo getFile(String key) {
    
    
        BucketManager bucketManager = new BucketManager(auth, cfg);
        FileInfo fileInfo = null;
        try {
    
    
            fileInfo = bucketManager.stat(bucketname, key);

        } catch (QiniuException ex) {
    
    
            System.err.println(ex.response.toString());
        }
        return fileInfo;
    }

    /**
     * 查找所有文件信息
     *
     * @param
     * @return
     */
    public static BucketManager.FileListIterator getAllFile() {
    
    
        //文件名前缀
        String prefix = "";
        //每次迭代的长度限制,最大1000,推荐值 1000
        int limit = 1000;
        //指定目录分隔符,列出所有公共前缀(模拟列出目录效果)。缺省值为空字符串
        String delimiter = "";
        BucketManager bucketManager = new BucketManager(auth, cfg);
        //列举空间文件列表
        BucketManager.FileListIterator fileListIterator = bucketManager.createFileListIterator(bucketname, prefix, limit, delimiter);
        return fileListIterator;
    }

    /**
     * 下载
     * fileName 七牛云上存储文件生成的文件名
     * @throws IOException
     */
    public static List<String> download(String fileName[]) throws IOException {
    
    
        List<String> list=new ArrayList<>();
        for (int i = 0; i < fileName.length; i++) {
    
    
            String encodedFileName = URLEncoder.encode(fileName[i], "utf-8").replace("+", "%20");
            String finalUrl = String.format("%s/%s", DOMAIN, encodedFileName);
            list.add(finalUrl);
        }
        return list;
    }

}

테스트 클래스 Test01.java(4개의 매개변수 작성 및 이미지 경로 추가)

package com.example.Test;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;

public class Test01 {
    
    

    public static void main(String[] args) {
    
    
        //构造一个带指定Region对象的配置类
        Configuration cfg = new Configuration(Region.huadongZheJiang2());
        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证,然后准备上传
        String accessKey = "XXXXXXXXXXXXXXXXXXXXX";
        String secretKey = "XXXXXXXXXXXXXXXXXXXXXXXXX";
        //空间名称
        String bucket = "XXXXX";
//如果是Windows情况下,格式是 D:\\qiniu\\test.png
        String localFilePath = "e:\\11.jpg";
//默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = null;
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);


        try {
    
    
            Response response = uploadManager.put(localFilePath, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
        } catch (QiniuException ex) {
    
    
            Response r = ex.response;
            System.err.println(r.toString());
            try {
    
    
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
    
    
                //ignore
            }
        }

    }

}

실행하면 콘솔에서 다음과 같이 키와 해시 값(즉, Qiniu Cloud에서 볼 수 있는 업로드된 파일 이름)을 반환하는 것을 확인할 수 있습니다.

사진 설명을 추가해주세요

그런 다음 Qiniuyun으로 돌아가서 생성한 공간 파일을 확인하면 파일이 업로드된 것을 확인할 수 있습니다.

사진 설명을 추가해주세요

그래서 효과가 있었다

webuploader를 사용하여 파일 업로드

컨트롤러 계층

WebController.java 클래스

package com.example.Controller;


import com.example.util.QiniuCloudUtil;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

@RestController
public class WebController {
    
    

//    @Autowired
//    private QiNiuService qiNiuService;

    /**
     * 上传图片的方法
     * @param files
     * @return
     * @throws IOException
     */
    @PostMapping("/addResource")
    public Map<String, Object> test(@RequestParam(name = "file", required = true) MultipartFile[] files) throws IOException {
    
    
        Map<String, Object> map = new HashMap<>();
        byte b[] = new byte[1024];
        for (MultipartFile file : files) {
    
    
            byte[] bytes = file.getBytes();
            DefaultPutRet putRet = QiniuCloudUtil.addByBytesImage(bytes);
            if (putRet != null) {
    
    

//                //向数据库中添加信息
//                QiNiu qn = new QingNiu();
                  String key = putRet.key;
                  String hash = putRet.hash;
//                qn.setId(key);
//                qn.setCodeid(hash);
//                qiNiuService.save(qn);

                System.out.println("key:" + key);
                System.out.println("hash:" + hash);

            } else {
    
    
                System.out.println("上传失败");
                map.put("status",0);
                return map;

            }

        }
        System.out.println("上传成功");
        map.put("status",1);
        return map;
    }

    @PostMapping ("/delResource")
    public void delect(){
    
    
        QiniuCloudUtil.delete("xxxxxxxxxxxxxxxxxxxx");
    }


    @GetMapping("/getResource")
    public void getFile(){
    
    
        FileInfo file = QiniuCloudUtil.getFile("xxxxxxxxxxxxxxxxxxxxx");
        System.out.println(file.hash);
        System.out.println(file.fsize);
        System.out.println(file.mimeType);
        System.out.println(file.putTime);
    }

    @GetMapping("/getAllResource")
    public void getAllFile(){
    
    
        BucketManager.FileListIterator fileListIterator = QiniuCloudUtil.getAllFile();
        while (fileListIterator.hasNext()) {
    
    

            //处理获取的file list结果
            FileInfo[] items = fileListIterator.next();
            for (FileInfo item : items) {
    
    
                System.out.println("=========================");
                System.out.println(item.key);
                System.out.println(item.hash);
                System.out.println(item.fsize);
                System.out.println(item.mimeType);
                System.out.println(item.putTime);
                System.out.println(item.endUser);
            }
        }
    }

}

다음은 이미지를 업로드하는 방법입니다.

프런트 엔드 js를 컨트롤러가 액세스하는 경로로 변경합니다.

tomcat으로 프로젝트 시작

전면 페이지 열기

앞 뒤 끝이 분리되지 않음

아이디어를 사용하여 프론트엔드와 백엔드를 모두 작성하고, 새로운 springboot 프로젝트를 생성하고, 그림과 같이 webapp에 구조를 설정합니다(위와 동일).

사진 설명을 추가해주세요

이 프로젝트의 index.html 경로를 입력하여 브라우저에 액세스하고 직접 사용하십시오.

효과:

사진 설명을 추가해주세요

Qiniuyun으로 돌아가 파일을 확인하면 파일이 성공적으로 업로드되었음을 알 수 있습니다.

사진 설명을 추가해주세요

앞끝과 뒷끝의 분리

HBuilder를 사용하여 프런트 엔드를 작성하고, 새 웹 프로젝트를 만들고, 다운로드한 webuploader 구성 요소를 아래와 같이 넣습니다(및 jquery).

사진 설명을 추가해주세요

이것과 프론트엔드와 백엔드의 분리의 차이는 포트에서의 프로세스가 아니고 크로스도메인 문제가 있기 때문에 크로스도메인 문제 해결이 필요하다는 것입니다.

백엔드에 인터셉터를 작성해야 함

인터셉터 클래스 Filter.java

package com.example.util;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(filterName = "requestFilter", urlPatterns = {
    
    "/*"})
public class Filter implements javax.servlet.Filter {
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // 此处 setHeader、addHeader 方法都可用。但 addHeader时写多个会报错:“...,but only one is allowed”
        response.setHeader("Access-Control-Allow-Origin", "*");
        //response.addHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
        // 解决预请求(发送2次请求),此问题也可在 nginx 中作相似设置解决。
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with,Cache-Control,Pragma,Content-Type,Token, Content-Type");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        String method = request.getMethod();
        if (method.equalsIgnoreCase("OPTIONS")) {
    
    
            servletResponse.getOutputStream().write("Success".getBytes("utf-8"));
        } else {
    
    
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {
    
    

    }
}

그런 다음 springboot 시작 클래스에 주석을 추가하십시오.

//添加过滤器
@ServletComponentScan

그럼 정상적으로 사용하실 수 있습니다

HBuilder에서 index.html을 연 다음 직접 사용하면 결과는 위와 동일합니다.

데이터베이스에 정보를 업로드하면 직접 작성할 수 있습니다.

Supongo que te gusta

Origin blog.csdn.net/weixin_55452293/article/details/127921033
Recomendado
Clasificación