1:首先配置pom依赖:
< dependency>
< groupId> com.aliyun.oss</ groupId>
< artifactId> aliyun-sdk-oss</ artifactId>
< version> 3.8.0</ version>
</ dependency>
< dependency>
< groupId> com.qcloud</ groupId>
< artifactId> cos_api</ artifactId>
< version> 5.6.75</ version>
</ dependency>
2:application.yml:
upload :
mode : windowsLocal
linuxLocal :
url : https: //上传子域名/
path : /usr/local/blog/upload/
windowsLocal :
url : http: //localhost: 8080/upload/
path : G: /桌面/博客/mongo- blog- master/springboot/src/main/resources/upload/
oss :
url : http: //Bucket域名/
endpoint : OSS配置endpoint
accessKeyId : OSS配置accessKeyId
accessKeySecret : OSS配置accessKeySecret
bucketName : OSS配置bucketName
cos :
url : https: //ftz- 1307097786.cos.ap- beijing.myqcloud.com/
region : ap- beijing
secretId : AKIDhKqBJPN8mDWcWFm6oVBj4A2h7IF2lFUX
secretKey : tBLekcFi27yb3IJ6i7GCzYt2ymLgtwmt
bucketName : ftz- 1307097786
2.1:腾讯云信息查看:secretId+secretKey在访问密钥里面查看
2.2:url+region+bucketName在配置管理查看
3:Windows本地,Linux本地,阿里云,腾讯云的配置:
3.1 :Windows本地配置:
(1):首先配置application.yml:
(2***):重点:配置登录拦截器,设置虚拟路径,因为浏览器不可以直接访问电脑资源目录文件,所以需要设置虚拟路径!否则会报错:Not allowed to load local resource
;这里的路径要跟application.yml中的路径相匹配
@Override
public void addResourceHandlers ( ResourceHandlerRegistry registry) {
registry. addResourceHandler ( "/upload/**" ) . addResourceLocations ( "file:G:/桌面/博客/mongo-blog-master/springboot/src/main/resources/upload/" ) ;
}
(3):策略枚举层:
package com. jjhroy. blog. enums ;
import lombok. AllArgsConstructor ;
import lombok. Getter ;
@Getter
@AllArgsConstructor
public enum UploadModeEnum {
OSS ( "oss" , "ossUploadStrategyImpl" ) ,
LOCAL ( "linuxLocal" , "localUploadStrategyImpl" ) ,
WINDOWS ( "windowsLocal" , "windowsUploadStrategyImpl" ) ,
COS ( "cos" , "cosUploadStrategyImpl" ) ;
private final String mode;
private final String strategy;
public static String getStrategy ( String mode) {
for ( UploadModeEnum value : UploadModeEnum . values ( ) ) {
if ( value. getMode ( ) . equals ( mode) ) {
return value. getStrategy ( ) ;
}
}
return null ;
}
}
(4):文件上传策略:
package com. jjhroy. blog. strategy. context ;
import com. jjhroy. blog. enums. UploadModeEnum ;
import com. jjhroy. blog. strategy. UploadStrategy ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. beans. factory. annotation. Value ;
import org. springframework. stereotype. Service ;
import org. springframework. web. multipart. MultipartFile ;
import java. io. InputStream ;
import java. util. Map ;
@Service
public class UploadStrategyContext {
@Value ( "${upload.mode}" )
private String uploadMode;
@Autowired
private Map < String , UploadStrategy > uploadStrategyMap;
public String executeUploadStrategy ( MultipartFile file, String path) {
return uploadStrategyMap. get ( UploadModeEnum . getStrategy ( uploadMode) ) . uploadFile ( file, path) ;
}
public String executeUploadStrategy ( String fileName, InputStream inputStream, String path) {
return uploadStrategyMap. get ( UploadModeEnum . getStrategy ( uploadMode) ) . uploadFile ( fileName, inputStream, path) ;
}
}
(5):本地路径上传策略方法实现层:WindowsUploadStrategyImpl:
package com. jjhroy. blog. strategy. impl ;
import com. jjhroy. blog. enums. FileExtEnum ;
import com. jjhroy. blog. exception. BizException ;
import org. springframework. beans. factory. annotation. Value ;
import org. springframework. stereotype. Service ;
import java. io. * ;
import java. nio. file. Files ;
import java. util. Objects ;
@Service ( "windowsUploadStrategyImpl" )
public class WindowsUploadStrategyImpl extends AbstractUploadStrategyImpl {
@Value ( "${upload.windowsLocal.path}" )
private String localPath;
@Value ( "${upload.windowsLocal.url}" )
private String localUrl;
@Override
public Boolean exists ( String filePath) {
return new File ( localPath + filePath) . exists ( ) ;
}
@Override
public void upload ( String path, String fileName, InputStream inputStream) throws IOException {
File directory = new File ( localPath + path) ;
if ( ! directory. exists ( ) ) {
if ( ! directory. mkdirs ( ) ) {
throw new BizException ( "创建目录失败" ) ;
}
}
File file = new File ( localPath + path + fileName) ;
String ext = "." + fileName. split ( "\\." ) [ 1 ] ;
switch ( Objects . requireNonNull ( FileExtEnum . getFileExt ( ext) ) ) {
case MD :
case TXT :
BufferedReader reader = new BufferedReader ( new InputStreamReader ( inputStream) ) ;
BufferedWriter writer = new BufferedWriter ( new FileWriter ( file) ) ;
while ( reader. ready ( ) ) {
writer. write ( ( char ) reader. read ( ) ) ;
}
writer. flush ( ) ;
writer. close ( ) ;
reader. close ( ) ;
break ;
default :
BufferedInputStream bis = new BufferedInputStream ( inputStream) ;
BufferedOutputStream bos = new BufferedOutputStream ( Files . newOutputStream ( file. toPath ( ) ) ) ;
byte [ ] bytes = new byte [ 1024 ] ;
int length;
while ( ( length = bis. read ( bytes) ) != - 1 ) {
bos. write ( bytes, 0 , length) ;
}
bos. flush ( ) ;
bos. close ( ) ;
bis. close ( ) ;
break ;
}
inputStream. close ( ) ;
}
@Override
public String getFileAccessUrl ( String filePath) {
return localUrl+ filePath;
}
}
(6):controller层:更新用户头像为例:
@ApiOperation ( value = "更新用户头像" )
@ApiImplicitParam ( name = "file" , value = "用户头像" , required = true , dataType = "MultipartFile" )
@PostMapping ( "/users/avatar" )
public Result < String > updateUserAvatar ( MultipartFile file) {
return Result . ok ( userInfoService. updateUserAvatar ( file) ) ;
}
(7):userInfoService.updateUserAvatar层及其实现:
@Transactional ( rollbackFor = Exception . class )
@Override
public String updateUserAvatar ( MultipartFile file) {
String avatar = uploadStrategyContext. executeUploadStrategy ( file, FilePathEnum . AVATAR . getPath ( ) ) ;
UserInfo userInfo = UserInfo . builder ( )
. id ( UserUtils . getLoginUser ( ) . getUserInfoId ( ) )
. avatar ( avatar)
. build ( ) ;
userInfoDao. updateById ( userInfo) ;
return avatar;
}
(8):uploadStrategyContext.executeUploadStrategy:
package com. jjhroy. blog. strategy. context ;
import com. jjhroy. blog. enums. UploadModeEnum ;
import com. jjhroy. blog. strategy. UploadStrategy ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. beans. factory. annotation. Value ;
import org. springframework. stereotype. Service ;
import org. springframework. web. multipart. MultipartFile ;
import java. io. InputStream ;
import java. util. Map ;
@Service
public class UploadStrategyContext {
@Value ( "${upload.mode}" )
private String uploadMode;
@Autowired
private Map < String , UploadStrategy > uploadStrategyMap;
public String executeUploadStrategy ( MultipartFile file, String path) {
return uploadStrategyMap. get ( UploadModeEnum . getStrategy ( uploadMode) ) . uploadFile ( file, path) ;
}
public String executeUploadStrategy ( String fileName, InputStream inputStream, String path) {
return uploadStrategyMap. get ( UploadModeEnum . getStrategy ( uploadMode) ) . uploadFile ( fileName, inputStream, path) ;
}
}
(9):抽象上传模板
(10)文件上传工具类:
package com. jjhroy. blog. util ;
import com. baomidou. mybatisplus. core. toolkit. StringUtils ;
import lombok. extern. log4j. Log4j2 ;
import org. apache. commons. codec. binary. Hex ;
import org. springframework. web. multipart. MultipartFile ;
import java. io. File ;
import java. io. IOException ;
import java. io. InputStream ;
import java. security. MessageDigest ;
import java. util. Objects ;
@Log4j2
public class FileUtils {
public static String getMd5 ( InputStream inputStream) {
try {
MessageDigest md5 = MessageDigest . getInstance ( "md5" ) ;
byte [ ] buffer = new byte [ 8192 ] ;
int length;
while ( ( length = inputStream. read ( buffer) ) != - 1 ) {
md5. update ( buffer, 0 , length) ;
}
return new String ( Hex . encodeHex ( md5. digest ( ) ) ) ;
} catch ( Exception e) {
e. printStackTrace ( ) ;
return null ;
} finally {
try {
if ( inputStream != null ) {
inputStream. close ( ) ;
}
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
public static String getExtName ( String fileName) {
if ( StringUtils . isBlank ( fileName) ) {
return "" ;
}
return fileName. substring ( fileName. lastIndexOf ( "." ) ) ;
}
public static File multipartFileToFile ( MultipartFile multipartFile) {
File file = null ;
try {
String originalFilename = multipartFile. getOriginalFilename ( ) ;
String [ ] filename = Objects . requireNonNull ( originalFilename) . split ( "\\." ) ;
file = File . createTempFile ( filename[ 0 ] , filename[ 1 ] ) ;
multipartFile. transferTo ( file) ;
file. deleteOnExit ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
return file;
}
private static double getAccuracy ( long size) {
double accuracy;
if ( size < 900 ) {
accuracy = 0.85 ;
} else if ( size < 2048 ) {
accuracy = 0.6 ;
} else if ( size < 3072 ) {
accuracy = 0.44 ;
} else {
accuracy = 0.4 ;
}
return accuracy;
}
}
3.2:其余三种类似,只需要改变一下application.yml就好