业务场景:

业务后台编辑资讯时候,从其他网页直接复制内容的时候,复制图片,部分图片由于前端跨域问题,无法展示,而且没法上传到本公司的资源文件服务;故需要后台下载图片资源文件,然后再进行上传本公司资源文件服务,再返回前端

问题:

由于网络上的图片路径各式各样,不能单纯通过外链接的后缀来判断图片的类型,如:https://hbimg.huabanimg.com/ff4aceaad9a05333b3e46579d991eecdcffb45f612951-T6WWCx_fw658/format/webp 、https://res.cloudinary.com/dfb5w2ccj/image/upload/v1585064831/blog/4_dcftnc.webp 、http://tnaot-test.oss-cn-hongkong.aliyuncs.com/image/2021/02/24/9a2bab3ff43d4e13a62c7f8335645564.jpg等,可以看出图片文件链接的各式各样,根本没有办法判断是什么图片类型

解决方案:

  • 把图片文件下载,如有明显的图片后缀则下载为该类型文件,若没有明显图片后缀则统一下载为jpg
  • 进行媒体文件类型进行判断是什么图片文件
  • 修改图片文件的名字为正确的文件类型

代码:

1.下载文件

public static File exLinkToFile(String exLink) throws IOException {URL uri = new URL(exLink);URLConnection connection = uri.openConnection();//统一格式处理:除gif、png、jpeg、bmp外,均处理成jpgString suffix = "jpg";if (exLink.contains(".gif")) {suffix = "gif";}if (exLink.contains(".png")) {suffix = "png";}if (exLink.contains(".jpeg")) {suffix = "jpeg";}if (exLink.contains(".bmp")) {suffix = "bmp";}File origFile = FileUtils.createTempFile(suffix);try (InputStream inputStream = connection.getInputStream()) {Files.copy(inputStream, origFile.toPath(), StandardCopyOption.REPLACE_EXISTING);} catch (Exception e) {UploadExUtil.uploadFail();}if (!origFile.exists() || !origFile.isFile()) {throw new IOException("origFile文件创建失败:" + exLink);}return origFile;
}

2.媒体文件类型判断

