Java实现图片上传返回上传地址

2023-11-19

关于在实际开发中最常用也是用的最多的Java实现文档、图片上传。
一、准备阶段
文档、图片上传有几种方式,包括传统的ajax上传,云上传,这里给大家实现通过代码将图片上传至七牛云服务器并返回图片地址。
1.需申请一台七牛云服务器地址(可免费试用30天)

注册登陆成功后可申请试用30天,点击空间管理,即可新增空间
新增成功点击进空间,会给你个测试域名用来返回图片地址调用,当然可以添加自己的域名,具体参考七牛云服务器描述

二、代码准备
只需要提供接口controller以及业务service包即可
话不多说!上代码!

package com.ymzd.shop.controller.fileupload;


import com.ymzd.shop.service.IUploadService;
import com.ymzd.shop.common.ResultData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author wangzhic
 * @date 2019-12
 */
@RestController
@RequestMapping("/upload")
@Api(tags = "文件上传接口", description = "wangzhicheng")
public class UploadController {

    @Resource
    private IUploadService uploadServiceImpl;


    /**
     * 获取七牛云的token
     *
     * @return
     */
    @GetMapping("/gettoken")
    @ApiOperation(value = "获取上传token", notes = "获取token无需要参数")
    public ResultData<String> getUpToken() {

        String upToken = uploadServiceImpl.getUpToken();
        if (upToken != null && upToken.length() != 0) {
            return new ResultData<String>().success(upToken);
        } else {
            return new ResultData<String>().error("token获取失败!");
        }
    }

    /**
     * 上传文件到七牛云服务器
     *
     * @param files
     * @param request
     * @return
     */
    @PostMapping(value = "/files", headers = "content-type=multipart/form-data")
    @ApiOperation(value = "文件上传接口", notes = "文件上传api必须用表单方式提交")
    public ResultData<String> upLoadFile(@ApiParam(value = "files", required = true)
                                         @RequestParam("files") MultipartFile[] files,
                                         HttpServletRequest request) {
        String url = "";
        if (files.length == 1) {
            if (files[0].getSize() > 5 * 1024 * 1024) {
                return new ResultData<String>().error("单个图片不能大于5M!");
            } else {
                try {
                    url = uploadServiceImpl.uploadFile(files[0]);
                    //return new ResultData<String>().success(url);
                } catch (Exception e) {
                    return new ResultData<String>().error("图片大于5M,请重新上传!");
                }
            }
        } else {
            for (MultipartFile file : files) {
                if (StringUtils.isEmpty(file)) {
                    return new ResultData<String>().error("文件为空请重新上传!");
                } else if (file.getSize() > 5 * 1024 * 1024) {
                    return new ResultData<String>().error("单个图片不能大于5M!");
                } else {
                    try {
                        url += uploadServiceImpl.uploadFile(file) + " ";
                        System.out.println("回调地址:" + url);
                    } catch (Exception e) {
                        return new ResultData<String>().error("图片大于5M,请重新上传!");
                    }
                }
            }
        }
        return new ResultData<String>().success(url);

    }
}


可设置上传大小,这里我设置了单个图片不能超过5M

servlet:
  multipart:
    max-file-size: 25MB
    max-request-size: 50MB

该配置表示单个文件不超过25M 单个请求的总文件大小不超过 50M

package com.ymzd.shop.service.impl;


import com.ymzd.shop.service.IUploadService;
import com.ymzd.shop.util.QiniuCloudUtil;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;


@Service
public class UploadServiceImpl implements IUploadService {

    /**
     * 获取七牛云token
     *
     * @return
     */
    @Override
    public String getUpToken() {
        return QiniuCloudUtil.getupToken();
    }

