目录
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运行流程
总结
在前端页面,我们可以提交文件,点击提交以后,文件的路径会被传到控制层,然后将这个路径存到数据库中。
当我们想查询我们添加的文件时,页面会发送请求到控制层,执行查询业务,像数据库中查询我们的文件路径,如果是ajax异步请求,在控制层封装成json数据最后返回到前端页面。
(1)引入文件上传的依赖。
commons-fileupload
commons-fileupload
1.4
(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" %>
Title
<%--
method: 提交方式 文件上传必须为post提交。
enctype:默认application/x-www-form-urlencoded 表示提交表单数据
multipart/form-data:可以包含文件数据
input的类型必须为file类型,而且必须有name属性
--%>
(3)在springmvc中配置文件上传解析器
(3)创建upload01接口方法
@RequestMapping(value = "/upload01")
//注意:MultipartFile 参数名必须和中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("."));
(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" %>
Title
注意: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转换方法。
上传到本地服务器的缺点: 如果搭建集群,导致文件无法在集群中共享。 它的解决方法就是把文件专门上传到一个文件服务器上,这些tomcat服务器都操作同一个文件服务器。
(1)创建bucket容器
(2)在该bucket中通过网页面板的形式操作该bucket。但是实际开发我们应该通过java代码往bucket中上传文件。
文件上传到本地服务器的缺点?
1. 当服务器重启,本地服务的文件没了。
2. 搭建服务器集群。A服务器1000, B服务器.........
客户第一次上传时访问的是A服务器。
客户第二次访问文件,访问的是B服务器。
如何解决本地服务器上传的缺点:
(1)自己搭建一个文件服务器。不会重启。维护。
(2) 使用第三方的文件服务器.
(1)引入阿里云的OSS依赖
com.aliyun.oss
aliyun-sdk-oss
3.10.2
(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" %>
Title
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";
}
(1)前端
<%--
Created by IntelliJ IDEA.
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%--action:文件上传的路径--%>
(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";
}
(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" %>
Title
立即提交
(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);
}
}
@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提交 编码方式必须是二进制编码。
第一步:用户发送请求到前端控制器(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对象类型并@ResponseBody6. 全局异常处理.
创建一个类并使用@ControllerAdvice
该类中创建异常处理的方法@ExceptionHandler
7. 拦截器:
1.创建一个拦截器类并实现HandlerInterceptor接口。
2.重写preHandler方法。写拦截器的业务代码。
3.注册到springmvc容器上.
8. springmvc文件上传.
(1)本地服务器上传.-------服务重启后文件不见了. 多态服务器无法共享文件。
(2)上传到OSS服务器。