采用云存储上传下载文件

作者:19级学生程渝林

常规的文件下载处理基于JavaWeb

        常规的文件上传与下载,就是通过前端页面通过文件类型的表单, 发起请求传输到java后端 (注意表单里的数据类型必须是:enctype="multipart/form-data") 使用这种数据类型会把文件也写入表单,这样才能传入到后台 且前端传入时,携带的传入文件名,必须与后台接收到的一致 (待会以SpringBoot形式基于springmvc进行演示) 然后通过输入输出流方式,写进后台,并进行缓存区大小的设置, 创建文件夹目录,设置传输文件大小,判断文件大小,写入磁盘, 关闭流的一系列操作。

html表单:

<!DOCTYPE html >
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
​
​
<body>
​
<form action="/file/image" method="post"  enctype="multipart/form-data">
    <input type="file" name="file" value="请选择文件" multiple>
    <input type="submit" value="上传">
</form>
​
</body>
​
</html>

普通上传下载基于http请求的

@WebServlet(name = "FileUploadServlet",value = "/Upload")
@MultipartConfig
public class FileUploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("doPost");
        Part part=request.getPart("load");
        String path=request.getServletContext().getRealPath("image");
        System.out.println(path);
        String fileName=uploadFile(part,path);
        System.out.println("new");
        PrintWriter out=response.getWriter();
        out.println("<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"utf-8\">\n" +
                "    <title>Upload</title>\n" +
                "</head>\n"
        );
        out.println("<img src='image/"+fileName+"'/>");
        out.println("</body>\n" +
                "</html>");
​
    }
​
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
​
    }
    public String uploadFile(Part part,String path)throws IOException{
        System.out.println(part.getSubmittedFileName());
        InputStream inputStream = part.getInputStream();
​
        byte[] bytes = new byte[1024];
        int length=0;
​
        
        System.out.println(path);
        File file=new File(path);
        if(!file.exists()){
            file.mkdir();//创建目录
        }
        UUID uuid=UUID.randomUUID();
        String fileName=uuid.toString()+part.getSubmittedFileName();
        OutputStream outputStream=new FileOutputStream(file+"/"+fileName);
​
        while ((length=inputStream.read(bytes))!=-1){
            outputStream.write(bytes,0,length);
        }
        outputStream.close();
        inputStream.close();
​
        return fileName;
    }
}

下载:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet");
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream");
        String fileName = request.getParameter("file");
        response.setHeader("Content-Disposition","attachment;fileName="+fileName);
        OutputStream out=response.getOutputStream();
        //PrintWriter out=response.getWriter();
        String path=this.getServletContext().getRealPath("/images");
        File file=new File(path+"\\"+fileName);
        if(file.exists()){
            InputStream is=new BufferedInputStream(new FileInputStream(file));
            int len=0;
            byte[] buffer = new byte[200];
            while((len=is.read(buffer))!=-1){
                out.write(buffer,0,len);
                //out.print(new String(buffer,0,len));
            }
            is.close();
            out.close();
        }
    }

基于SpringBoot的文件上传下载

        前端同理,而SpringMvc自己封装了一个MultipartFile,点开MultipartFile的源文件,

MultipartFile是继承于InputStreamSource,

 并且该方法返回的是是inputstream类型,那么可以得知,其实MultipartFile就是以流的形式来处理文件的,实质上和刚刚所说的普通的以流的形式处理文件是一样的。具体的代码可以自行查看 那么知道了spring已经为我们封装好了文件处理方式,那么就来处理文件, 在用MultipartFile的对象将文件从前端传到后台,在MultipartFile对象中已经帮我们把文件进行处理过了,所以我们需要做的,就是判断文件是否传入,判断文件大小是否正常,还可以通过文件后辍判断文件是否是你所需要的文件类型,也可以将文件名进行处理,以此避免文件名重复,最后将你的文件传入你所指定的磁盘地址。同时这里也可以自定义创建文件夹保存。

结合刚刚的html代码就可以使用了

基于springmvc的文件下载

  
  //上传到的文件位置---非本地
    private String newFileName = null;
    private String fileType = null;
