springboot上传文件
1.本地服务器保存文件
1.1配置服务器保存地址
#图片存放地址 file: linux: path: /images/ window: path: D:/images/
1.2文件上传
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; @Component @Slf4j public class FileUtil { private static String linuxPath; public static String getLinuxPath() { return linuxPath; } @Value("${file.linux.path}") public void setLinuxPath(String linuxPath) { FileUtil.linuxPath = linuxPath; } private static String windowPath; public static String getWindowPath() { return windowPath; } @Value("${file.window.path}") public void setWindowPath(String windowPath) { FileUtil.windowPath = windowPath; } //保存图片并返回地址 public static String getImgSrc(MultipartFile file){ try { String fileName = file.getOriginalFilename(); String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); File files; String os = System.getProperty("os.name"); if(os.toLowerCase().startsWith("win")){ files = new File(windowPath); }else{ files = new File(linuxPath); } log.debug("文件夹{}",files); if (!files.exists()) {//目录不存在就创建 files.mkdirs(); } String newName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); log.debug("文件名称{}",newName); file.transferTo(new File(files + File.separator + newName + "." + suffix)); String realPath; if(os.toLowerCase().startsWith("win")){ realPath = "/" + windowPath + newName + "." + suffix; }else{ realPath = linuxPath + newName + "." + suffix; } log.debug("路径地址{}",realPath); return realPath; } catch (IOException e) { throw new RuntimeException("文件上传失败"); } } }
1.3WebConfig配置
import com.oigcn.association.common.WebInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Value("${file.linux.path}") private String linuxPath; @Value("${file.window.path}") private String windowPath; /** * 拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new WebInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/login/in") .excludePathPatterns("/images/**"); } /** * 跨域支持 * @param registry */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowCredentials(true) .allowedHeaders("*") .allowedOrigins("*") .allowedMethods("*") .maxAge(3600); } /** * 文件上传 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { String os = System.getProperty("os.name"); if(os.toLowerCase().startsWith("win")){ registry.addResourceHandler("/" + windowPath + "**").addResourceLocations("file:///" + windowPath); }else{ registry.addResourceHandler(linuxPath + "**").addResourceLocations("file:" + linuxPath); } } }
2.外部oss存储minio
2.1服务器配置、maven依赖
#图片服务器minio配置 minio: ip: http://ip:9000 #minio登录账号密码 accessKey: admin secretKey: admin #桶名(文件夹)命名规则要符合 亚马逊S3标准 详情可看http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html bucketName: #照片文件夹 images: file
<!--minio oss--> <dependency> <groupId>io.minio</groupId> <artifactId>minio</artifactId> <version>5.0.2</version> </dependency>
2.2上传文件
import io.minio.MinioClient; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.io.InputStream; @Component @Slf4j public class FileUploader { /** * 服务器地址 */ @Value("${minio.ip}") private String ip; /** * 登录账号 */ @Value("${minio.accessKey}") private String accessKey; /** * 登录密码 */ @Value("${minio.secretKey}") private String secretKey; /** * 文件上传 * @param file * @param fileName 文件名 * @param bucketName 桶名(文件夹) * @return */ public String upload(MultipartFile file, String fileName, String bucketName){ try { MinioClient minioClient = new MinioClient(ip, accessKey, secretKey); boolean bucketExists = minioClient.bucketExists(bucketName); if (bucketExists) { log.info("仓库" + bucketName + "已经存在,可直接上传文件。"); } else { minioClient.makeBucket(bucketName); } //上传 minioClient.putObject(bucketName, fileName, file.getInputStream(), file.getContentType()); log.info("成功上传文件 " + fileName + " 至 " + bucketName); String fileUrl = "/" + bucketName + "/" + fileName; return fileUrl; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 判断文件是否存在 * @param fileName 文件名 * @param bucketName 桶名(文件夹) * @return */ public boolean isFileExisted(String fileName, String bucketName) { InputStream inputStream = null; try { MinioClient minioClient = new MinioClient(ip, accessKey, secretKey); inputStream = minioClient.getObject(bucketName, fileName); if (inputStream != null) { return true; } } catch (Exception e) { return false; } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return false; } /** * 删除文件 * @param fileName 文件名 * @param bucketName 桶名(文件夹) * @return */ public boolean delete(String fileName,String bucketName) { try { MinioClient minioClient = new MinioClient(ip, accessKey, secretKey); minioClient.removeObject(bucketName,fileName); return true; } catch (Exception e) { log.error(e.getMessage()); return false; } } /** * 获取文件流 * @param fileName 文件名 * @param bucketName 桶名(文件夹) * @return */ public InputStream getFileInputStream(String fileName,String bucketName) { try { MinioClient minioClient = new MinioClient(ip, accessKey, secretKey); return minioClient.getObject(bucketName,fileName); } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); } return null; } }
2.3文件上传、预览
import com.oigcn.association.utils.FileUploader; import com.oigcn.association.utils.Response; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.HandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; @RestController @RequestMapping("/common") @Slf4j @Api(tags = "公共接口") public class CommonAction { @Autowired private FileUploader fileUploader; @Value("${minio.bucketName.images}") private String bucketName; @PostMapping("/image/upload") @ApiOperation(value = "图片上传") @ApiImplicitParams({ @ApiImplicitParam(name = "file", value = "MultipartFile[]",required = true), }) public Response imageUpload(@RequestParam("file") MultipartFile file){ if(file == null){ return Response.failure("file为空"); } log.info("图片上传{}",file.getOriginalFilename()); //文件是否存在 String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1); String newName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + "." + suffix; boolean exist = fileUploader.isFileExisted(newName,bucketName); if(exist){ throw new RuntimeException("文件名重复"); } //上传文件 String fileUrl = fileUploader.upload(file,newName,bucketName); return Response.success(fileUrl); } @GetMapping("/image/view/**") @ApiOperation(value = "图片预览") @ApiImplicitParams({ @ApiImplicitParam(name = "imgSrc", value = "上传图片时候返回地址",required = true), }) public void imageView(HttpServletRequest request, HttpServletResponse response){ String imgSrc = extractPathFromPattern(request); if(StringUtils.isBlank(imgSrc)){ throw new RuntimeException("图片地址为空"); } response.setContentType("image/jpeg;charset=utf-8"); //文件 String bucketName = imgSrc.split("/")[0]; //文件名 String fileName = imgSrc.split("/")[1]; try(InputStream inputStream = fileUploader.getFileInputStream(fileName,bucketName); OutputStream outputStream = response.getOutputStream()) { byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, len); } response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } } private static String extractPathFromPattern(final HttpServletRequest request) { String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path); } }