public class MimeTypeUtils {private static boolean isBMP(byte[] buf){byte[] markBuf = "BM".getBytes();  //BMP图片文件的前两个字节return compare(buf, markBuf);}private static boolean isICON(byte[] buf) {byte[] markBuf = {0, 0, 1, 0, 1, 0, 32, 32};return compare(buf, markBuf);}private static boolean isWEBP(byte[] buf) {byte[] markBuf = "RIFF".getBytes(); //WebP图片识别符return compare(buf, markBuf);}private static boolean isGIF(byte[] buf) {byte[] markBuf = "GIF89a".getBytes(); //GIF识别符if(compare(buf, markBuf)){return true;}markBuf = "GIF87a".getBytes(); //GIF识别符if(compare(buf, markBuf)){return true;}return false;}private static boolean isPNG(byte[] buf) {byte[] markBuf = {(byte) 0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A}; //PNG识别符// new String(buf).indexOf("PNG")>0 //也可以使用这种方式return compare(buf, markBuf);}private static boolean isJPEGHeader(byte[] buf) {byte[] markBuf = {(byte) 0xff, (byte) 0xd8}; //JPEG开始符return compare(buf, markBuf);}private static boolean isJPEGFooter(byte[] buf)//JPEG结束符{byte[] markBuf = {(byte) 0xff, (byte) 0xd9};return compare(buf, markBuf);}/*** 获取文件的mimeType* @param filename* @return*/private static String getMimeType(String filename){try {String mimeType = readType(filename);return String.format("image/%s", mimeType);} catch (IOException e) {e.printStackTrace();}return null;}/*** 读取文件类型* @param filename* @return* @throws IOException*/private static String readType(String filename) throws IOException {FileInputStream fis = null;try {File f = new File(filename);if(!f.exists() || f.isDirectory() || f.length()<8) {throw new IOException("the file ["+f.getAbsolutePath()+"] is not image !");}fis= new FileInputStream(f);byte[] bufHeaders = readInputStreamAt(fis,0,8);if(isJPEGHeader(bufHeaders)){long skiplength = f.length()-2-8; //第一次读取时已经读了8个byte,因此需要减掉byte[] bufFooters = readInputStreamAt(fis, skiplength, 2);if(isJPEGFooter(bufFooters)){return "jpeg";}}if(isPNG(bufHeaders)){return "png";}if(isGIF(bufHeaders)){return "gif";}if(isWEBP(bufHeaders)){return "webp";}if(isBMP(bufHeaders)){return "bmp";}if(isICON(bufHeaders)){return "ico";}throw new IOException("the image's format is unkown!");} catch (FileNotFoundException e) {throw e;}finally{try {if(fis!=null){fis.close();}} catch (Exception e) {}}}/*** 标示一致性比较* @param buf  待检测标示* @param markBuf 标识符字节数组* @return 返回false标示标示不匹配*/private static boolean compare(byte[] buf, byte[] markBuf) {for (int i = 0; i < markBuf.length; i++) {byte b = markBuf[i];byte a = buf[i];if(a!=b){return false;}}return true;}/**** @param fis 输入流对象* @param skiplength 跳过位置长度* @param length 要读取的长度* @return 字节数组* @throws IOException*/private static byte[] readInputStreamAt(FileInputStream fis, long skiplength, int length) throws IOException{byte[] buf = new byte[length];fis.skip(skiplength);  //int read = fis.read(buf,0,length);return buf;}public static void main(String[] args) {String filename = "C:\\Users\\mx80414\\Desktop\\webptuan.jpg";String type = getMimeType(filename);System.out.println(type);}}

3.文件工具类

public class FileUtils {private static MultipartConfigElement pathProperties = SpringUtils.getBean(MultipartConfigElement.class);/*** 临时文件夹*/private static String tempPath = "C:\\mongcent\\temp";/*** 是否为视频** @param fileName* @return*/public static boolean isVideo(String fileName) {if (StringUtils.isEmpty(fileName)) {return false;}String[] videoSuffixs = new String[]{"wmv", "mp4", "3gp", "mov", "m4v", "avi"};String suffix = getSuffix(fileName).toLowerCase();for (String videoSuffix : videoSuffixs) {if (Objects.equals(videoSuffix, suffix)) {return true;}}return false;}/*** 格式化文件路径** @param filePath* @return*/public static String formatFilePath(String filePath) {if (StringUtils.isEmpty(filePath)) {return filePath;}return filePath.replaceAll("\\\\+", "/");}/*** 创建父级目录** @param outputPath*/public static void createParentPath(String outputPath) {File file = new File(outputPath);createParentPath(file);}/*** 创建父级目录** @param file*/public static void createParentPath(File file) {File parentFile = file.getParentFile();if (!parentFile.exists()) {parentFile.mkdirs();}}public static boolean copyFile(File file, File copyFile) {FileUtils.createParentPath(copyFile);try {Files.copy(file.toPath(), copyFile.toPath());return true;} catch (IOException e) {e.printStackTrace();}return false;}/*** 将输入流保存成文件到本地** @param in* @param localFileName* @return*/public static void saveFromInputStream(InputStream in, String localFileName) throws IOException {OutputStream out = null;FileUtils.createParentPath(localFileName);File file = new File(localFileName);if (file.exists()) {file.delete();}try {file.createNewFile();out = new FileOutputStream(file);byte[] buffer = new byte[4096];int readLength;while ((readLength = in.read(buffer)) > 0) {byte[] bytes = new byte[readLength];System.arraycopy(buffer, 0, bytes, 0, readLength);out.write(bytes);}out.flush();} catch (IOException e) {throw e;} finally {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 获取文件大小,并转化为M为单位。保留两位小数** @param file* @return*/public static double getSizeForMB(File file) {long size = file.length();double mb = size * 1.0 / 1024 / 1024;BigDecimal bg = new BigDecimal(mb);return save2Decimal(bg).doubleValue();}/*** 获取文件大小,并转化为M为单位。保留两位小数** @param filePath* @return*/public static double getSizeForMB(String filePath) {if (StringUtils.isEmpty(filePath)) {return 0;}File file = new File(filePath);if (!file.exists()) {return 0;}return getSizeForMB(file);}/*** @param filePath* @return*/public static boolean existsFile(String filePath) {if (filePath == null) {return false;}return existsFile(new File(filePath));}public static boolean existsFile(File file) {if (file == null) {return false;}return file.exists();}/*** 获取文件名的后缀** @param fileName* @return*/public static String getSuffix(String fileName) {int index = fileName.lastIndexOf(".");if (index == -1) {return "";}return fileName.substring(index + 1);}/*** 获取文件名,去掉后缀** @param fileName* @return*/public static String getName(String fileName) {int index = fileName.lastIndexOf(".");if (index == -1) {return fileName;}return fileName.substring(0, index);}private static BigDecimal save2Decimal(BigDecimal bg) {return bg.setScale(2, BigDecimal.ROUND_HALF_UP);}private static final SecureRandom random = new SecureRandom();/*** 临时文件夹** @return*/public static String createTempPath() {String tempPath;if (org.springframework.util.StringUtils.hasText(pathProperties.getLocation())) {tempPath = pathProperties.getLocation();} else {tempPath = AccessController.doPrivileged(new GetPropertyAction("java.io.tmpdir"));}if (tempPath == null) {tempPath = FileUtils.tempPath;}File parent = new File(tempPath);if (!parent.exists() || !parent.isDirectory()) {parent.mkdirs();}return parent.getPath();}/*** 生成一个临时文件** @param suffix 后缀名* @return*/public static File createTempFile(String suffix) {String filename;if (StringUtils.isBlank(suffix)) {filename = String.valueOf(getRandomNumber());} else {filename = getRandomNumber() + "." + suffix;}return new File(createTempPath(), filename);}/*** 获取随机名称(原文件名+随机数字+后缀)** @param imageName 原文件名* @return*/public static String getRandomName(String imageName) {long n = getRandomNumber();String filename = getSuffix(imageName);if (StringUtils.isNotBlank(filename)) {filename = "." + filename;}return getName(imageName) + n + filename;}public static long getRandomNumber() {long n = random.nextLong();if (n == Long.MIN_VALUE) {n = 0;} else {n = Math.abs(n);}return n;}public static Boolean isSameFilePath(File firstFile,File secondFile){return firstFile.getAbsolutePath().equals(secondFile.getAbsolutePath());}
}

java下载网络图片文件,并获取其图片类型相关推荐