    /**
     * 上传文件到七牛云
     *
     * @param file
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        byte[] bytes = null;
        System.out.println("fileName="+file.getOriginalFilename());
        try {
            bytes = file.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return QiniuCloudUtil.uploadFileBytes(bytes,file.getOriginalFilename());
    }

}

业务块代码

package com.ymzd.shop.util;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.qiniu.util.Base64;
import com.qiniu.util.StringMap;
import com.qiniu.util.UrlSafeBase64;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.apache.tomcat.util.http.fileupload.FileUploadBase;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

public class QiniuCloudUtil {
    private static Properties properties = new Properties();
    // 设置七牛云账号的AK和SK
    private static String ACCESS_KEY = null;
    private static String SECRET_KEY = null;
    // 要上传的空间bucket
    private static String BUCKET = null;
    //外链地址:这里要改成自己的域名
    private static String DOMAIN = null;

    private static SimpleDateFormat simpleDateFormat;

    private static int i = 1;

    static {
        try {
            properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("qiniuyun.properties"));
            ACCESS_KEY = properties.getProperty("accessKey");
            SECRET_KEY = properties.getProperty("secretKey");
            BUCKET = properties.getProperty("hostname");
            DOMAIN = properties.getProperty("DOMAIN");
            simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取七牛云Token
     */
    public static String getupToken() {
        //秘钥配置上传的凭证
        Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
        StringMap putPolicy = new StringMap();
        putPolicy.put("returnBody", "{\"fileUrl\": \"" + DOMAIN + "$(key)\"}");//上传成功后是返回这个json数据,fileUrl就是的地址
        long expireSeconds = 3600;//过期时间

        String upToken = auth.uploadToken(BUCKET, null, expireSeconds, putPolicy);
        System.out.println(upToken);
        return upToken;
    }

    /**
     * @param
     * @return 外键地址
     */
    //普通上传
    public static String uploadFile() {
        //文件的外链地址
        StringBuffer fileUrl = new StringBuffer(DOMAIN);

        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone2());

        UploadManager uploadManager = new UploadManager(cfg);

        //如果是Windows情况下,格式是 D:\\qiniu\\test.png
        String localFilePath = "/Users/leeyunt/Downloads/1864602-3d5d1de100e459b8.png";
        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = null;

        try {
            //上传文件
            Response response = uploadManager.put(localFilePath, key, getupToken());

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

    //base64方式上传
    public static String uploadFileBase64(byte[] base64, String key) throws Exception {
        String file64 = Base64.encodeToString(base64, 0);
        Integer l = base64.length;
        String uploadUrl = "http://up-z2.qiniup.com/putb64/" + l + "/key/" + UrlSafeBase64.encodeToString(key);
        //非华南空间需要修改上传域名
        //上传文件
        RequestBody rb = RequestBody.create(null, file64);
        Request request = new Request.Builder().
                url(uploadUrl)
                .addHeader("Content-Type", "application/octet-stream")
                .addHeader("Authorization", "UpToken " + getupToken())
                .post(rb).build();
        //System.out.println(request.headers());
        OkHttpClient client = new OkHttpClient();
        okhttp3.Response response = client.newCall(request).execute();
        System.out.println(response);
        return DOMAIN + key;
    }

    //字节数组上传

    /**
     * 字节上传
     *
     * @param uploadBytes
     * @param fileName
     * @return 链接地址
     * @throws Exception
     */
    public static String uploadFileBytes(byte[] uploadBytes, String fileName) throws Exception {
        //文件的外链地址
        StringBuffer fileUrl = new StringBuffer("https://"+DOMAIN);

        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone2());

        UploadManager uploadManager = new UploadManager(cfg);
        //默认不指定key的情况下,以文件内容的hash值作为文件名
        //System.out.println("截取文件:"+fileName.substring(fileName.indexOf(".")));

        String key = simpleDateFormat.format(new Date())+ i + fileName.substring(fileName.indexOf("."));

        i++;
        //秘钥配置上传的凭证
        Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
        String upToken = auth.uploadToken(BUCKET);

        try {
            //上传文件
            Response response = uploadManager.put(uploadBytes, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
            fileUrl.append("/" + putRet.key);
            //MyPutRet myPutRet=response.jsonToObject(MyPutRet.class);
            //System.out.println(myPutRet);
        } catch (QiniuException ex) {
            Response r = ex.response;
            System.err.println(r.toString());
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
        }
        return fileUrl.toString();
    }

}

这里附上工具类,经过我不断发现问题,多次加工完成,我所返回的地址为“https”的加密路径,所以七牛云必须配置自己的域名。
上传差不多就这个,返回的字符即是图片地址,即可访问。盆友开始编码吧!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现图片上传返回上传地址 的相关文章

