JavaWed开发——文件上传
一.文件上传大小的限制
一般文件上传默认只能传1MB
要设置该值需要在资源配置文件配置,我资源配置文件是.yml文件
在.yml文件中输入multipart
点击第一项
然后按照下图修改
这样就设置了上传文件的最大大小
二. 文件如何从前端上传到后端本地
在Controller层用MultipartFile类型进行文件的传递,他会存储文件的名字和文件的内容
@PostMapping(\"/upload\")public Result upload(string name, Integer age, Multipartfile file) throws IoException { log.info(\"按收参数:{},{},{}\",name,age,file); String originalFilename =file.getOriginalFilename();//获取原始文件名XXX.jpg/png/... //保存文件 file.transferTo(new File( pathname: \"D:/images/\"+ originalFilename));return Result.success();}
但是这样又有一个问题,那就是当第二次存储相同名字的文件时,后一个文件会替换第一个文件,导致文件遗失
那么我们得用uuid进行
什么是uuid?
例子:
输出结果:
uuid是不会重复的
@PostMapping(\"/upload\")public Result upload(string name, Integer age, MultipartFile file) throws IoException { log.info(\"接收参数:{},{},{}\",name,age,file);//获取原始文件名 String originalFilename = file.getoriginalFilename();//1.jpg 22.2.2.2.png //新的文件名后缀 String extension = originalfilename.substring(originalfilename.lastIndexof( \".\")); String newFileName =UuID.randomUUID().tostring()+ extension; //保存文件 file.transferTo(new File( pathname: \"D:/images/\" + newFileName)); return Result.success();}
这样存下来的文件名就一定不会重复了
三. 将前端传过来的文件传到阿里云OSS
1.配置阿里云
如果还没有阿里云账号
首先得注册阿里云的账号,生成Accesskey_ID和AccessKey_Secret
然后在以管理员身份打开cmd窗口
输入
set OSS_ACCESS_KEY_ID=你的Accesskey_ID
set OSS_ACCESS_KEY_SECRET=你的AccessKey_Secret
然后接着输入
setx OSS_ACCESS_KEY_ID \"%OSS_ACCESS_KEY_ID%\"setx OSS_ACCESS_KEY_SECRET \"%OSS_ACCESS_KEY_SECRET%\"
这是在配置环境
然后分别输入以下语句确认环境有没有生效
echo %OSS_ACCESS_KEY_ID%echo %OSS_ACCESS_KEY_SECRET%
如果成功,他会返回你的Accesskey_ID和Accesskey_Secret
然后
在阿里云官网看一边SDK文档:OSS Java SDK_对象存储(OSS)-阿里云帮助中心
里面有详细的配置信息
如果不想看,可以跟着我下面的来操作
在项目的pom.xml文件配置依赖
com.aliyun.oss aliyun-sdk-oss 3.17.4
如果使用的是Java 9及以上的版本,则需要添加以下JAXB相关依赖。
javax.xml.bind jaxb-api 2.3.1 javax.activation activation 1.1.1 org.glassfish.jaxb jaxb-runtime 2.3.3
接下来就可以写Java程序对阿里云OSS操作了
具体操作仍然需要看阿里云OSS的SDK文档
2.参照官方的SDK编写程序
在阿里云OSS的SDK文档中,找到简单上传文件,那里有模板代码
import com.aliyun.oss.*;import com.aliyun.oss.common.auth.*;import com.aliyun.oss.common.comm.SignVersion;import com.aliyun.oss.model.PutObjectRequest;import com.aliyun.oss.model.PutObjectResult;import java.io.FileInputStream;import java.io.InputStream;public class Demo { public static void main(String[] args) throws Exception { // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = \"https://oss-cn-hangzhou.aliyuncs.com\"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = \"examplebucket\"; // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。 String objectName = \"exampledir/exampleobject.txt\"; // 填写本地文件的完整路径,例如D:\\\\localpath\\\\examplefile.txt。 // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。 String filePath= \"D:\\\\localpath\\\\examplefile.txt\"; // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。 String region = \"cn-hangzhou\"; // 创建OSSClient实例。 // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { InputStream inputStream = new FileInputStream(filePath); // 创建PutObjectRequest对象。 PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream); // 创建PutObject请求。 PutObjectResult result = ossClient.putObject(putObjectRequest); } catch (OSSException oe) { System.out.println(\"Caught an OSSException, which means your request made it to OSS, \" + \"but was rejected with an error response for some reason.\"); System.out.println(\"Error Message:\" + oe.getErrorMessage()); System.out.println(\"Error Code:\" + oe.getErrorCode()); System.out.println(\"Request ID:\" + oe.getRequestId()); System.out.println(\"Host ID:\" + oe.getHostId()); } catch (ClientException ce) { System.out.println(\"Caught an ClientException, which means the client encountered \" + \"a serious internal problem while trying to communicate with OSS, \" + \"such as not being able to access the network.\"); System.out.println(\"Error Message:\" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } }}
只要按他的注释修改你的值就行了
文件上传到阿里云后,他会自动生成一个url地址,别人只要访问这个地址就能自动下载你的资源
3.代码的优化
向阿里云OSS的SDK文档的模板代码在我们日常项目开发中是不推荐的,因为已经把endpoint和那些变量写死了,不便于日常的维护
所以需要修改一下:把这些有关阿里云OSS的相关参数配置到.yml文件中,当要用到再以@Value(${aliyun.oss.endpoint}在变量声目前注入就行了
4.代码的再优化
当配置的变量特别多时,也不好管理和代码的复用,还要一项一项的指定
那我们可以再优化,通过实体类注入bean的方法
通过对一个存有相关变量的实体类(注意,变量名要和资源配置文件的保持一致)通过@Component修饰放入IOC容器当作一个bean对象
然后通过@ConfigurationProperties(prefix = “aliyun.oss”)说明注入的变量值.yml资源配置文件的aliyun.oss前缀的值
这样,当要用到相关变量,只要@Autowired注释声明一个该对象然后用get方法得到对应的值就好了