springmvc文件上传

1. 文件上传的原理

2. 文件上传到本地服务器

(1)文件上传的依赖。

    <!--文件上传的依赖-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>

(2) 创建一个页面

<%--
  Created by IntelliJ IDEA.
  User: myL
  Date: 2022/6/10
  Time: 8:45
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <%--
        method:必须post提交
        enctype:multipart/form-data 可以包含文件数据
        input:必须file类型 必须有name属性
    --%>
<form method="post" action="upload01" enctype="multipart/form-data">
<input type="file" name="myfile"/><br/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

 (3)在springmvc中配置文件上传解析器

<!--
上传文件拦截器
id必须为:multipartResolver
单位为字节
-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760"/>
    </bean>
</beans>

(3) 创建upload01接口方法

 @RequestMapping("/upload01")
    //注意:MultipartFile 参数名必须和<input type="file" name="myfile"/>中name相同
    public String upload01(MultipartFile myfile, HttpServletRequest request) throws IOException {
        //1.得到本地服务目录的地址
        String path = request.getSession().getServletContext().getRealPath("upload");
        System.out.println(path);
        //2.判断该目录是否存在
        File file = new File(path);
        if (!file.exists()) {
        file.mkdirs();
        }
        //3.把myfile保存到本地文件夹中
        //随机一个文件名字
        String filename= UUID.randomUUID().toString().replace("-","")+myfile.getOriginalFilename();
        File target=new File(path+"/"+filename);
        //把file转到目标目录下
        myfile.transferTo(target);
        return "";
    }

3. elementui+vue+axios完成文件上传

(1)页面的布局

<%--
  Created by IntelliJ IDEA.
  User: myL
  Date: 2022/6/10
  Time: 9:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <!--引入element得css样式-->
    <link type="text/css" rel="stylesheet" href="css/index.css"/>
    <!--引入vue得js文件 这个必须在element之前引入-->
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript" src="js/qs.min.js"></script>
    <script type="text/javascript" src="js/axios.min.js"></script>
    <!--element得js文件-->
    <script type="text/javascript" src="js/index.js"></script>
</head>
<body>
    <div id="app">
        <%--action:文件上传的路径--%>
        <el-upload
                class="avatar-uploader"
                action="/upload02"
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload">
            <img v-if="imageUrl" :src="imageUrl" class="avatar">
            <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
    </div>
</body>
<script>
     var app=new Vue({
           el:"#app",
           data:{
               imageUrl:"",
           },
           methods:{
               //上传成功后触发的方法
               handleAvatarSuccess(res, file) {
                   this.imageUrl=res.data;
               },
               //上传前触发的方法
               beforeAvatarUpload(file) {
                   const isJPG = file.type === 'image/jpeg';
                   const isPNG = file.type === 'image/png';
                   const isLt2M = file.size / 1024 / 1024 < 2;
                   if (!isJPG) {
                       this.$message.error('上传头像图片只能是 JPG 格式!');
                   }
                   if (!isLt2M) {
                       this.$message.error('上传头像图片大小不能超过 2MB!');
                   }
                   return isJPG && isLt2M;
               }
           }
     })
</script>

<style>
    .avatar-uploader .el-upload {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
    }
    .avatar-uploader .el-upload:hover {
        border-color: #409EFF;
    }
    .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 178px;
        height: 178px;
        line-height: 178px;
        text-align: center;
    }
    .avatar {
        width: 178px;
        height: 178px;
        display: block;
    }
</style>
</html>

(2)后台的接口

4. 上传到oss阿里云的服务器

上传到本地服务器的缺点: 如果搭建集群,导致文件无法在集群中共享。 它的解决方法就是把文件专门上传到一个文件服务器上,这些tomcat服务器都操作同一个文件服务器。

4.1 申请oss文件服务

4.2 在oss界面上操作文件上传

*(1)创建bucket容器

可以在该bucket中通过网页面板的形式操作该bucket.

但是实际开发我们应该通过java代码往bucket中上传文件。

4.3 申请阿里云的密钥

 5. 普通的文件上传到OSS文件服务器

(1)引入阿里云的OSS依赖

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

