Springmvc框架-----3 文件上传

本文详细介绍了文件上传的原理,包括前端提交文件、后端接收并存储到本地服务器,以及使用Element UI和Vue.js实现异步上传。进一步讨论了本地服务器上传的局限性,如集群环境下文件共享问题,并提出使用阿里云OSS作为解决方案。通过实例展示了如何注册阿里云OSS服务,创建bucket,并通过Java代码上传文件。最后,整合Element UI实现上传到OSS的前端交互,以及保存用户信息时上传头像的综合案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.文件上传的原理

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

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

4.注册阿里云服务器并将文件上传到OSS

 4.1 申请OSS文件服务

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

4.3 申请阿里云的密钥

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

6. elementui 异步上传OSS服务器

7. 保存用户信息--头像(综合案例)

8.其他注解

9.Springmvc运行流程

总结


1.文件上传的原理

在前端页面,我们可以提交文件,点击提交以后,文件的路径会被传到控制层,然后将这个路径存到数据库中。

        当我们想查询我们添加的文件时,页面会发送请求到控制层,执行查询业务,像数据库中查询我们的文件路径,如果是ajax异步请求,在控制层封装成json数据最后返回到前端页面。
 

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

(1)引入文件上传的依赖。

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

(2) 创建一个页面

<%--
  Created by IntelliJ IDEA.
  User: w
  Date: 2022/6/9
  Time: 19:57
  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:默认application/x-www-form-urlencoded 表示提交表单数据
              multipart/form-data:可以包含文件数据

      input的类型必须为file类型,而且必须有name属性
   --%>
    <form action="upload01" method="post" enctype="multipart/form-data">
        <input type="file" name="myfile"/>
        <input type="submit" value="确定"/>
    </form>
</body>
</html>

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

   <!--
     id的名称必须叫multipartResolver
     -->
     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <!--这里的单位为字节10M*1024K*1024-->
          <property name="maxUploadSize" value="10485760"/>
     </bean>

(3)创建upload01接口方法

@RequestMapping(value = "/upload01")
    //注意:MultipartFile 参数名必须和<input type="file" name="myfile"/>中name属性相同
    public String upload01(MultipartFile myfile, HttpServletRequest request) throws  Exception{
        try {
            //获取本地服务器目录的地址
            String path = request.getSession().getServletContext().getRealPath("upload");
            //判断该目录是否存在
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            //把myfile保存到本地服务器中某个文件夹下
            String filename = UUID.randomUUID().toString().replace("-", "") + myfile.getOriginalFilename();//生成随机数 为了让名字不重复
            File target = new File(path +"/"+ filename);
            myfile.transferTo(target);//把myfile转移到目标目录下
        }catch (Exception e){
            e.printStackTrace();
        }
        return  "";
    }

UUID.randomUUID()   

//随机生成一个字符串 这个字符串一定不会重复

下面的也可以   目的都是为了让文件名不重复

Date date = new Date();

 String filename = date.getTime()+ myfile.getOriginalFilename();        //date.getTime() 时间戳

生成不重复的名称

String filename = date.getTime() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));

                                                

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

(1)页面的布局

<%--
  Created by IntelliJ IDEA.
  User: w
  Date: 2022/6/9
  Time: 20:25
  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">
        <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>
<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>

<script>
        var app = new Vue({
            el:"#app",
            data:{
                imageUrl:"",
            },
            methods: {
                handleAvatarSuccess(res, file) {
                    alert("bbb")
                    //console.log(res)
                    this.imageUrl = res.data;
                },
                beforeAvatarUpload(file) {
                    alert("aaa");
                    const isJPG = file.type === 'image/jpeg';
                    const isPNG = file.type === 'image/png';
                    const isLt2M = file.size / 1024 / 1024 < 10;

                    if (!isJPG&&!isPNG) {
                        this.$message.error('上传头像图片只能是 JPG 格式或 PNG 格式!');
                    }
                    if (!isLt2M) {
                        this.$message.error('上传头像图片大小不能超过 10MB!');
                    }
                    return (isJPG||isPNG) && isLt2M;
                }
            }
        })

</script>
</html>

注意:elementui中提交文件的表单 中的name属性默认为file。 

