一:需求背景.
Web系统开发中,文件上传是非常常见的功能,本来也没啥好说的,就是通过IO流将文件写到另外一个地方,这个地方可以是
1. 项目的目录中的某个文件夹.
2. 本地盘符的某个文件下.
3. 云服务OSS里面.例如七牛云,OSS等.
4. FastDSF的分布式文件存储系统.
本次使用阿里云OSS为例介绍一下吧.
二:环境搭建
1. SpringBoot框架.Thymeleaf.BootStrap.开通的阿里云OSS空间.买云服务器会送一定的空间.
新建一个空间(符合命名规范即可)那个Access Key就是这个Bucket的一下授权信息.使用第三方服务必用的.
2. Maven依赖(Thymeleaf,SpringBoot的热部署,lombok)
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-devtools true com.aliyun.oss aliyun-sdk-oss 2.4.0 commons-fileupload commons-fileupload 1.3.1 org.projectlombok lombok 1.16.18
3. 准备一下上传成功的提示图片嘛.当然使用Ajax是比较好的.
三. 源码如下
1. application-dev.properties(由于使用的是多个环境下的properties,这里是开发环境.)
#OSS配置 lximage.endpoint=你的endPoint(见控制台) lximage.keyid=你的keyid lximage.keysecret=你的keysecret lximage.bucketname1=你新建的bucket的名字 lximage.filehost=你的目录我做测试的是file(就是一个根目录嘛)
2.配置类(JAVA配置类获取配置文件里面的信息)
@Getter @Setter @Component @Configuration public class ConstantConfig { @Value("${lximage.endpoint}") private String LXIMAGE_END_POINT; @Value("${lximage.keyid}") private String LXIMAGE_ACCESS_KEY_ID; @Value("${lximage.keysecret}") private String LXIMAGE_ACCESS_KEY_SECRET; @Value("${lximage.filehost}") private String LXIMAGE_FILE_HOST; @Value("${lximage.bucketname1}") private String LXIMAGE_BUCKET_NAME1; }
3. 工具类
AliyunOSSUtil
@Component public class AliyunOSSUtil { @Autowired private ConstantConfig constantConfig; private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class); /** 上传文件*/ public String upLoad(File file){ logger.info("------OSS文件上传开始--------"+file.getName()); String endpoint=constantConfig.getLXIMAGE_END_POINT(); System.out.println("获取到的Point为:"+endpoint); String accessKeyId=constantConfig.getLXIMAGE_ACCESS_KEY_ID(); String accessKeySecret=constantConfig.getLXIMAGE_ACCESS_KEY_SECRET(); String bucketName=constantConfig.getLXIMAGE_BUCKET_NAME1(); String fileHost=constantConfig.getLXIMAGE_FILE_HOST(); SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); String dateStr=format.format(new Date()); // 判断文件 if(file==null){ return null; } OSSClient client=new OSSClient(endpoint, accessKeyId, accessKeySecret); try { // 判断容器是否存在,不存在就创建 if (!client.doesBucketExist(bucketName)) { client.createBucket(bucketName); CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead); client.createBucket(createBucketRequest); } // 设置文件路径和名称 String fileUrl = fileHost + "/" + (dateStr + "/" + UUID.randomUUID().toString().replace("-", "") + "-" + file.getName()); // 上传文件 PutObjectResult result = client.putObject(new PutObjectRequest(bucketName, fileUrl, file)); // 设置权限(公开读) client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead); if (result != null) { logger.info("------OSS文件上传成功------" + fileUrl); } }catch (OSSException oe){ logger.error(oe.getMessage()); }catch (ClientException ce){ logger.error(ce.getErrorMessage()); }finally{ if(client!=null){ client.shutdown(); } } return null; } }
4. 上传控制器
@Controller public class UpLoadController { private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass()); private static final String TO_PATH="upLoad"; private static final String RETURN_PATH="success"; @Autowired private AliyunOSSUtil aliyunOSSUtil; @RequestMapping("/toUpLoadFile") public String toUpLoadFile(){ return TO_PATH; } /** 文件上传*/ @RequestMapping(value = "/uploadFile") public String uploadBlog(@RequestParam("file") MultipartFile file) { logger.info("文件上传"); String filename = file.getOriginalFilename(); System.out.println(filename); try { if (file!=null) { if (!"".equals(filename.trim())) { File newFile = new File(filename); FileOutputStream os = new FileOutputStream(newFile); os.write(file.getBytes()); os.close(); file.transferTo(newFile); // 上传到OSS String uploadUrl = aliyunOSSUtil.upLoad(newFile); } } } catch (Exception ex) { ex.printStackTrace(); } return RETURN_PATH; } }
5. 上传页面
html>
xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
charset="UTF-8">
【基于OSS的上传文件页面】
rel="stylesheet" th:href="@{/css/bootstrap.min.css}" media="all">
align="center">
style="color:orangered;">基于OSS的上传文件页面
6. 上传成功页面
html>
xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
charset="UTF-8">
【文件上传成功页面】
align="center">
上传成功
src="images/true.jpg" />
四:运行结果
控制台查看图片
2018-07-09 22:13:07.660 INFO 30080 --- [nio-8082-exec-4] c.l.myvideo.controller.UpLoadController : ============>文件上传
star.jpg
2018-07-09 22:13:07.667 INFO 30080 --- [nio-8082-exec-4] com.lx.myvideo.util.AliyunOSSUtil : ------OSS文件上传开始--------star.jpg
2018-07-09 22:13:09.510 INFO 30080 --- [nio-8082-exec-4] com.lx.myvideo.util.AliyunOSSUtil : ------OSS文件上传成功------file/2018-07-09/5e5170620a664f488f2df0f30c4823e2-star.jpg
这个默认的上传大小是可以看下面的异常, 默认的大小是128KB.这个可以在控制台设置上传大小的.
FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.
五:注意事项
1. 写表单的时候注意不要落了name="file".基本操作.
2. @Value的时候属性字段不要使用static,final修饰,否则就取不到值的.为null.先JUnit单元测试一下嘛,方法上 go to.
3. 遇到陌生的错误,先思考一下程序应有的流程.DeBug一下嘛.
一句话就是IO流将文件写入你想要的地方.详细的开发文档仔细看一下吧.