https post上传文件指定mimeType(token)

该博客介绍如何在Java中通过HTTPS POST方式上传文件,并详细说明如何根据文件后缀指定MimeType。内容涵盖本地MIME类型映射、上传请求方法的实现以及测试方法。

对于上传文件,服务接口需要根据指定的文件名称后缀来确定类型。

本地存放mime映射类型及几个变量

    public static final String CATEGORY_CODE = "13";//系统默认
    public static final String LANGUAGE = "zh";//系统默认

    public static final String MIME_GROUPS = "[" +
            "{\"fileType\":\".txt\",\"mimeType\":\"text/plain\",\"mimeGroup\":\"the text document\"},\n" +
            "{\"fileType\":\".jpg\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".jpeg\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".jpe\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".png\",\"mimeType\":\"image/png\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".bmp\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".dib\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".bmp\",\"mimeType\":\"image/x-windows-bmp\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".tif\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".tiff\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".jfif\",\"mimeType\":\"image/jpeg\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".gif\",\"mimeType\":\"image/gif\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".doc\",\"mimeType\":\"application/msword\",\"mimeGroup\":\"Word document\"},\n" +
            "{\"fileType\":\".docx\",\"mimeType\":\"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\"mimeGroup\":\"Word document\"},\n" +
            "{\"fileType\":\".docm\",\"mimeType\":\"application/vnd.ms-word.document.macroenabled.12\",\"mimeGroup\":\"Word document\"},\n" +
            "{\"fileType\":\".dotx\",\"mimeType\":\"application/vnd.openxmlformats-officedocument.wordprocessingml.template\",\"mimeGroup\":\"Word document\"},\n" +
            "{\"fileType\":\".dotm\",\"mimeType\":\"application/vnd.ms-word.template.macroEnabled.12\",\"mimeGroup\":\"Word document\"},\n" +
            "{\"fileType\":\".rtf\",\"mimeType\":\"application/rtf\",\"mimeGroup\":\"Word document\"},\n" +
            "{\"fileType\":\".pdf\",\"mimeType\":\"application/pdf\",\"mimeGroup\":\"PDF\"},\n" +
            "{\"fileType\":\".pptx\",\"mimeType\":\"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\"mimeGroup\":\"PowerPoint\"},\n" +
            "{\"fileType\":\".pptm\",\"mimeType\":\"application/vnd.ms-powerpoint.presentation.macroEnabled.12\",\"mimeGroup\":\"PowerPoint\"},\n" +
            "{\"fileType\":\".ppt\",\"mimeType\":\"application/vnd.ms-powerpoint\",\"mimeGroup\":\"PowerPoint\"},\n" +
            "{\"fileType\":\".odp\",\"mimeType\":\"application/vnd.oasis.opendocument.presentation\",\"mimeGroup\":\"Open Document\"},\n" +
            "{\"fileType\":\".ods\",\"mimeType\":\"application/vnd.oasis.opendocument.spreadsheet\",\"mimeGroup\":\"Open Document\"},\n" +
            "{\"fileType\":\".odt\",\"mimeType\":\"application/vnd.oasis.opendocument.text\",\"mimeGroup\":\"Open Document\"},\n" +
            "{\"fileType\":\".xps\",\"mimeType\":\"application/vnd.ms-xpsdocument\",\"mimeGroup\":\"XPS\"},\n" +
            "{\"fileType\":\".vds\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"VDS\"},\n" +
            "{\"fileType\":\".dif\",\"mimeType\":\"video/x-dv\",\"mimeGroup\":\"DIF\"},\n" +
            "{\"fileType\":\".prn\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"PRN\"},\n" +
            "{\"fileType\":\".dib\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"image\"},\n" +
            "{\"fileType\":\".csv\",\"mimeType\":\"text/csv\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".slk\",\"mimeType\":\"application/sylk\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".xlsb\",\"mimeType\":\"application/vnd.ms-excel.sheet.binary.macroenabled.12\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".xlsm\",\"mimeType\":\"application/vnd.ms-excel.sheet.macroenabled.12\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".xltx\",\"mimeType\":\"application/vnd.openxmlformats-officedocument.spreadsheetml.template\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".xls\",\"mimeType\":\"application/vnd.ms-excel\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".xltm\",\"mimeType\":\"application/vnd.ms-excel.template.macroEnabled.12\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".xlsx\",\"mimeType\":\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\"mimeGroup\":\"spreadsheet\"},\n" +
            "{\"fileType\":\".html\",\"mimeType\":\"application/html\",\"mimeGroup\":\"HTML\"},\n" +
            "{\"fileType\":\".xsl\",\"mimeType\":\"application/xml\",\"mimeGroup\":\"HTML\"},\n" +
            "{\"fileType\":\".xdp\",\"mimeType\":\"application/vnd.adobe xdp+xml\",\"mimeGroup\":\"HTML\"},\n" +
            "{\"fileType\":\".htm\",\"mimeType\":\"application/html\",\"mimeGroup\":\"HTML\"},\n" +
            "{\"fileType\":\".avi\",\"mimeType\":\"video/avi\",\"mimeGroup\":\"video\"},\n" +
            "{\"fileType\":\".mp4\",\"mimeType\":\"video/mp4\",\"mimeGroup\":\"video\"},\n" +
            "{\"fileType\":\".mov\",\"mimeType\":\"video/quicktime\",\"mimeGroup\":\"video\"},\n" +
            "{\"fileType\":\".wmv\",\"mimeType\":\"video/x-ms-asf\",\"mimeGroup\":\"video\"},\n" +
            "{\"fileType\":\".wav\",\"mimeType\":\"audio/wav\",\"mimeGroup\":\"audio\"},\n" +
            "{\"fileType\":\".mp3\",\"mimeType\":\"audio/mpeg3\",\"mimeGroup\":\"audio\"},\n" +
            "{\"fileType\":\".aml\",\"mimeType\":\"application/AML\",\"mimeGroup\":\"XML\"},\n" +
            "{\"fileType\":\".url\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"XML\"},\n" +
            "{\"fileType\":\".xml\",\"mimeType\":\"application/xml\",\"mimeGroup\":\"XML\"},\n" +
            "{\"fileType\":\".dwg\",\"mimeType\":\"application/acad\",\"mimeGroup\":\"CAD\"},\n" +
            "{\"fileType\":\".dxf\",\"mimeType\":\"application/dxf\",\"mimeGroup\":\"CAD\"},\n" +
            "{\"fileType\":\".sat\",\"mimeType\":\"application/sat\",\"mimeGroup\":\"CAD\"},\n" +
            "{\"fileType\":\".stp\",\"mimeType\":\"application/step\",\"mimeGroup\":\"CAD\"},\n" +
            "{\"fileType\":\".bag\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".h4\",\"mimeType\":\"application/x-hdf\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".h5\",\"mimeType\":\"application/x-hdf5\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".he5\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".hdf4\",\"mimeType\":\"application/x-hdf\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".hdf5\",\"mimeType\":\"application/x-hdf5\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".hdf\",\"mimeType\":\"application/x-hdf\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".msz\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\".fbx\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"augmented reality\"},\n" +
            "{\"fileType\":\"ELINK\",\"mimeType\":\"application/xml\",\"mimeGroup\":\"link\"},\n" +
            "{\"fileType\":\".out\",\"mimeType\":\"application / x-out\",\"mimeGroup\":\"data exchange files\"},\n" +
            "{\"fileType\":\".mon\",\"mimeType\":\"\",\"mimeGroup\":\"data exchange files\"},\n" +
            "{\"fileType\":\".aas\",\"mimeType\":\"application/json\",\"mimeGroup\":\"data exchange files\"},\n" +
            "{\"fileType\":\".zip\",\"mimeType\":\"application/zip\",\"mimeGroup\":\"compress the file\"},\n" +
            "{\"fileType\":\".tar\",\"mimeType\":\"application/x-tar\",\"mimeGroup\":\"compress the file\"},\n" +
            "{\"fileType\":\".tgz\",\"mimeType\":\"application/x-gzip\",\"mimeGroup\":\"compress the file\"},\n" +
            "{\"fileType\":\".deb\",\"mimeType\":\"application/vnd.debian.binary-package\",\"mimeGroup\":\"compress the file\"},\n" +
            "{\"fileType\":\".aasx\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"compress the file\"},\n" +
            "{\"fileType\":\".amlx\",\"mimeType\":\"application/octet-stream\",\"mimeGroup\":\"XML\"}" +
            "]\n";