  • Java:无法从同一包中的不同类访问静态变量

    这很奇怪 因为我有一个可以访问 Frame dimension getWidth 的 Character 类 及其伙伴 getHeight 但是当我想在 Map 类中使用它时 Eclipse 强调了它并且无法给我反馈 运行该程序最终会出现
  • 是否有任何简单(且最新)的 Java 框架可用于在 Swing 应用程序中嵌入电影?

    我正在构建一个小型 Swing 应用程序 我想在其中嵌入一部电影 重要的是 这个应用程序是一个 WebStart 应用程序 并且该库应该能够打包在我启动的 jnlp 中 即 不依赖于本机库 我知道并尝试过 JMF 但我认为与其他框架相比 其
  • Spring RestTemplate 使用 cookie 遵循重定向

    最近我遇到了一个问题 我需要做一个GET请求远程服务 我假设使用一个简单的 servlet 并且 RestTemplate 返回Too many redirects 经过一番调查 似乎对指定远程服务发出的第一个请求实际上只是一个 302 重
  • 大数据使用什么数据结构

    我有一个包含一百万行的 Excel 工作表 每行有 100 列 每行代表一个具有 100 个属性的类的实例 列值是这些属性的值 哪种数据结构最适合在这里使用来存储数百万个数据实例 Thanks 这实际上取决于您需要如何访问这些数据以及您想要
  • 是否可以通过编程方式查找 logback 日志文件?

    自动附加日志文件以支持电子邮件会很有用 我可以以编程方式设置路径 如以编程方式设置 Logback Appender 路径 https stackoverflow com questions 3803184 setting logback
  • 如何检测 Java 字符串中的 unicode 字符?

    假设我有一个包含 的字符串 我如何找到所有这些 un icode 字符 我应该测试他们的代码吗 我该怎么做呢 例如 给定字符串 A X 我想将其转换为 AYXY 我想对其他 unicode 字符做同样的事情 并且我不想将它们存储在某种翻译映
  • 套接字的读写如何同步?

    我们创建一个套接字 在套接字的一侧有一个 服务器 在另一侧有一个 客户端 服务器和客户端都可以向套接字写入和读取 这是我的理解 我不明白以下事情 如果服务器从套接字读取数据 它在套接字中是否只看到客户端写入套接字的内容 我的意思是 如果服务
  • 生成的序列以 1 开头,而不是注释中设置的 1000

    我想请求一些有关 Hibernate 创建的数据库序列的帮助 我有这个注释 下面的代码 在我的实体类中 以便为合作伙伴表提供单独的序列 我希望序列以 1000 开头 因为我在部署期间使用 import sql 将测试数据插入数据库 并且我希
  • 如何避免 ArrayIndexOutOfBoundsException 或 IndexOutOfBoundsException? [复制]

    这个问题在这里已经有答案了 如果你的问题是我得到了java lang ArrayIndexOutOfBoundsException在我的代码中 我不明白为什么会发生这种情况 这意味着什么以及如何避免它 这应该是最全面的典范 https me
  • 如何在 Spring 属性中进行算术运算?

  • 使用架构注册表对 avro 消息进行 Spring 云合约测试

    我正在查看 spring 文档和 spring github 我可以看到一些非常基本的内容examples https github com spring cloud samples spring cloud contract sample
  • Docker 和 Eureka 与 Spring Boot 无法注册客户端

    我有一个使用 Spring Boot Docker Compose Eureka 的非常简单的演示 我的服务器在端口 8671 上运行 具有以下应用程序属性 server port 8761 eureka instance prefer i
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • Spring-ws:如何从没有“Request”元素的 xsd 创建 Wsdl