​
@RequestMapping("/upload")
    public Map<String, String> FileUpload(@RequestParam(name = "file", required = false)MultipartFile multipartFile) {
        Map<String, String> map = new HashMap<>();
        //文件不存在
        if (multipartFile == null) {
            map.put("msg", "请上传文件");
            return map;
        }
        //文件存在,获取文件名,文件地址
        String filename = multipartFile.getOriginalFilename();
        //控制文件大小
        Integer size = 1024 * 1024 * 10;
        if (multipartFile.getSize() > size) {
            map.put("msg", "文件不能超过10M");
            return map;
        }
        //重命名文件名
        String uuid = UUID.randomUUID().toString();
        //只支持JPG和PNG格式的文件类型
        String[] exName = {".jpg", ".png"};
        String ExtendName = filename.substring(filename.lastIndexOf("."));
        if(!(exName[0].equals(ExtendName)||exName[1].equals(ExtendName))){
            map.put("mag","不支持的文件类型");
            return map;
        }
        //拼接文件名
        newFileName=uuid.concat(ExtendName);
        String filePath = new File("").getAbsolutePath();
        File fileUpload = new File(filePath);
        if(!fileUpload.exists()){
            fileUpload.mkdirs();
        }
        fileUpload = new File(filePath,newFileName);
        try {
            multipartFile.transferTo(fileUpload);
            map.put("msg","上传成功");
            fileType=multipartFile.getContentType();
            map.put("fileType",fileType);
            return map;
        } catch (IOException e) {
            map.put("上传失败",e.toString());
        }
        return map;
    }

为什么不将文件存储在服务器或本机主机,为什么本机主机只进行文件的临时存储与上传下载?

        例如有用户传输文件给我,我如何处理这个文件?是将文件直接保存到本地,利用本地路径存储到数据库,等到前端需要展示时再通过其文件路径将文件展示出来吗?这是可以行的,但我认为,将工程和数据存储在一个服务器上是不合理的行为,这样能够减轻工程服务器压力,并且在使用时,本地服务器存储的图片是没有进行压缩的,如果服务器系统出现错误,容易出现数据出错或者丢失,并且大大减少了工程的可扩展性。在最初的我只是觉得以这种方式存储,在拿去文件的时候十分麻烦,并且不易存储。因为我存储图片都是以图床的形式去存储。 于是就有了云存储。

什么是云存储,为什么要使用云存储?好处?

        我的理解:在我查阅了资料过后,云存储其实也是服务器存储数据,云存储就是将数据放在云端。当然毕竟是在别人公司的服务器里,相对来说不是绝对安全的,但对于我们学习和开发使用,我觉得是非常不错的。 在这里,我们将文件类的大型数据放在云存储里,减少了我们工程服务器的压力,并且云存储会将图片进行压缩,将图片放在云端,以图床形式返回给我们。 最重要的是,他以图床的形式返回给我们,能以更方便的形式存储在数据库中。 就是专门用来存放图片,同时允许你把图片对外连接的网上空间,实际上是一个链接,访问连接得到图片。 比如: http://baidu.com/6plmqdj5bcr

使用云存储

首先我们要了解云存储的结构,阿里云,腾讯云,七牛云都可以。这里我以七牛云举例。 创建存储空间:在七牛云的控制台中:

存储区域可以选择默认 

        这里首先提一点,没有域名的就使用他提供的测试域名,有备案域名的,使用自己的 备案域名,域名仅仅是访问图片地址的地址,没有域名的也不要有压力。 打开空间管理=>文件管理=>点击上传文件,上传成功后,会有一个地址,打开地址, 就能看到自己上传的图片了。 那么问题来了,java如何上传图片呢?返回给我的地址如何获取呢? 在这里首先我们要了解一个东西叫http请求,对就是计算机网络教的http请求, 但是在这里我们是需要用java去进行http请求。 然后我们要了解SDK,什么是SDK?就是软件开发工具包,在java的maven仓库里就是我 们的dependency依赖。我使用的是七牛云的云存储,那么相应的要使用七牛云的JAVA SDK

        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>7.10.2</version>
        </dependency>

七牛云JavaSDK文档:https://developer.qiniu.com/linking/6279/linking-java-sdk

利用Java对七牛云存储获取token接口

什么是token?

        token简单理解就是对七牛云存储上传所需要的密钥也就是上传凭证,深度理解就是通过七牛云空间的用户id和密码生成的base64加密数据,具体的封装过程七牛云的SDK已经为我们封装好。

获取token:

        这里了解两个东西: 在七牛云的个人中心=>密钥管理中,有这两个密钥 accessKey secretKey这是每个用户都会有的独特的密码,通过密码获取上传凭证token,当然并不是只有这两个还有你的上传地址。这里上传地址并不是你访问的测试地址,而是你的空间名,注意我最开始截图画的重点,空间名。 我们获取token需要向七牛云服务端获取这几个参数: accessKey secretKey bucket:你的空间名

在有了这三个参数的时候,我们就可以获取token了