上传的请求方法类:

package org.jeecg.modules.ain.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * 描述信任SSL 发送https请求工具类
 */
public class FileHttpsUtil {
    private static class TrustAnyTrustManager implements X509TrustManager {

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }

    private static class TrustAnyHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    public static JSONObject submitPost(String url, String token, File file, String newFileName, String shortDesc, String desc, String mimeType) throws NoSuchAlgorithmException, KeyManagementException {
        JSONObject resultJson = new JSONObject();
        SSLContext sslContext = SSLContext.getInstance("SSL");
        X509TrustManager tm = new TrustAnyTrustManager();
        sslContext.init(null, new TrustManager[]{tm}, new java.security.SecureRandom());
        HttpClient httpclient = HttpClients.custom()
                .setSSLHostnameVerifier(new TrustAnyHostnameVerifier()).setSSLContext(sslContext).build();

//        HttpClient httpclient = new DefaultHttpClient();
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Authorization", "Bearer " + token);//token

//            httpPost.setHeader("Accept", "*");
//            httpPost.setHeader("Cache-Control", "no-cache");
//            //            httpPost.setHeader("Content-Type", "multipart/form-data");
//            httpPost.setHeader("Content-Type", "multipart/form-data; boundary=--------------------------168650270649406994495093");

//            String BOUNDARY = "--------7d4a6d158c9";// 定义数据分隔线
//            httpPost.setHeader("Authorization", "Bearer " + token);//token
//            httpPost.setHeader("connection", "Keep-Alive");
//            httpPost.setHeader("user-agent", "Mozilla/4.0(compatible;NSIE 6.0; Mindows NT 5.1;SV1)");
//            httpPost.setHeader("charset", "UTF-8");
//            httpPost.setHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

//            MultipartEntity reqEntity = new MultipartEntity();
            MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
            //设置浏览器兼容模式
            reqEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            //设置请求的编码格式
            reqEntity.setCharset(Consts.UTF_8);
            reqEntity.setContentType(ContentType.MULTIPART_FORM_DATA);