(2)后台的接口

    @RequestMapping(value = "/upload02")
    @ResponseBody
    public CommonResult upload02(MultipartFile file,HttpServletRequest request){
        try{

            //获取本地服务器目录的地址
            String path = request.getSession().getServletContext().getRealPath("upload");
            System.out.println(path);
            //判断该目录是否存在
            File file1 = new File(path);
            if(!file1.exists()){
                file1.mkdirs();
            }
            //把file保存到保存到本地服务器某个文件夹下
            String filename = UUID.randomUUID().toString().replace("-","")+file.getOriginalFilename();//设置上传后的文件名称
            System.out.println(filename);
            File target = new File(path+"/"+filename);
            file.transferTo(target);
            //通过访问服务器地址来访问图片
            String data = "http://localhost:8080/Springmvc0609_2/upload/"+filename;
            CommonResult commonResult = new CommonResult(2000,"上传成功",data);
            return commonResult;
        }catch (Exception e){
            e.printStackTrace();
        }
        CommonResult commonResult = new CommonResult(2000,"上传失败",null);
        return commonResult;
    }

注意:前端发送的是axios异步请求,后端必须响应给前端一个json格式数据。@ResponseBody注解为springmvc中的jackson的jar包内置的json转换方法。

4.注册阿里云服务器并将文件上传到OSS

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

 4.1 申请OSS文件服务

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

(1)创建bucket容器

  (2)在该bucket中通过网页面板的形式操作该bucket。但是实际开发我们应该通过java代码往bucket中上传文件。

4.3 申请阿里云的密钥

文件上传到本地服务器的缺点?

1. 当服务器重启,本地服务的文件没了。
2. 搭建服务器集群。A服务器1000, B服务器......... 
    客户第一次上传时访问的是A服务器。
    客户第二次访问文件,访问的是B服务器。

如何解决本地服务器上传的缺点:

(1)自己搭建一个文件服务器。不会重启。维护。

(2) 使用第三方的文件服务器.

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

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

 

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

(2)代码的书写。

前端:

<%--
  Created by IntelliJ IDEA.
  User: w
  Date: 2022/6/10
  Time: 21:35
  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>
    <form action="/user/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="file">
        <input type="submit" value="提交">
    </form>
</body>
</html>

controller: 

实际开发中,添加新功能时,先创建个测试类,测试成功后再添加到项目上,否则项目会改的一塌糊涂。

@RequestMapping("/upload03")
    public String upload03(MultipartFile myfile,HttpServletRequest request){
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";

      
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI78XQAZq";    //你的密钥
        String accessKeySecret = "qdyZxR0x4Lo";    //密码
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "wzh666";
        //你上传到oss后的名字 会根据日期帮你创建文件夹。
        Calendar calendar=Calendar.getInstance();
        String objectName =calendar.get(Calendar.YEAR)+"/"+(calendar.get(Calendar.MONTH)+1)+"/"+
                calendar.get(Calendar.DATE)+"/"+UUID.randomUUID().toString().replace("-","")+
                myfile.getOriginalFilename();

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

        try {
            InputStream inputStream =myfile.getInputStream();
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception oe) {

        } 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.

  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="/upload04"
                :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)后端工具:

package com.wzh.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 myfile){
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";

        
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI7";
        String accessKeySecret = "qdyZxbcrhEyw7H";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "wzh666";
        //你上传到oss后的名字 会根据日期帮你创建文件夹。
        String objectName =fileName(myfile);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            InputStream inputStream =myfile.getInputStream();
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception oe) {

        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        
        String url="https://"+bucketName+"."+endpoint+"/"+objectName;
        return url;
    }

    //获取上传到oss后的名字
    private static String fileName(MultipartFile myfile){
        Calendar calendar=Calendar.getInstance();
        String name=calendar.get(Calendar.YEAR)+"/"+(calendar.get(Calendar.MONTH)+1)+"/"+
                calendar.get(Calendar.DATE)+"/"+ UUID.randomUUID().toString().replace("-","")+
                myfile.getOriginalFilename();

        return name;
    }
}

(3) controller接口

@RequestMapping(value = "/upload")
@ResponseBody
    public String upload11(MultipartFile file){
        String imgUrl = OSSUtils.upload(file);
        return "success.jsp";
    }

7. 保存用户信息--头像(综合案例)

(1)前端的布局

<%--
  Created by IntelliJ IDEA.
  User: w
  Date: 2022/6/10
  Time: 20:27
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <link rel="stylesheet" type="text/css" 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 ref="form" :model="userForm" label-width="80px" size="mini">
            <el-form-item label="头像:">
                <el-upload
                        class="avatar-uploader"
                        action="/user/avatarUpload"
                        :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.age"></el-input>
            </el-form-item>
            <el-form-item label="性别:">
                <el-input v-model="userForm.sex"></el-input>
            </el-form-item>

            <el-form-item size="large">
                <el-button type="primary" @click="onSubmit">立即提交</el-button>
            </el-form-item>
        </el-form>
    </div>
    <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>