(2)代码的书写

 

 

 @RequestMapping("upload02")
    public String upload02(MultipartFile file,HttpServletRequest request){
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI5tLDkC3FPJ4P1W5iJv7K";
        String accessKeySecret = "zGrwc7w6mlvQH6NEcNeslPZgulGDo7";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "lmy111";
        //你上传到oss后的名字 会根据日期帮你创建文件夹
        Calendar calendar = Calendar.getInstance();
        String objectName = calendar.get(Calendar.YEAR)+"/"+(calendar.get(Calendar.MONTH)+1)+"/"+calendar.get(Calendar.DATE)+
                UUID.randomUUID().toString().replace("-","")+
                file.getOriginalFilename();
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            InputStream inputStream =  file.getInputStream();
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }  finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        //https://qy151.oss-cn-hangzhou.aliyuncs.com/2022/6/10/20d3d7e6b5bb455cb548675501f7270fgdnj.jpg
        String url = "https://"+bucketName+"."+endpoint+"/"+objectName;
        request.setAttribute("imgUrl",url);
        return "success.jsp";
    }

6. elementui 异步上传OSS服务器

(1)前端

<%--
  Created by IntelliJ IDEA.
  User: myL
  Date: 2022/6/10
  Time: 13:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <link type="text/css" rel="stylesheet"href="css/index.css"/>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript" src="js/axios.min.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
    <script type="text/javascript" src="js/qs.min.js"></script>
</head>
<body>
<div id="app">
    <el-upload
    <%--
         action:文件上传的路径
         handleAvatarSuccess:上传成功后触发的方法
         beforeAvatarUpload:上传前触发的方法

    --%>
            class="avatar-uploader"
            action="upload02"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload">

        <img v-if="imageUrl" :src="imageUrl" class="avatar">
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
</div>
</body>
<script>
    var app = new Vue({
        el:"#app",
        data:{
            imageUrl:"",
        },
        methods: {
            handleAvatarSuccess(res, file) {
                console.log(res);
                this.imageUrl=res.data;
            },
            beforeAvatarUpload(file) {
                const isJPG = file.type === 'image/jpeg';
                const isLt2M = file.size / 1024 / 1024 < 2;

                if (!isJPG) {
                    this.$message.error('上传头像图片只能是 JPG 格式!');
                }
                if (!isLt2M) {
                    this.$message.error('上传头像图片大小不能超过 2MB!');
                }
                return isJPG && isLt2M;
            }
        }
    })
</script>

<style>
    .avatar-uploader .el-upload {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
    }
    .avatar-uploader .el-upload:hover {
        border-color: #409EFF;
    }
    .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 178px;
        height: 178px;
        line-height: 178px;
        text-align: center;
    }
    .avatar {
        width: 178px;
        height: 178px;
        display: block;
    }
</style>
</html>

(2)后端工具:  

package com.lmy.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.Calendar;
import java.util.UUID;

public class OSSUtils {
    public static String upload(MultipartFile file){
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI5tLDkC3FPJ4P1W5iJv7K";
        String accessKeySecret = "zGrwc7w6mlvQH6NEcNeslPZgulGDo7";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "lmy111";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如0.
        // exampledir/exampleobject.txt。


        String objectName = filename(file);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            InputStream inputStream =  file.getInputStream();
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }  finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        String url = "https://"+bucketName+"."+endpoint+"/"+objectName;
        return  url;
    }
    //获取上传到oss后的名字
    private static String filename(MultipartFile file){
        Calendar calendar = Calendar.getInstance();
        String name = calendar.get(Calendar.YEAR)+"/"+(calendar.get(Calendar.MONTH)+1)+"/"+calendar.get(Calendar.DATE)+
                UUID.randomUUID().toString().replace("-","")+
                file.getOriginalFilename();
        return name;
    }
}

(3) controller接口

@RequestMapping("upload02")
@ResponseBody
    public Map upload02(MultipartFile file){
    try {
        String url = OSSUtils.upload(file);
        Map map = new HashMap();
        map.put("code",2000);
        map.put("msg","上传成功");
        map.put("data",url);
        return map;
    }catch (Exception e){
        e.printStackTrace();
    }
    HashMap map = new HashMap();
    map.put("code",5000);
    map.put("msg","上传失败");
    return map;
}

