业务模型
- 已知图片网络图片url(或一段含有图片的富文本)。
- 通过图片url加载图片到本地(或者读取富文本中的img属性解析图片url)(使用方法 getFileByNetUrlHttp、getImgStr)。
- 获取文件大小并转换为MB(使用formatFileSize)
- 如果文件大于一定大小(fileMaxVlue)按照比例(reduce)压缩通过url加载的本地图片,并重命名(方法renameAndReduceFile)。
- 图片压缩完成之后转换成MultipartFile并提交到上传接口(uploadPostUrl ),删除压缩后的本地图片(sendMultipartFilePost)。
工具类主要功能
- 网络图片加载到本地Fille(getFileByNetUrlHttp)
- 获取文件File大小,并转换为MB单位(formatFileSize)
- 图片按照比例压缩成新文件File,重命名(renameAndReduceFile)
- 图片File转换为MultipartFile对象(getMultipartFile)
- 提交MultipartFile对象到图片上传接口(sendMultipartFilePost)
- 富文本中提取图片(img标签src属性)(getImgStr)
工具类源码
package com.shipj.test.util;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;
import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author shipj
* @version 1.0
* @Title: ProductpPcturesDealUtil
* @Description: 图片压缩并接口上传工具类(业务模型,从图片url(从图片url或富文本中包含url)加载图片到本,本地进行压缩图片,压缩完成之后通过接口上传到服务)
* @date 2021-04-09 16:19
*/
@Slf4j
public class ProductpPcturesDealUtil {
//压缩比例
private static float reduce = 0.3f;
//文件临时目录
private static String fileDir = "D:\\TEMP\\";
//上传图片url
private static String uploadPostUrl = "https://127.0.0.1:8080/test/storage/putFile";
//上传文件名称
private static String fileParName = "file";
//需压缩文件界值
public static float fileMaxVlue = 5f;
//img Matcher 对象
private static Pattern p_image=Pattern.compile("<img.*src\\s*=\\s*(.*?)[^>]*?>",Pattern.CASE_INSENSITIVE);
//img src Matcher 对象
private static Pattern r_image=Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)");
/**
* @return float
* @Author shipj
* @Description 转换文件大小(MB)
* @Date 10:58 2021-04-09
* @Param [fileLength] file length
**/
public static float formatFileSize(long fileLength) {
if (fileLength == 0) {
return 0;
}
//运算转换单位(保留2位小数)
float mbUnit = 1048676;
float mbValue = ((float) fileLength) / mbUnit;
//转换单位为MB
float fileSizeMB = new BigDecimal(mbValue).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
return fileSizeMB;
}
/**
* @return java.util.Map<java.lang.String, java.lang.Object>
* @Author shipj
* @Description 根据图片url全路径获取File对象信息
* @Date 10:57 2021-04-09
* @Param [netUrl] 图片url
**/
public static Map<String, Object> getFileByNetUrlHttp(String netUrl) {
//构建file对象返回所需参数
Map<String, Object> result = new HashMap<>();
//对本地文件命名,path是http的完整路径,主要得到资源的名字
String newUrl = netUrl;
newUrl = newUrl.split("[?]")[0];
String[] arraySlash = newUrl.split("/");
//得到最后一个分隔符后的名字
String fileName = arraySlash[arraySlash.length - 1];
//获取文件后缀名
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
//保存到本地的路径
String filePath = fileDir + fileName;
File file = null;
URL urlfile = null;
//判断文件的父级目录是否存在,不存在则创建
file = new File(filePath);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try {
//创建文件
file.createNewFile();
} catch (Exception e) {
result.put("code", 1);
result.put("msg", "file.createNewFile 异常,异常信息:" + e.getMessage());
}
try {
urlfile = new URL(newUrl);
} catch (MalformedURLException e) {
result.put("code", 1);
result.put("msg", "URL 异常,异常路径:" + e.getMessage());
}
HttpURLConnection huc = null;
try {
huc = (HttpURLConnection) urlfile.openConnection();
} catch (IOException e) {
result.put("code", 1);
result.put("msg", "huc 异常:" + e.getMessage());
}
//从HTTP响应消息获取状态码,如果响应成功,则处理图片
int code = 0;
try {
code = huc.getResponseCode();
} catch (IOException e) {
result.put("code", 1);
result.put("msg", "huc.getResponseCode 异常:" + e.getMessage());
}
if (code == 200) {
InputStream inputStream = null;
OutputStream outputStream = null;
//下载
try {
inputStream = urlfile.openStream();
} catch (IOException e) {
result.put("code", 1);
result.put("msg", "inputStream 异常,异常信息:" + e.getMessage());
}
try {
outputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
result.put("code", 1);
result.put("msg", "outputStream 异常,异常信息:" + e.getMessage());
}
int bytesRead = 0;
byte[] buffer = new byte[1024];
while (true) {
try {
if (!((bytesRead = inputStream.read(buffer, 0, 1024)) != -1)) {
break;
}
outputStream.write(buffer, 0, bytesRead);
} catch (IOException e) {
result.put("code", 1);
result.put("msg", "outputStream.write 异常,异常信息:" + e.getMessage());
break;
}
}
//关闭输入输出流
try {
if (null != outputStream) {
outputStream.close();
}
if (null != inputStream) {
inputStream.close();
}
} catch (IOException e) {
result.put("code", 1);
result.put("msg", "outputStream.close/inputStream.close 异常,异常信息 :" + e.getMessage());
}
//判断文件大小
float fileSize = formatFileSize(file.length());
log.info(fileName + " 文件大小:" + fileSize);
result.put("fileSize", fileSize);
result.put("fileMaxVlue", fileMaxVlue);
result.put("code", 0);
result.put("msg", "");
} else {
result.put("code", 1);
result.put("msg", "无法正常访问地址:" + netUrl);
}
result.put("fileDir", fileDir);
result.put("filePath", filePath);
result.put("fileName", fileName);
result.put("suffix", suffix);
result.put("file", file);
log.info("图片转化文件成功");
return result;
}
/**
* @return java.util.Map<java.lang.String, java.lang.Object>
* @Author shipj
* @Description 图片重命名并压缩处理
* @Date 11:27 2021-04-09
* @Param [path, oldname, newname]
**/
public static Map<String, Object> renameAndReduceFile(String path, String oldname, String newname) {
//构建file对象返回所需参数
Map<String, Object> result = new HashMap<>();
if (!oldname.equals(newname)) {//新的文件名和以前文件名不同时,才有必要进行重命名
String oldFilePath = path + File.separator + oldname;
String newFilePath = path + File.separator + newname;
File oldfile = new File(oldFilePath);
File newfile = new File(newFilePath);
if (!oldfile.exists()) {
log.info(oldname + "重命名文件不存在!");
//重命名文件不存在
result.put("code", 1);
result.put("msg", "重命名文件不存在");
return result;
}
if (newfile.exists()) {
//若在该目录下已经有一个文件和新文件名相同,则不允许重命名
log.info(newname + "已经存在!");
result.put("code", 1);
result.put("msg", newname + "已经存在!");
return result;
} else {
try {
//压缩图片
Thumbnails.of(oldfile).scale(1).outputQuality(reduce).toFile(newfile);
//删除原有文件
oldfile.deleteOnExit();
} catch (IOException e) {
log.info("压缩文件发生异常:" + e.getMessage());
}
oldfile.renameTo(newfile);
result.put("code", 0);
result.put("msg", "");
result.put("newFile", newfile);
result.put("newFileName", newname);
result.put("newFileDir", path);
result.put("newFilePath", newFilePath);
log.info("重命名文件并压缩文件成功");
return result;
}
} else {
log.info("新文件名和旧文件名相同...");
result.put("code", 1);
result.put("msg", "新文件名和旧文件名相同");
return result;
}
}
/**
* @return java.util.Map<java.lang.String, java.lang.Object>
* @Author shipj
* @Description 将本地文件转换为MultipartFile
* @Date 11:51 2021-04-09
* @Param [file]
**/
public static Map<String, Object> getMultipartFile(File file) {
//构建file对象返回所需参数
Map<String, Object> result = new HashMap<>();
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
result.put("code", 0);
result.put("multipartFile", multipartFile);
log.info("转换 MultipartFile 成功");
return result;
} catch (IOException e) {
result.put("code", 1);
result.put("msg", "转换 MultipartFile 失败,异常信息:" + e.getMessage());
return result;
} finally {
try {
if (null != inputStream) {
inputStream.close();
}
} catch (IOException e) {
result.put("code", 1);
result.put("msg", "转换 MultipartFile 文件流关闭失败,异常信息:" + e.getMessage());
return result;
}
}
}
/***
* @Author shipj
* @Description 构建文件上传请求,并返回结果
* @Date 13:51 2021-04-09
* @Param [multipartFile, file,params]
* @return java.util.Map<java.lang.String, java.lang.Object>
**/
public static Map<String, Object> sendMultipartFilePost(MultipartFile multipartFile, File file, Map<String, Object> params) {
Map<String, Object> resultMap = new HashMap<String, Object>();
CloseableHttpClient httpClient = HttpClients.createDefault();
String result = "";
try {
HttpPost httpPost = new HttpPost(uploadPostUrl);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(java.nio.charset.Charset.forName("UTF-8"));
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
String fileName = null;
fileName = multipartFile.getOriginalFilename();
builder.addBinaryBody(fileParName, multipartFile.getBytes(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
//解决中文乱码
// ContentType contentType = ContentType.create(HTTP.PLAIN_TEXT_TYPE, HTTP.UTF_8);
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (entry.getValue() == null) {
continue;
}
// 类似浏览器表单提交,对应input的name和value
builder.addTextBody(entry.getKey(), entry.getValue().toString());
}
HttpEntity entity = builder.build();
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);// 执行提交
// 设置连接超时时间
// RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout)
// .setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
// httpPost.setConfig(requestConfig);
HttpEntity responseEntity = response.getEntity();
int code = response.getStatusLine().getStatusCode() == 200 ? 0 : 1;
if (code == 0) {
resultMap.put("code", code);
resultMap.put("msg", String.valueOf(response.getStatusLine().getStatusCode()));
if (responseEntity != null) {
// 将响应内容转换为字符串
result = EntityUtils.toString(responseEntity, java.nio.charset.Charset.forName("UTF-8"));
log.info("构建文件上传请求,上传成功返回 result :" + result);
resultMap.put("msg", result);
((CloseableHttpResponse) response).close();
} else {
resultMap.put("code", 1);
resultMap.put("msg", "构建文件上传请求,HTTP请求出现返回 responseEntity 为空");
}
} else {
log.info("构建文件上传请求,返回非 200 code :" + String.valueOf(response.getStatusLine().getStatusCode()));
resultMap.put("code", code);
resultMap.put("msg", String.valueOf(response.getStatusLine().getStatusCode()));
}
httpPost.releaseConnection();
httpClient.close();
} catch (Exception e) {
log.info("构建文件上传请求,HTTP请求出现异常:" + e.getMessage());
resultMap.put("code", 1);
resultMap.put("msg", "构建文件上传请求,HTTP请求出现异常: " + e.getMessage());
} finally {
//删除源文件
file.deleteOnExit();
}
return resultMap;
}
/**
* @Author shipj
* @Description 提取富文本图片(img标签src属性)
* @Date 20:49 2021-04-12
* @Param [htmlStr]
* @return java.util.List<java.lang.String>
**/
public static List<String> getImgStr(String htmlStr) {
List<String> list = new ArrayList<>();
String regEx_img = "<img.*src\\s*=\\s*(.*?)[^>]*?>";
Matcher m_image = p_image.matcher(htmlStr);
while (m_image.find()) {
// 得到<img />数据
String img = m_image.group();
// System.out.println(img);
// 匹配<img>中的src数据
Matcher m = r_image.matcher(img);
while (m.find()) {
list.add(m.group(1));
}
}
return list;
}
/**
* @Author shipj
* @Description 提取富文本中纯文本
* @Date 20:42 2021-04-12
* @Param [richText]
* @return java.lang.String
**/
public static String getText(String richText) {
String regx = "(<.+?>)|(</.+?>)";
Matcher matcher = Pattern.compile(regx).matcher(richText);
while (matcher.find()) {
// 替换图片
richText = matcher.replaceAll("").replace(" ", "");
}
return richText;
}
}
这是一个Java工具类,用于处理网络图片:从URL加载图片到本地,根据大小进行压缩,重命名,转换为MultipartFile并上传到服务器。类包括网络图片加载、文件大小转换、图片压缩、MultipartFile转换和上传等功能。

330

被折叠的 条评论
为什么被折叠?