代码:

七牛实体类:

@Data
public class QiNiu {
    private String token;
    private String key;
}

获取token

    QiNiu qiNiu = new QiNiu();
​
​
    // 获取 七牛云的 token
    @RequestMapping(value = "/getToken", method = RequestMethod.GET)
    public String getToken() {
        String accessKey = "自己的accessKey";
        String secretKey = "自己的secretKey";
        String bucket = "自己的空间名";
        long expireSeconds = 600;   //过期时间
        StringMap putPolicy = new StringMap();
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket,null,expireSeconds,putPolicy);
        qiNiu.setKey(UUID.randomUUID().toString().replaceAll("\\-", ""));
        qiNiu.setToken(upToken);
        return qiNiu.getToken();
    }

最后返回String类型的uptoken为了防止token被滥用,我们可以将token进行json格式的封装,用uuid设置上传的指定的key,最后再返回,我这里省的麻烦,就直接拿来用了。 我们已经获取到token了,就可以携带token参数对七牛云存储空间进行文件上传并进行访问了

本地上传文件到七牛

 @GetMapping(value = "/qiniu/upload")
    public Result UpLoad(){
        Result result = new Result();
        Configuration cfg = new Configuration(Region.huanan());//Region.huanan()对应自己的存储区域
        UploadManager uploadManager = new UploadManager(cfg);
        String token=qiNiu.getToken();
        String key=qiNiu.getKey();
        String url="";//这里是你的域名地址
        String filePath="你电脑的图片地址";
        try {
            Response response = uploadManager.put(filePath,key,token);
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
            String imageUrl=url+putRet.key;
            result.setData(imageUrl);
            return result;
        } catch (QiniuException e) {
            e.printStackTrace();
            result.setMessage("err");
            return result;
        }
    }

这里返回的key就是我们的文件名,例如滑稽.jpg 所以最后拼接上我们的域名地址就是我们的图片地址了。 当然 我们也可以不用本地文件上传,而是让文件传来的过程中,将文件缓存在服务器,利用流形式,将文件转成二进制,再将文件上传至七牛云,也是可以的。

返回的Result数据类型

package com.school.commons;
​
import lombok.Data;
​
/**
 * 统一响应结果集
 *
 */
@Data
public class Result<T> {
​
    //操作代码
    Integer code;
​
    //提示信息
    String message;
​
    //结果数据
    T data;
​
    public Result() {
    }
​
    public Result(ResultCode resultCode) {
        this.code = resultCode.code();
        this.message = resultCode.message();
    }
​
    public Result(ResultCode resultCode, T data) {
        this.code = resultCode.code();
        this.message = resultCode.message();
        this.data = data;
    }
​
    public Result(String message) {
        this.message = message;
    }
​
    public static Result SUCCESS() {
        return new Result(ResultCode.SUCCESS);
    }
​
    public static <T> Result SUCCESS(T data) {
        return new Result(ResultCode.SUCCESS, data);
    }
​
    public static Result FAIL() {
        return new Result(ResultCode.FAIL);
    }
​
    public static Result FAIL(String message) {
        return new Result(message);
    }
​
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
华为OBS(Object Storage Service)是一种可扩展的云存储服务,通过它可以方便地进行文件的存储、备份和批量上传等操作。 要实现华为OBS文件的批量上传,我们可以采用以下步骤: 1. 首先,需要在华为上创建一个OBS存储桶。在华为控制台中,选择OBS服务,然后点击创建存储桶,并根据需要配置存储桶的相关参数。 2. 在本地计算机上准备好需要上传的文件,可以将这些文件放在同一个文件夹中,方便进行批量操作。 3. 接下来,可以使用华为提供的OBS SDK,根据编程语言的不同选择相应的SDK版本。一般可以通过安装SDK的方式,引入SDK到项目中。 4. 在代码中,首先需要进行OBS的验证,即提供访问华为账号的认证信息(Access Key和Secret Key),以便进行API调用。 5. 在验证通过之后,可以使用SDK提供的方法,选择需要上传的文件路径和OBS存储桶的名称等相关参数。然后使用循环或批量操作的方式,依次上传文件。 6. 上传过程中,可以监听上传的进度和状态,以便得知文件上传是否成功。 7. 完成文件上传后,可以通过华为控制台,或者使用OBS SDK提供的API方法,查看已上传的文件。 总的来说,华为OBS文件的批量上传可以通过使用OBS SDK来实现,在代码中调用相应的API方法,依次上传文件即可。通过这种方式,可以提高上传效率,简化操作步骤,方便批量上传大量文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值