Skip to content

Java后端上传数据

提示

本章节仅做兴趣扩展,不属于官方SDK,仅做参考

本文将通过java tus-java-client 实现数据上传,包含示例代码

tus-java-client github:https://github.com/tus/tus-java-client

1.SDK部署的服务器端nginx增加配置

nginx
location /admin/api/files/upload/ {
    proxy_pass http://127.0.0.1:9999; # 修改为部署txcloud-upms-biz.jar服务实际的端口号
}

信息

如果不增加上述nginx配置,也可将示例代码中的上传路径(url)改为直接连接后端服务。 即http://127.0.0.1/api/admin/api/files/upload改为http://127.0.0.1:9999/admin/api/files/upload,其中9999请替换为部署txcloud-upms-biz.jar服务的端口号

2.java端引入tus-java-client依赖

xml
<dependency>
    <groupId>io.tus.java.client</groupId>
    <artifactId>tus-java-client</artifactId>
    <version>0.5.0</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.5.13</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.7</version>
</dependency>

3.示例代码

java

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.*;
import io.tus.java.client.*;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class TusFileUploadClient {

    public static void main(String[] args) {

        // 登录凭证,接口参考文档:http://api.wish3d.com/api/earthsdk3.0.0/serviceapi/user.html#post-%E7%99%BB%E5%BD%95
        String authorization = "Bearer 824f39c2-af4e-4ae1-93f0-78daae8440f5";
        String projectId = "f24d2da5e290ccf8826af8da5c61f33a";// 上传到的所属项目ID,如果上传到公共资源,则无需传参该参数
        // 上传路径,修改为实际的部署地址
        String urlInit = "http://10.16.30.161/api/admin/data/upload";
        String url = "http://10.16.30.161/api/admin/api/files/upload";

        // 文件信息预保存接口获取到的id,接口参考文档:http://api.wish3d.com/api/earthsdk3.0.0/serviceapi/dataUpload.html#post-1%E6%96%87%E4%BB%B6%E4%BF%A1%E6%81%AF%E9%A2%84%E4%BF%9D%E5%AD%98
        String dataId = getDataid(urlInit, authorization, projectId);


        // 初始化 TusClient
        TusClient client = initTusClient(url, dataId, authorization);

        // 指定待上传的文件路径
        File file = new File("G:\\Data\\LSP示例数据\\影像\\20221102151104.mbtiles");
        if (!file.exists()) {
            System.err.println("错误:文件未找到 -> " + file.getAbsolutePath());
            return;
        }

        // 创建 TusUpload 实例
        TusUpload upload = createTusUpload(file, dataId, projectId);
        if (upload == null) {
            return;
        }

        System.out.println("开始上传文件:" + file.getName());

        // 进行文件上传
        uploadFile(client, upload);
    }

    private static String getDataid(String urlStr, String authorization, String projectId) {
        String dataId = "";

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addTextBody("key", "value", ContentType.TEXT_PLAIN); // 添加其他表单字段
        builder.addTextBody("bizType", "1", ContentType.TEXT_PLAIN);
        builder.addTextBody("fileName", "20221102151104.mbtiles", ContentType.TEXT_PLAIN);
        builder.addTextBody("cfgJson", "{}", ContentType.TEXT_PLAIN);
        builder.addTextBody("isPublish", "1", ContentType.TEXT_PLAIN);
        builder.addTextBody("fileType", "mbtiles", ContentType.TEXT_PLAIN);
        builder.addTextBody("foldersId", "0", ContentType.TEXT_PLAIN);
        builder.addTextBody("projectId", projectId, ContentType.TEXT_PLAIN);
        HttpEntity multipart = builder.build();

        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(urlStr);

        try {
            // 设置请求头
            httpPost.setHeader("Authorization", authorization);
//            httpPost.setHeader("Content-type", "multipart/form-data; boundary=" + boundary);
            // 设置请求体
            httpPost.setEntity(multipart);

            CloseableHttpResponse response = client.execute(httpPost);
            try {
                String result = EntityUtils.toString(response.getEntity());
                System.out.println(response.getStatusLine().getStatusCode());
                System.out.println(result);

                JSONObject obj = JSONObject.parseObject(result.toString());
                if(obj != null){
                    JSONObject objData = obj.getJSONObject("data");
                    if(objData != null){
                        dataId = objData.getString("id");
                    }
                }
            } finally {
                response.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return  dataId;
    }


    /**
     * 初始化 TusClient,并配置必要的请求头
     */
    private static TusClient initTusClient(String url, String dataId, String authorization) {
        TusClient client = new TusClient();
        try {
            client.setUploadCreationURL(new URL(url));
        } catch (MalformedURLException e) {
            System.err.println("错误:上传地址格式错误!");
            e.printStackTrace();
            System.exit(1);
        }

        // 设置 HTTP 请求头,更多参数设置需参考:http://api.wish3d.com/api/earthsdk3.0.0/serviceapi/dataUpload.html#post-2%E5%88%86%E7%89%87%E4%B8%8A%E4%BC%A0%E5%88%9D%E5%A7%8B%E5%8C%96
        Map<String, String> headers = new HashMap<>();
        headers.put("dataId", dataId);
        headers.put("authorization", authorization);
        client.setHeaders(headers);

        // 启用断点续传
        client.enableResuming(new TusURLMemoryStore());

        return client;
    }

    /**
     * 创建 TusUpload 上传对象
     */
    private static TusUpload createTusUpload(File file) {
        try {
            TusUpload upload = new TusUpload(file);
            // 设置元数据,更多参数设置需参考:http://api.wish3d.com/api/earthsdk3.0.0/basemodule/data.html#%E4%B8%8A%E4%BC%A0%E6%96%87%E4%BB%B6%E7%A4%BA%E4%BE%8B
            Map<String, String> metadata = new HashMap<>();
            metadata.put("folderId", "0"); // 上传到的所属文件夹ID,如果是顶级,则传0
            metadata.put("projectId", ""); // 上传到的所属项目ID,如果上传到公共资源,则无需传参该参数
            metadata.put("dataId", ""); // 文件信息预保存接口获取到的源数据id
            upload.setMetadata(metadata);
            return upload;
        } catch (FileNotFoundException e) {
            System.err.println("错误:文件未找到 -> " + file.getAbsolutePath());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 进行文件上传
     */
    private static void uploadFile(TusClient client, TusUpload upload) {
        TusExecutor executor = new TusExecutor() {
            @Override
            protected void makeAttempt() throws IOException, ProtocolException {
                TusUploader uploader;
                try {
                    uploader = client.resumeOrCreateUpload(upload);
                } catch (ProtocolException e) {
                    System.err.println("错误:无法创建或恢复上传!");
                    throw e;
                }

                uploader.setChunkSize(1024); // 设置分块大小(单位:字节)
                long totalBytes = upload.getSize(); // 文件总大小
                long bytesUploaded; // 已上传字节数

                while ((bytesUploaded = uploader.getOffset()) < totalBytes) {
                    double progress = (double) bytesUploaded / totalBytes * 100;
                    System.out.printf("上传进度: %.2f%% (%d/%d bytes)\n", progress, bytesUploaded, totalBytes);
                    uploader.uploadChunk(); // 上传分块
                }

                uploader.finish(); // 结束上传
                System.out.println("上传完成!");
            }
        };

        try {
            executor.makeAttempts(); // 执行上传
        } catch (ProtocolException | IOException e) {
            System.err.println("上传失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
}

4.注意事项

危险

  1. 本章节仅做兴趣扩展,不属于官方SDK,仅做参考
  2. 示例代码中的异常捕获后续逻辑需根据业务按需补充处理
  3. 上传涉及到的参数,需根据SDK文档进一步完善
  4. 本文档仅根据tus-java-client实现简单的文件上传集成,更多逻辑及特性可根据实际业务自行扩展

Released under the MIT License.