背景:领导要我把三种上传文件的方法合并起来,不要用if,用策略模式,之前没写过,找了一会资料,写了个简单的
首先创建一个公共接口
public interface UploadService {
//共同方法行为
R<UploadResp> toUploadBase(UploadBaseReq uploadStrategy);
}
实体类参数包括上传类型
@Data
@ApiModel
@JsonIgnoreProperties(ignoreUnknown = true)
public class UploadBaseReq implements Serializable {
/***
* 上传类型 general--普通上传 mongo--mongo上传 oss--阿里OSS文件上传
*/
@ApiModelProperty(value = "上传类型 GENERAL--普通上传 MONGO--mongo上传 ALI_OSS--阿里OSS文件上传", required = true)
private EnumTypes.UploadChannelType typeCode;
/***
* 文件路径
*/
@ApiModelProperty(value = "文件", required = true)
@NotNull(message = "文件不能为空")
private MultipartFile file;
/***
* 文件路径或者mongo集合名称
*/
@ApiModelProperty(value = "mongo上传时传mongo集合名称,普通上传时传文件路径,OSS文件上传时传文件夹路径名称", required = true)
private String pathOrName;
}
有几种上传类型就创建对应的实现类
@Slf4j
@Service
public class UploadGeneralServiceImpl implements UploadService {
@Override
public R<UploadResp> toUploadBase(UploadBaseReq uploadStrategy) {
//写实现方法
}
}
@Slf4j
@Service
public class UploadMongoServiceImpl implements UploadService {
@Override
public R<UploadResp> toUploadBase(UploadBaseReq uploadStrategy) {
//写实现方法
}
}
@Slf4j
@Service
public class UploadOSSServiceImpl implements UploadService {
@Override
public R<UploadResp> toUploadBase(UploadBaseReq uploadStrategy) {
//写实现方法
}
}
再写个转换类
把@Resource用在Map上会自动把实现了UploadService的实现类的类名做key,对象放到value上
/***
* 文件上传转换工具类
*/
@Component
@Slf4j
public class TransferUploadUtil {
public static Map<String, UploadService> UPLOAD_ERVICE = new HashMap<>();
@Resource
Map<String, UploadService> uploadStrategyService;
@PostConstruct
public void init() {
UPLOAD_ERVICE.put("general", uploadStrategyService.get("uploadGeneralServiceImpl"));
UPLOAD_ERVICE.put("mongo", uploadStrategyService.get("uploadMongoServiceImpl"));
UPLOAD_ERVICE.put("aliOss", uploadStrategyService.get("uploadOSSServiceImpl"));
}
}
最后在controller调用即可,通过类型调相应的实现类
@Slf4j
@RestController
@Api(value = "文件服务", tags = "上传接口")
@RequestMapping(value = "/upload")
public class UploadController {
@Resource
CustomerProperty customerProperty;
/***
* 统一文件上传路径,普通,mongo,oss
* @param uploadBaseReq
* @return
*/
@ApiOperation(value = "统一文件上传")
@PostMapping("/base/file")
@ResponseBody
public R<UploadResp> uploadBase(@Validated UploadBaseReq uploadBaseReq) {
List<String> allowUploadExtList = customerProperty.getAllowUploadExt();
try {
String type = FileTypeUtil.getType(uploadBaseReq.getFile().getInputStream());
if (!allowUploadExtList.contains(type)) {
log.error("[文件上传] 不支持此文件类型上传:{}", type);
return R.failed("不支持此文件类型上传");
}
} catch (Exception ex) {
return R.failed(ex.getMessage());
}
String uploadChanelTypeCode = uploadBaseReq.getTypeCode().getValue();
UploadService uploadStrategy = TransferUploadUtil.UPLOAD_ERVICE.get(uploadChanelTypeCode);
if (uploadStrategy == null) {
return R.failed("不支持该上传类型:" + uploadChanelTypeCode);
}
if (null == uploadBaseReq.getFile() || uploadBaseReq.getFile().isEmpty()) {
return R.failed("请选择文件");
}
return uploadStrategy.toUploadBase(uploadBaseReq);
}
}
还可以写更智能的,不过赶紧交任务要紧 hhhhh