            //            FileBody fileBody = new FileBody(file);
//            FileBody fileBody = new FileBody(file, ContentType.APPLICATION_OCTET_STREAM, file.getName());
//            FileBody fileBody = new FileBody(file, ContentType.TEXT_PLAIN, file.getName());//txt success
//            FileBody fileBody = new FileBody(file, ContentType.TEXT_PLAIN);//txt success
//            FileBody fileBody = new FileBody(file, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");//word .docx
            //根据文件名称的后缀获取mimetype
            String fileName = file.getName();
            String fileType = fileName.substring(fileName.lastIndexOf("."));
            if (StringUtils.isEmpty(mimeType)) {
                JSONArray array = JSONArray.parseArray(AinConstant.AIN_MIME_GROUPS);
                for (int i = 0; i < array.size(); i++) {
                    if (fileType.equals(array.getJSONObject(i).getString("fileType"))) {
                        mimeType = array.getJSONObject(i).getString("mimeType");
                        break;
                    }
                }
            }
            if (StringUtils.isEmpty(mimeType)) {
                resultJson.put("code", "error");
                resultJson.put("message", "未找到文件对应的mimeType");
                return resultJson;
            }
            FileBody fileBody = new FileBody(file, mimeType);//word .docx

            reqEntity.addPart("file", fileBody);//请求后台的普通参数属性名


            //ContentType.DEFAULT_BINARY,"fileName.jpg"
//            reqEntity.addBinaryBody("file", getBytesByFile(file), ContentType.DEFAULT_BINARY, file.getName());

//            reqEntity.addBinaryBody("file", new FileInputStream(file), ContentType.APPLICATION_OCTET_STREAM, file.getName());
//            reqEntity.addBinaryBody("file", new FileInputStream(file), ContentType.TEXT_PLAIN, file.getName());//txt success
//            reqEntity.addBinaryBody("file", new FileInputStream(file), ContentType.IMAGE_PNG, file.getName());//png success

//            InputStream in = new FileInputStream(file);
//            InputStreamBody inputStreamBody = new InputStreamBody(in, file.getName());
////            InputStreamBody inputStreamBody = new InputStreamBody(in, ContentType.TEXT_PLAIN);//txt success
////            InputStreamBody inputStreamBody = new InputStreamBody(in, ContentType.TEXT_PLAIN);//doc error
//            reqEntity.addPart("file", inputStreamBody);//请求后台的普通参数属性名

            reqEntity.addPart("fileName", new StringBody(newFileName, Charset.forName("utf8")));//文件名称中文乱码 和 系统title一致
            reqEntity.addPart("categoryCode", new StringBody(AinConstant.CATEGORY_CODE));
            reqEntity.addPart("language", new StringBody(AinConstant.LANGUAGE));
            reqEntity.addPart("shortDescription", new StringBody(shortDesc, Charset.forName("utf8")));
            reqEntity.addPart("description", new StringBody(desc, Charset.forName("utf8")));

//            httpPost.setEntity(reqEntity);
            httpPost.setEntity(reqEntity.build());