    尝试为客户端实现 SOAP Web 服务 我需要一个 wsdl 文件来通过soapUI 测试该服务 但正如您在下面看到的 这个 xsd 没有 Request 和 Response 方法 所有请求和响应都被定义为基本 ServiceProvi
  • Java Swing:需要一个高质量的带有复选框的开发 JTree

    我一直在寻找一个 Tree 实现 其中包含复选框 其中 当您选择一个节点时 树中的所有后继节点都会被自动选择 当您取消选择一个节点时 树中其所有后继节点都会自动取消选择 当已经选择了父节点 并且从其后继之一中删除了选择时 节点颜色将发生变化
  • Angular 2 - Http - 正确忽略空结果

    我有很多处理请求并简单返回 200 的 REST 端点 我注意到将结果映射为错误json 如果我尝试不进行任何类型的映射 我会看到浏览器警告它无法解析 XML 由于不返回任何内容是很常见的 我很好奇我应该如何处理响应 这是一个基本的代码示例
  • 如何重新启动死线程? [复制]

    这个问题在这里已经有答案了 有哪些不同的可能性可以带来死线程回到可运行状态 如果您查看线程生命周期图像 就会发现一旦线程终止 您就无法返回到新位置 So 没有办法将死线程恢复到可运行状态 相反 您应该创建一个新的 Thread 实例
  • 泛型、数组和 ClassCastException

    我想这里一定发生了一些我不知道的微妙事情 考虑以下 public class Foo
  • 在浏览器刷新中刷新检票面板

    我正在开发一个付费角色系统 一旦用户刷新浏览器 我就需要刷新该页面中可用的统计信息 统计信息应该从数据库中获取并显示 但现在它不能正常工作 因为在页面刷新中 java代码不会被调用 而是使用以前的数据加载缓存的页面 我尝试添加以下代码来修复
  • 洪水填充优化:尝试使用队列

    我正在尝试创建一种填充方法 该方法采用用户指定的初始坐标 检查字符 然后根据需要更改它 这样做之后 它会检查相邻的方块并重复该过程 经过一番研究 我遇到了洪水填充算法并尝试了该算法 它可以工作 但无法满足我对 250 x 250 个字符的数

随机推荐

  • 电脑修改用户(User)文件夹名称

    情景 Windows 11 的用户名与 C 盘 系统盘 中的文件夹名称不对应 可能是由于重装系统导致的 例如我笔记本中系统用户名是 fly 但文件夹名称却是 16490 Step 1 打开Administrator账户 搜索 cmd 右键
  • 二、字符串(36)392. 判断子序列

    392 判断子序列 给定字符串 s 和 t 判断 s 是否为 t 的子序列 字符串的一个子序列是原始字符串删除一些 也可以不删除 字符而不改变剩余字符相对位置形成的新字符串 例如 ace 是 abcde 的一个子序列 而 aec 不是 进阶
  • 关于游戏设计状态

    状态转移在数学里究竟是干嘛的我也不多说了 毕竟大家都是做游戏的 也不需要这么高深的数学知识 我就从一个实例开始讲一下吧 看不懂那我也没办法了 死套公式也行 只要调整下系数问题也不大 以武器强化为例 武器强化等级假如总共有十个等级 从一级开始
  • 数据结构----对称矩阵压缩存储中下标的计算

    一 压缩存储的概念 首先看一个对称矩阵 以深灰色为对称轴 由于矩阵内数据对称 因此只需将任意一边的数据存储起来即可 考虑到存储单元的线性结构 我们可以以一维数组的形式将其存储起来 需要存储的元素为 各个元素对应在一维数组中的位置示意图 按行
  • vue3+element+sortablejs实现table表格 行列动态拖拽

    vue3 element sortablejs实现table动态拖拽 1 第一步我们要安装sortablejs依赖 2 在我们需要的组件中引入 3 完整代码 4 效果 5 扩展 判断要拖动的行能不能拖动并放置到新位置 1 第一步我们要安装s
  • Promise {}

    Promise
  • 二叉树的链式结构实现

