这里我以阿里云上传文件的案例为例。endpoint,accessKeyId, accessKeySecret, bucketName,这四个参数是连接上你阿里云库的必要参数,由于在开发中可能有很多开发环境,比如pre,dev等,不同的环境下我们可能会用到不同的阿里云库,因此这些参数不会在Java代码中写死,而是放在配置文件当中,那么配置文件中保存的用户名,秘钥等信息如何传递到java代码当中呢?
1.在application.yml配置文件当中获取另一个配置文件application-dev.yml中信息,application.yml中各种用户名密码等信息也不会写死,用$符包裹
#application.yml
spring:
profiles:
active: dev
sky:
alioss:
endpoint: ${sky.alioss.endpoint}
access-key-id: ${sky.alioss.access-key-id}
access-key-secret: ${sky.alioss.access-key-secret}
bucket-name: ${sky.alioss.bucket-name}
而在application-dev.yml配置文件当中才真正保存着这些信息,如果要更换开发环境是需要在application.yml把dev换成pro等
#application-dev.yml
sky:
alioss:
endpoint: ********************
access-key-id: ********************
access-key-secret: ********************
bucket-name: ********************
2.在Java类中如何读取到这些配置信息呢?这就要用到一个注解@ConfigurationProperties(prefix = "***"),这个注解可以读取配置类中信息并转化为Java对象,配置信息中习惯命名方式为“-”,而Java类中习惯驼峰命名法,这些spring能够自动识别
@Component
@ConfigurationProperties(prefix = "sky.alioss")
@Data
public class AliOssProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
}
3.封装工具类对象,创建AliOssUtil对象,AliOssUtil中也要这四个属性并且定义了upload方法,upload方法中用到了这些属性对象的值;AliOssProperties中有@Data注解,包含了get和set方法;使用@bean注解交给spring管理,后面可以@autowired自动注入。
/**
* 配置类,用于创建AliOssUtil对象
*/
@Configuration
@Slf4j
public class OssConfiguration {
@Bean
public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties){
log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
return new AliOssUtil(
aliOssProperties.getEndpoint(),
aliOssProperties.getAccessKeyId(),
aliOssProperties.getAccessKeySecret(),
aliOssProperties.getBucketName());
}
}
4.定义文件上传的方法
@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
/**
* 文件上传
*
* @param bytes
* @param objectName
* @return
*/
public String upload(byte[] bytes, String objectName) {
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
// 创建PutObject请求。
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
} 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();
}
}
//文件访问路径规则 https://BucketName.Endpoint/ObjectName
StringBuilder stringBuilder = new StringBuilder("https://");
stringBuilder
.append(bucketName)
.append(".")
.append(endpoint)
.append("/")
.append(objectName);
log.info("文件上传到:{}", stringBuilder.toString());
return stringBuilder.toString();
}
}
5.在controller中注入AliOssUtil,传入参数就可以调用upload方法
@RestController
@RequestMapping("/admin/common")
@Slf4j
public class CommonController {
@Autowired
private AliOssUtil aliOssUtil;
@PostMapping("/upload")
public Result<String> upload(MultipartFile file){
try {
//获取原始文件名
String originalFilename = file.getOriginalFilename();
//获取文件名后缀
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
//构造新文件名称
String objectName = UUID.randomUUID().toString() + extension;
//文件的请求路径
String filePath = aliOssUtil.upload(file.getBytes(), objectName);
return Result.success(filePath);
}catch (IOException e){
log.error("上传文件失败");
}
return Result.error(MessageConstant.UPLOAD_FAILED);
}
}