dubbo微服务架构中传递MuitipartFile的问题及解决方式

引言

今天在使用springboot+dubbo+zookeeper搭建的微服务架构项目中使用阿里云oss对象存储去集成图片上传功能时出现如下错误:

Serialized class org.apache.catalina.core.ApplicationPart must implement java.io.Serializable

根据这个错误提示可以看出是由于未序列化引发的问题,但是不知道具体问题出在哪

错误原因

经过资料查询后发现是由于dubbodubbo不能在不同服务间传递MutipartFile,因为MuitipartFile是不可序列化的,需要转为byte[]进行传递

解决方式

在Controller层将MultipartFile转为byte[]传递给Service层,如果需要MultipartFile携带的参数,也可以在Controller层获取后传给Service层。

Controller层

重点是使用multipartFile.getBytes()去将其转化为字节形式

/**
 * <p>
 *
 * </p>
 *
 * @author:雷子杰
 * @date:2022/8/7
 */
@RestController
@Api(tags = "阿里云对象存储ossAPI模块")
public class AliOssController {

    @Reference
    private AliOssService aliOssService;

    @PostMapping("/uploadImage")
    @ApiOperation(value = "图片上传")
    public Result upload(MultipartFile file){
        //因为dubbo中不能传递MultipartFile,所以需要转为字节后传过去再转回来
        byte[] arr=null;
        String fileName = file.getOriginalFilename();//获取文件名
        long fileSize = file.getSize();//获取图片大小
        
        try {
            arr = file.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String url = aliOssService.upload(arr,fileName,fileSize);

        return  Result.ok().data("url", url);
    }
}

Service层

重点是使用new ByteArrayInputStream(arr)将传过来的字节转换为流的格式

/**
 * <p>
 *
 * </p>
 *
 * @author:雷子杰
 * @date:2022/8/7
 */
@Service
@Component
@Slf4j
@Transactional
public class AliOssServiceImpl implements AliOssService {

    @Override
    public String upload(byte[] arr, String fileName, long fileSize) {
        InputStream inputStream=null;
        
        inputStream = new ByteArrayInputStream(arr);//将字节转换为流

        //拼接文件夹名字会指定上传到存储空间下面的子文件夹(文件名改为:当前时间到毫秒+uuid+原来文件后缀名)
        String originalFilename= Conts.IMAGESURL
                +System.currentTimeMillis()
                + UUID.randomUUID().toString()
                + fileName.substring(fileName.lastIndexOf("."));

        //使用封装的工具类进行上传
        OssManager.uploadImage(originalFilename, fileSize,inputStream);

        String url=OssManager.bucketDomain+"/"+originalFilename;
        log.debug("文件上传后的路径是{}",url);

        return url;
    }
}

总结

在编程的过程中总会遇到各式各样的问题,只有遇到的多了,总结的多了,我们才会有提升,在未来的道路上走的更远。