    文章目录 前言 链式结构实现 创建结点结构体 构建树逻辑结构 遍历二叉树 计算二叉树高度 结点数 叶子数 前言 对于一般的二叉树 非完全二叉树 满二叉树 而言 用顺序表去存储 会造成空间的浪费 所以一般采用链式结构实现 对于非完全非满二叉树
  • 前端Tabs表单的使用

  • 【codeforces #290(div 1)】ABC题解

    A Fox And Names time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard o
  • 08-10章

    第8章 函数 1 def 定义函数 2 形参 实参 3 位置实参 关键字实参 可给形参指定默认值 4 返回值 使用reture语句将值返回到调用函数的代码行 5 让实参变成可选的 将某个形参设置为空值 6 返回字典 7 向函数传递列表 在函
  • 学海无涯苦作舟

    作者在Twitter上发的一条短讯 每一天 你一定要一起床就热情澎湃 否则 你就只是在打工 3 51 PM 2012 5 1 在我们创办Stack Overflow网站之后 有些人开始承认 我们构造了一个还过得去的 捕鼠器 把大家都吸引到那
  • 拷贝构造函数 浅拷贝与深拷贝

    目录 拷贝构造函数 浅拷贝 深拷贝 拷贝构造函数 上一期中我们讲述了构造函数的相关内容 谈到构造函数在形式上有几种分类 即带参数的 不带参数的以及参数列表初始化的 还有一种传引用的构造函数 称为拷贝构造函数 顾名思义 就是起到拷贝的功能 通
  • 函数的防抖和节流简述

    防抖和节流 即 限制函数的执行次数 防抖和节流二者非常相似 但还是有细微的不同 防抖 通过 setTimeout 的方式在一定的时间间隔内 将多次触发变成一次触发 比如用户在十秒内一直连续点击 但最后只会触发一次 简单举例 function
  • FreeBSD用ports安装Firefox不成功 + 解决办法!

    今天在FreeBSD 5 4 Release中安装Firefox 先更新ports tree到最新版本 FreeBSD cvsup g L 2 root ports supfile 然后到Firefox的目录中去执行make FreeBSD
  • 在linux下为arm开发板交叉编译openssl报错arm-linux-gcc.br_real: error: unrecognized command line option '-m64'

    ubuntu 1804下安装树莓派的编译器后 在编译openssl时遇到下面问题 因此在网上找资料 参考网上一位大神介绍 原文链接如下 https blog csdn net trustbo article details 76851481
  • 打开Excle出现配置进度解决方法

    网上的最多的解决方案如果解决不了 想一下最近是不是安装或者卸载过WPS 以下是WPS导致配置进度的解决方案 安装Office之后 会发现每次打开excel都会出现一个配置进度的对话框 但是Word 和 PPT 都不会 这就说明你的电脑有安装
  • 【程序员面试金典】01.04. 回文排列

    回文排列 给定一个字符串 编写一个函数判定其是否为某个回文串的排列之一 回文串是指正反两个方向都一样的单词或短语 排列是指字母的重新排列 回文串不一定是字典当中的单词 示例 1 输入 tactcoa 输出 true 排列有 tacocat
  • MySQL经典50道练习题及全网最详细解析

    MySQL练习 文章目录 MySQL练习 50道经典SQL练习题全网最详细解析 数据表介绍 建表语句 插入数据 练习题目 1 查询 01 课程比 02 课程成绩高的学生的信息及课程分数 2 查询同时存在 01 课程和 02 课程的情况 3
  • TypeError: 'float' object is not callable

    今天在做一道Python练习题时遇到的问题 记录一下 请输入三个整数a b c 判断能否以它们为三个边长构成三角形 若能 输出YES和面积 否则输出NO 刚开始写的代码如下 a int input 请输入一个整数 b int input 请
  • Java实现图片上传返回上传地址

    关于在实际开发中最常用也是用的最多的Java实现文档 图片上传 一 准备阶段 文档 图片上传有几种方式 包括传统的ajax上传 云上传 这里给大家实现通过代码将图片上传至七牛云服务器并返回图片地址 1 需申请一台七牛云服务器地址 可免费试用