  1. java下载网络中的文件,java下载网络文件解决思路

    java下载网络文件 下面这段代码是下载一个http网络文件的代码,但有时候下载下来的图片是完整的,有时候下载下来的不完整,还有下载的ppt,pdf之类,也是打不开的.请大件们给指导一下,小弟感激不尽 ...

  2. 如何通过Java下载远程文件到浏览器

    如何通过Java下载远程文件到浏览器 整体思路: 首先获取远程资源的文件输入流,使用HttpServletResponse的输出流,通过Java io转换将输入流转成输出流,写入指定文件,下载到浏览器 ...

  3. java下载zip文件损坏_使用Java下载.zip文件会导致损坏的.zip文件?

    我写了这个方法来下载最新的Selenium Chrome驱动程序,它不起作用.它导致损坏的.zip文件.任何人都可以发现我的错误在哪里?使用Java下载.zip文件会导致损坏的.zip文件? priv ...

  4. java获得src文件夹下的图片和 获得resource目录下的文件

    java获得src文件夹下的图片和 获得resource目录下的文件 1 获得src文件夹下的图片 文件位置 获得url代码 URL url= getClass().getClassLoader(). ...

  5. java下载网络文件至本地

    通过url下载网络文件至本地 所需依赖和工具类代码 所需依赖 <dependency><groupId>org.apache.httpcomponents</groupI ...

  6. java下载网络文件的N种方式

    通过java api下载网络文件的方法有很多,在这里我做个汇总,主要方式有以下几种: 1.使用 common-io库下载文件,需要引入commons-io-2.6.jar public static ...

  7. 咖啡汪日志——JAVA导出pdf文件加水印 文字+图片、文字

    咖啡汪日志--JAVA导出pdf文件加水印 文字和图片.文字 hello,又大家见面了! 作为一只不是在戏精就是在戏精路上的哈士奇,今天要展示给大家的就是如何快捷地给pdf文件增加各种水印.嗷呜呜,前 ...

  8. 【转】java下载网络文件至本地

    通过url下载网络文件至本地 所需依赖和工具类代码 所需依赖 <dependency><groupId>org.apache.httpcomponents</groupI ...

  9. java下载xlsx文件_Java后台Controller实现文件下载操作

    代码 参数: 1.filePath:文件的绝对路径(d:\download\a.xlsx) 2.fileName(a.xlsx) 3.编码格式(GBK) 4.response.request不介绍了, ...

最新文章

  1. 《自然》 脑机接口新突破 人脑信号转文本准确率达97%
  2. CentOS 6.5下Redis安装配置记录
  3. 建站常用13种PHP开源CMS比较
  4. HDOJ 1143 Tri Tiling
  5. 2.1 0/1分类问题-机器学习笔记-斯坦福吴恩达教授
  6. 编程之美-找到符合条件的整数
  7. 从零单排学Redis【黄金】
  8. 2020年推荐系统工程师炼丹手册RecSys-Long Paper版
  9. 教你怎么上传本地代码到github
  10. 20145240 《信息安全系统设计基础》第三周学习总结
  11. 根据图片地址得到文件流
  12. 递归-裴波那契数列(代码、分析、汇编)
  13. php检测字符长度(中文)
  14. Set与WeakSet
  15. C BNF grammar
  16. selenium+java+chrome环境搭建
  17. 手机连接charles问题
  18. 论巴西世界杯带给移动互联网产品的契机!
  19. 大学生课程设计 ------ Java Web课程设计(学生成绩管理系统03)
  20. 计算机内存与外存有什么特点,为什么计算机要分内存与外存,内存与外存各有什么特点?...

热门文章

  1. h5--块级元素与行内元素
  2. 程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
  3. 函数、包,字符串处理,错误处理
  4. H-1B身份六年后的延期问题
  5. 【web前端】html+js实现流程进度展示条
  6. 有效触点归因“强助攻“,对广告主的一大爆击
  7. FM调制的FPGA实现
  8. 一种Android输入框待输入字符去除文本监听回调的方案思路
  9. Asterisk学习之旅(三)
  10. 你还在使用JDK7,今天阿粉带你来了解一下JDK8,不得不说,真香!