背景介绍
在开发过程中,不论是做网页还是APP,基本上都会有图片上传的业务需求,最典型的就是注册账号之后需要用户上传头像或者用户验证的时候上传身份证照片。而java中实现图片上传大概有两种形式:一种是使用jsp+servlet实现图片上传;一种是使用jsp+controller实现图片上传。存储基本上也有两种形式,在数据库中直接存储blob类型的图片或者图片存储在服务器上并在数据库中存储箱对应的路径,绝大部分网站用后者。
知识剖析
在springmvc中,使用jsp+controller实现图片上传的基本思路是:
(1)使用MultipartFile类接收上传的图片;
(2)将图片存储在服务器(阿里云OSS),返回一个图片路径;
(3)图片路径存储在用户信息中以供调用。
其中阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以通过调用 API,在任何应用、任何时间、任何地点上传和下载数据,也可以通过Web控制台对数据进行简单的管理。OSS适合存放任意类型的文件,适合各种网站、开发企业及开发者使用。按实际容量付费真正使您专注于核心业务。
而MultipartFile则是HTML中form mata方式上传的文件,只存储有二进制文件和文件名。
常见问题
解决方案
代码实战:
利用阿里云OSS提供的依赖实现图片上传的工具类如下,其余代码省略。
public static String uploadFile2OOS(OSSClient ossClient, File file, String name) { try { InputStream is = new FileInputStream(file); String fileName = name;//用户名作为存储的文件名 Long fileSize = file.length(); //文件描述 ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(is.available());//is.available()返回值是byte[],必须设置 metadata.setContentEncoding("utf-8");//下载时的编码格式 metadata.setContentType(getContentType(file.getName()));//设置contentType metadata.setContentDisposition("filename/fileSize=" + fileName + "/" + fileSize + "Byte.");//被下载时的提示 //以文件流的形式上传文件 ossClient.putObject(bucketName, folder + fileName, is, metadata); Long exp = new Date().getTime() + 31536000000L; Date expiration = new Date(exp);//过期时间一年 URL url = ossClient.generatePresignedUrl(bucketName, folder + fileName, expiration);//获取url if (url != null) return url.toString(); } catch (Exception e) { e.printStackTrace(); logger.info("上传阿里云OSS服务器异常." + e.getMessage(), e); } return null; }
扩展思考
参考文献
更多讨论
1、form表单提交的是MultipartFile类型的文件,而第三方api需要的是file类型的文件,如何进行转换?
第一种方法:
MultipartFile file = xxx;
CommonsMultipartFile cf= (CommonsMultipartFile)file;
DiskFileItem fi = (DiskFileItem)cf.getFileItem();
File f = fi.getStoreLocation();
会在项目的根目录的临时文件夹下生成一个文件;
第二种方法:
transferTo(File dest);
会在项目中生成一个新文件;
第三种方法:
File f = (File) xxx 强转即可。前提是要配置multipartResolver,要不然会报类型转换失败的异常。
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600"/>
<property name="maxInMemorySize" value="4096"/>
</bean>
没试过;
第四种方法:
Workbook wb = Workbook.getWorkbook(xxx .getInputStream());
转换为输入流,直接读取;
第五种方法:
byte[] buffer = myfile.getBytes();
先转换为字节数组,没试过;
2、怎么调用第三方API?
调用第三方API一般来说需要先申请接口,像阿里云OSS就是要实名认证后才能开通。具体使用的话,需要查看官方文档,写得非常的详细,然后在程序中照葫芦画瓢即可。
3、上传之后返回的url如何使用?
这个url其实就是一个有有效期的连接,可以通过此连接访问到OSS上的文件(如果服务器的AccessKey没有被关闭的话)。那么在页面中需要用到这个图片的地方,贴上对应的url即可。