</body>
<script>
    var app = new Vue({
        el:"#app",
        data:{
            userForm:{},
            imageUrl:""
        },
        methods:{
            onSubmit(){
                axios.post("/user/add",this.userForm).then(function (result){

                });
            },
            handleAvatarSuccess(res, file) {
                this.imageUrl = res.data;
                this.userForm.avatarUrl = this.imageUrl;
            },
            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>
</html>

(2)工具类

package com.wzh.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;

/**
 * @ProjectName: springmvc0610_4
 * @Package: com.wzh.utils
 * @ClassName: OSSUtils
 * @Author: 王振华
 * @Description:
 * @Date: 2022/6/10 21:19
 * @Version: 1.0
 */
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 = "LTAI5tBPAR";
        String accessKeySecret = "RtitGXAuK0yDtzfshVct";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "wzh666";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。

        String objectName = filename(file);
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。

        // 创建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 imgURL = "https://"+bucketName+"."+endpoint+"/"+objectName;
        return imgURL;
    }

    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)后台代码

package com.wzh.controller;

import com.wzh.entity.User;
import com.wzh.utils.CommonResult;
import com.wzh.utils.OSSUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

/**
 * @ProjectName: springmvc0610_4
 * @Package: com.wzh.controller
 * @ClassName: UserController
 * @Author: 
 * @Description:
 * @Date: 2022/6/10 20:23
 * @Version: 1.0
 */
@Controller
@RequestMapping(value = "/user")
public class UserController {
    @RequestMapping(value = "/avatarUpload")
    @ResponseBody
    public CommonResult upload(MultipartFile file){
        String imgUrl = OSSUtils.upload(file);
        return new CommonResult(2000,"上传成功",imgUrl);
    }

    @RequestMapping(value = "/add")
    @ResponseBody
    public CommonResult add(@RequestBody User user){
        System.out.println(user);
        return new CommonResult(2000,"提交成功",null);
    }

   
}

8.其他注解

@RestController----类上等价于 @Controller+@ResponseBody
    该注解下所有的方法都是返回json数据

 

@RequestMapping: 作用: 把请求路径映射到响应的方法上。 

 要与action一致

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

 

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

@ResponseBody:把java转换为json数据   从后端转前端

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

@PostMapping("addUser"):表示只接受postt提交方式的请求 

上下两者一样的效果

 

注意:  文件上传必须用post   表单必须是post提交  编码方式必须是二进制编码。

9.Springmvc运行流程

第一步:用户发送请求到前端控制器(DispatcherServlet)。

第二步:前端控制器请求 HandlerMapping 查找 Handler,可以根据 xml 配置、注解进行查找。

第三步: 处理器映射器 HandlerMapping 向前端控制器返回 Handler

第四步:前端控制器调用处理器适配器去执行 Handler

第五步:处理器适配器执行 Handler

第六步:Handler 执行完成后给适配器返回 ModelAndView

第七步:处理器适配器向前端控制器返回 ModelAndView

    ModelAndView 是SpringMVC 框架的一个底层对象,包括 Model 和 View

第八步:前端控制器请求试图解析器去进行视图解析

    根据逻辑视图名来解析真正的视图。

第九步:试图解析器向前端控制器返回 view

第十步:前端控制器进行视图渲染

    就是将模型数据(在 ModelAndView 对象中)填充到 request 域

第十一步:前端控制器向用户响应结果

总结

1. springmvc框架:----可以帮你完成请求参数的封装以及返回json数据和网页跳转。
2. springmvc如何搭建。依赖,配置文件,web.xml
3. springmvc如何接受请求的参数。
      [1]单个参数--方法中生成这个参数名
      [2]多个参数--封装一个java实体类,方法中声明该实体类即可。
      [3]接受的为日期类型参数.在实体的位置@DatetimeFormat 
4. springmvc如何保存数据到网页: request,session ,model
5. springmvc如何响应json数据。
    1.依赖jackson
    2.方法的返回类型为java对象类型并@ResponseBody

6. 全局异常处理.
     创建一个类并使用@ControllerAdvice
     该类中创建异常处理的方法@ExceptionHandler
7. 拦截器:
    1.创建一个拦截器类并实现HandlerInterceptor接口。
    2.重写preHandler方法。写拦截器的业务代码。
    3.注册到springmvc容器上.
    
8. springmvc文件上传.
    (1)本地服务器上传.-------服务重启后文件不见了. 多态服务器无法共享文件。
    (2)上传到OSS服务器。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值