            HttpResponse response = httpclient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                System.out.println("服务器正常响应.....");
                HttpEntity resEntity = response.getEntity();
                String resultStr = EntityUtils.toString(resEntity);//httpclient自带的工具类读取返回数据
                System.out.println("返回内容:" + resultStr);
                resultJson.put("code", "success");
                resultJson.put("result", JSONObject.parseObject(resultStr));
                //System.out.println(resEntity.getContent());
                EntityUtils.consume(resEntity);
            } else {
                System.out.println("服务器响应失败.....status:" + statusCode);
                HttpEntity resEntity = response.getEntity();
                String resultStr = EntityUtils.toString(resEntity);//httpclient自带的工具类读取返回数据
                System.out.println("返回内容:" + resultStr);
                resultJson.put("code", "error");
                resultJson.put("message", JSONObject.parse(resultStr));
                EntityUtils.consume(resEntity);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultJson.put("code", "error");
            resultJson.put("message", "系统异常:" + e.getMessage());
            return resultJson;
        } finally {
            try {
                httpclient.getConnectionManager().shutdown();
            } catch (Exception ignore) {
            }
        }
        return resultJson;
    }

    public static JSONObject sendPost(String url, String token, JSONObject jsonParam) throws NoSuchAlgorithmException, KeyManagementException {
        JSONObject resultJson = new JSONObject();
        SSLContext sslContext = SSLContext.getInstance("SSL");
        X509TrustManager tm = new TrustAnyTrustManager();
        sslContext.init(null, new TrustManager[]{tm}, new java.security.SecureRandom());
        HttpClient httpclient = HttpClients.custom()
                .setSSLHostnameVerifier(new TrustAnyHostnameVerifier()).setSSLContext(sslContext).build();

        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Authorization", "Bearer " + token);//token
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setHeader("Connection", "Keep-Alive");// 维持长连接
            httpPost.setHeader("Charset", "UTF-8");
            httpPost.setHeader("X-Client-Version", "1.0");

            //请求参数
            if (jsonParam != null) {
                httpPost.setEntity(new StringEntity(jsonParam.toString(), StandardCharsets.UTF_8));
            }

            HttpResponse response = httpclient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                System.out.println("服务器正常响应.....");
                HttpEntity resEntity = response.getEntity();
                String resultStr = EntityUtils.toString(resEntity);//httpclient自带的工具类读取返回数据
                System.out.println("返回内容:" + resultStr);
                resultJson.put("code", "success");
                resultJson.put("result", JSONObject.parseObject(resultStr));
                //System.out.println(resEntity.getContent());
                EntityUtils.consume(resEntity);
            } else {
                System.out.println("服务器响应失败.....status:" + statusCode);
                HttpEntity resEntity = response.getEntity();
                String resultStr = EntityUtils.toString(resEntity);//httpclient自带的工具类读取返回数据
                System.out.println("返回内容:" + resultStr);
                resultJson.put("code", "error");
                resultJson.put("message", JSONObject.parse(resultStr));
                EntityUtils.consume(resEntity);
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultJson.put("code", "error");
            resultJson.put("message", "系统异常:" + e.getMessage());
            return resultJson;
        } finally {
            try {
                httpclient.getConnectionManager().shutdown();
            } catch (Exception ignore) {
            }
        }
        return resultJson;
    }


    public static byte[] getBytesByFile(String filePath) {
        try {
            File file = new File(filePath);
            //获取输入流
            FileInputStream fis = new FileInputStream(file);

            //新的 byte 数组输出流,缓冲区容量1024byte
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
            //缓存
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            //改变为byte[]
            byte[] data = bos.toByteArray();
            //
            bos.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] getBytesByFile(File file) {
        try {
            //获取输入流
            FileInputStream fis = new FileInputStream(file);

            //新的 byte 数组输出流,缓冲区容量1024byte
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
            //缓存
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            //改变为byte[]
            byte[] data = bos.toByteArray();
            //
            bos.close();
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

测试方法:

使用本地的一个文件路径测试即可

        String filePath = "d:/演示文稿1.pptx";
        String fileCode = "50520-000001-001";
        String desc = "测试文件上传";


        String token = "";//根据实际情况

        File file = new File(filePath);
        System.out.println("文件名称:" + file.getName());
        System.out.println("文件路径:" + file.getPath());

        String fileName = file.getName();
        String filePrefix = fileName.substring(0, fileName.lastIndexOf("."));
        System.out.println(filePrefix);

        //获取 mimeType
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        String mimeType = "";
        JSONArray array = JSONArray.parseArray(Constant.MIME_GROUPS);
        for (int i = 0; i < array.size(); i++) {
            if (fileType.equals(array.getJSONObject(i).getString("fileType"))) {
                mimeType = array.getJSONObject(i).getString("mimeType");
                break;
            }
        }
        System.out.println("mimeType=" + mimeType);

        String newFileName = fileName;//新文件名称
        System.out.println(newFileName);

        //newUrl 根据实际情况填写
        String newUrl = "";
        JSONObject result = FileHttpsUtil.submitPost(newUrl, token, file, newFileName, fileCode, desc, mimeType);
        System.out.println(result.toString());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值