7. 保存用户信息--头像

(1)前端的布局

<%--
  Created by IntelliJ IDEA.
  User: myL
  Date: 2022/6/10
  Time: 19:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <link type="text/css" rel="stylesheet"href="css/index.css"/>
    <script type="text/javascript" src="js/vue.js"></script>
    <script type="text/javascript" src="js/axios.min.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
    <script type="text/javascript" src="js/qs.min.js"></script>
</head>
<body>
<div id="app">
    <el-form  label-width="80px" :model="userForm">
        <el-form-item label="头像:">
            <el-upload
                    class="avatar-uploader"
                    action="user/uploadAvatar"
                    :show-file-list="false"
                    :on-success="handleAvatarSuccess"
                    :before-upload="beforeAvatarUpload">
                <img v-if="imageUrl" :src="imageUrl" class="avatar">
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
            </el-upload>
        </el-form-item>
        <el-form-item label="账号:">
            <el-input v-model="userForm.name"></el-input>
        </el-form-item>
        <el-form-item label="密码:">
            <el-input v-model="userForm.pwd"></el-input>
        </el-form-item>
        <el-form-item label="地址:">
            <el-input v-model="userForm.address"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="onSubmit">提交</el-button>
        </el-form-item>
    </el-form>
</div>
</body>
<script>
    var app=new Vue({
        el:"#app",
        data:{
            userForm:{},
            imageUrl:"",
        },
        methods:{
            handleAvatarSuccess(result,file){
                this.imageUrl=result.data;
                //为表单添加头像地址
                this.userForm.avatarUrl=result.data;
            },
            //提交
            onSubmit(){
                //console.log(this.userForm);
                axios.post("user/addUser",this.userForm).then(function (result){

                });
            },
            beforeAvatarUpload(file) {
                const isJPG = file.type === 'image/jpeg';
                const isLt2M = file.size / 1024 / 1024 < 2;

                if (!isJPG) {
                    this.$message.error('上传头像图片只能是 JPG 格式!');
                }
                if (!isLt2M) {
                    this.$message.error('上传头像图片大小不能超过 2MB!');
                }
                return isJPG && isLt2M;
            }
        }
    })
</script>

<style>
    .avatar-uploader .el-upload {
        border: 1px dashed #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
    }
    .avatar-uploader .el-upload:hover {
        border-color: #409EFF;
    }
    .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 178px;
        height: 178px;
        line-height: 178px;
        text-align: center;
    }
    .avatar {
        width: 178px;
        height: 178px;
        display: block;
    }
</style>
</html>

(2)后台代码

package com.lmy.controller;

import com.lmy.user.User;
import com.lmy.utils.CommonResult;
import com.lmy.utils.OSSUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
//该注解下的所有方法都是返回json方法
@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("uploadAvatar")
    public CommonResult uploadAvatar(MultipartFile file){
    try {
        String avatar = OSSUtils.upload(file);
        return  new CommonResult(2000,"上传成功",avatar);
    }catch (Exception e){
        e.printStackTrace();
    }
    return new CommonResult(5000,"上传失败",null);
}

 //@RequestBody:把请求体中json数据转换为java对象
@RequestMapping("addUser")
    public CommonResult addUser(@RequestBody User user){
    System.out.println(user);
    // 调用dao完成保存到数据库

    return  new CommonResult(2000,"成功",null);
}
}

8. 其他的注解

@RestController----类上等价于 @COntroller+@ResponseBody
    该注解下所有的方法都是返回json数据
    
@RequestMapping: 作用: 把请求路径映射到响应的方法上。 

@RequestParam(value = "u"):设置你接受的请求参数名。查询参数

@RequestMapping(value = "/addUser",method = RequestMethod.POST)
       method:表示该接口接受的请求方式.不设置可以接受任意请求方式。
       
@GetMapping("addUser"):表示只接受get提交方式的请求     

@RequestBody:把请求的json数据转换为java对象。从前端到后端
@ResponseBody:把java转换为json数据   从后端转前端

 

 


版权声明:本文为qq_59114219原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>