0
点赞
收藏
分享

微信扫一扫

【排坑】websoucket场景下文件无法上传到服务器的解决方案

木樨点点 2022-09-23 阅读 114

一、问题描述及解决

具体文件上传业务代码在如上标注的文章中,可见前端传入到接口的格式是String类型的Base64字符串,这里面有第一个坑就是以String接的话,会存在”/r/n“这些转义符,我们需要做一个replace即byte[] bytes = Base64.getDecoder().decode(base64.replace("\r\n",""));

接下来在我们自己本地测试,使用整套流程都没有问题。然而代码放到了服务器上就无法将文件写入到服务器指定位置。
这里面写入先后用到的是FileOutputStream、BufferedOutputStream,再找问题时找到一篇大概很有帮助的文章,同时也参考了很多方案都没有起效果。
Java踩坑笔记 —— 关于OutPutStream流无法在Process应用场景写入失败解决方案

于是,转变思路。我们平常封装好的通过File或者MultipartFile格式的工具类来接收前端传入的文件,一般工具类如下:

public class FileUtil {
    public static String uploadFile(MultipartFile file) {
    	//获取文件上传路径
    	String path = "/tomcat/webapps/file";
//    	String path = "D:\\file";
    	String originalFilename = file.getOriginalFilename();
        //获取文件后缀
        String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
        File targetFile ;
        //拼接新文件名(时间戳+5位数随机数)
        String photoFileName=System.currentTimeMillis() + RandomUtil.getAllNum(5) + substring;
        try {
            File upload = new File(path);
            if(!upload.exists()) {
            	upload.mkdirs();
            }
            targetFile = new File(path, photoFileName);
        	//将上传的文件写到服务器上指定的目录。
            file.transferTo(targetFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "/file/" + photoFileName;
    }
 }

但是缺陷就是需要前端转换传输格式,虽然稳妥,但在原基础上工作量增加很多。又经过一阵子寻找,最终找到一个更好的方案,在原基础上同样吧String类型的Base64字符串转换成byte 用ByteArrayInputStream、FileOutputStream写入完成,并且返还图片地址、图片名称。

public class ToImgUtil {
    private String base;
 
    public ToImgUtil() {
    }
 
    public ToImgUtil(String base) {
        this.base = base;
    }
 
    public String getBase() {
        return base;
    }
 
    public void setBase(String base) {
        this.base = base;
    }
 
    /**
     * 为文件重新命名,命名规则为当前系统时间毫秒数
     *
     * @return string
     */
    private static String getFileNameNew() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return fmt.format(new Date());
    }
    public static Map ToImg(String base){
        //获取年月日
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        //将年、月、日存入数组
        String[] time = sdf.format(new Date()).split("-");
        // 文件保存地址 默认地址为xxxx/年/月/日
//        String destDir = "xxxx/"+time[0]+"/"+time[1]+"/"+time[2];;
        String destDir = "/tomcat/webapps/file";
        /* response.setHeader("Access-Control-Allow-Origin", "*");
         response.setHeader("Access-Control-Allow-Methods", "POST");*/
        base=base.replaceAll("data:image/png;base64,","");
        BASE64Decoder decoder =  new BASE64Decoder();
        byte[] imageByte = null;
        try{
            imageByte = decoder.decodeBuffer(base);
            for (int i = 0; i < imageByte.length; ++i) {
                if (imageByte[i] < 0) {// 调整异常数据
                    imageByte[i] += 256;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (imageByte.length>0) {
            try {
                String filepath = destDir;
                File destfile = new File( filepath);
                if (!destfile.exists()) {
                    destfile.mkdirs();
                }
                //文件新名称
                String fileNameNew = getFileNameNew() + ".png";
                File f = new File(destfile.getAbsoluteFile() + File.separator + fileNameNew);
                // 将字符串转换成二进制,用于显示图片
                // 将上面生成的图片格式字符串 imgStr,还原成图片显示
                InputStream in = new ByteArrayInputStream(imageByte);
                FileOutputStream fos = new FileOutputStream(f);
                // BufferedOutputStream bos = new BufferedOutputStream(fos);
                byte[] buf = new byte[1024];
                int length;
                length = in.read(buf, 0, buf.length);
 
                while (length != -1) {
                    fos.write(buf,0,length);
                    length = in.read(buf);
                }
                fos.flush();
                fos.close();
                in.close();
                Map<String,String> map = new HashedMap<>();
                map.put("destDir",destDir);
                map.put("fileNameNew",fileNameNew);
                return map;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
            }
        }
        return null;
    }
}

二、资料引申

Socket通讯使用遇到(BufferedReader||Write)(Output||InputStream)(Object Input||Output Stream)的问题/阻塞/空

Base64转MultipartFile

Java将base64字符串转成MultipartFile类型

Base64转MultipartFile工具类

WebSocket

举报

相关推荐

0 条评论