package org.springblade.common.utils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; import org.apache.commons.io.FileUtils; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import net.coobird.thumbnailator.Thumbnails; /** * 微信安全检验工具类 */ public class WeiXinSecurityUtil { private static Integer IMG_WIDTH = 750; private static Integer IMG_HEIGHT = 1334; /** * 图片检测接口 */ private static String IMG_SEC_URL = "https://api.weixin.qq.com/wxa/img_sec_check?access_token="; //获取wxAccessToken private static String WX_GET_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token"; private static String WX_APP_ID = "wx41aa8a5d2e565a05"; private static String WX_SECRET = "e0e9218ac368cd4ca620ff4c7030f468"; /** * 恶意图片过滤-校验图片是否含有违法违规内容 * MultipartFile multipartFile, String accessToken * @param multipartFile * @return */ public static String checkImg(MultipartFile multipartFile){ String result = ""; //压缩图片 InputStream inputStream = compressImage(multipartFile); // 校验api url String url = IMG_SEC_URL + getWxAccessToken(); // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的 HttpClient httpclient = HttpClients.createDefault(); //创建一个post请求 HttpPost request = new HttpPost(url); //设置响应头 ( application/octet-stream:二进制流,不知道下载文件类型) request.addHeader("Content-Type", "application/octet-stream"); try { //创建一个byte数组,和输入的文件的大小一样 byte[] byt = new byte[inputStream.available()]; //从输入流中读取全部,并将其存储在缓冲区数组byt 中。 inputStream.read(byt); //定制提交内容 request.setEntity(new ByteArrayEntity(byt, ContentType.create("image/jpg"))); //由客户端执行(发送)请求,执行校验 HttpResponse response = httpclient.execute(request); // 从响应模型中获取响应实体 HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity, "UTF-8");// 转成string //打印校验结果 System.out.println("result:" + result); } catch (IOException e) { e.printStackTrace(); } finally { if(inputStream != null){ try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } // 响应返回结果 return result; } /** * 图片过滤检测 * @param file 图片文件 * @return */ public String checkPic(MultipartFile file) { String access_token = ""; String result = ""; //自己写一个定时任务或其他方式 获取AccessToken try { access_token = getWxAccessToken(); String url = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=" + access_token; result = uploadFile(url, file); System.out.println("图片检测结果 = " + result); } catch (Exception e) { System.out.println("----------------调用腾讯内容过滤系统出错------------------" + e.getMessage()); } // 返回 return result; } /** * 上传二进制文件 * @param graphurl 接口地址 * @param file 图片文件 * @return */ public static String uploadFile(String graphurl,MultipartFile file) { String line = null;//接口返回的结果 try { // 换行符 final String newLine = "\r\n"; final String boundaryPrefix = "--"; // 定义数据分隔线 String BOUNDARY = "========7d4a6d158c9"; // 服务器的域名 URL url = new URL(graphurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置为POST情 conn.setRequestMethod("POST"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 设置请求头参数 conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("Charsert", "UTF-8"); conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY); conn.setRequestProperty("User-Agent","Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"); OutputStream out = new DataOutputStream(conn.getOutputStream()); // 上传文件 StringBuilder sb = new StringBuilder(); sb.append(boundaryPrefix); sb.append(BOUNDARY); sb.append(newLine); // 文件参数,photo参数名可以随意修改 sb.append("Content-Disposition: form-data;name=\"image\";filename=\"" + "https://api.weixin.qq.com" + "\"" + newLine); sb.append("Content-Type:application/octet-stream"); // 参数头设置完以后需要两个换行,然后才是参数内容 sb.append(newLine); sb.append(newLine); // 将参数头的数据写入到输出流中 out.write(sb.toString().getBytes()); // 读取文件数据 out.write(file.getBytes()); // 最后添加换行 out.write(newLine.getBytes()); // 定义最后数据分隔线,即--加上BOUNDARY再加上--。 byte[] end_data = (newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine).getBytes(); // 写上结尾标识 out.write(end_data); out.flush(); out.close(); // 定义BufferedReader输入流来读取URL的响应 BufferedReader reader = new BufferedReader(new InputStreamReader( conn.getInputStream())); while ((line = reader.readLine()) != null) { return line; } } catch (Exception e) { System.out.println("发送POST请求出现异常!" + e); } return line; } /** * 上传二进制文件 * @param apiurl 接口地址 * @param file 图片文件 * @return */ public static String uploadFile(String apiurl, byte[] file) { //接口返回的结果 String line = null; try { // 换行符 final String newLine = "\r\n"; final String boundaryPrefix = "--"; // 定义数据分隔线 String BOUNDARY = "========7d4a6d158c9"; // 服务器的域名 URL url = new URL(apiurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 设置为POST情 conn.setRequestMethod("POST"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); // 设置请求头参数 conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("Charsert", "UTF-8"); conn.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY); conn.setRequestProperty("User-Agent","Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.15(0x17000f31) NetType/WIFI Language/zh_CN"); OutputStream out = new DataOutputStream(conn.getOutputStream()); // 上传文件 StringBuilder sb = new StringBuilder(); sb.append(boundaryPrefix); sb.append(BOUNDARY); sb.append(newLine); // 文件参数,photo参数名可以随意修改 sb.append("Content-Disposition: form-data;name=\"image\";filename=\"" + "https://api.weixin.qq.com" + "\"" + newLine); sb.append("Content-Type:application/octet-stream"); // 参数头设置完以后需要两个换行,然后才是参数内容 sb.append(newLine); sb.append(newLine); // 将参数头的数据写入到输出流中 out.write(sb.toString().getBytes()); // 读取文件数据 out.write(file); // 最后添加换行 out.write(newLine.getBytes()); // 定义最后数据分隔线,即--加上BOUNDARY再加上--。 byte[] end_data = (newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine).getBytes(); // 写上结尾标识 out.write(end_data); out.flush(); out.close(); // 定义BufferedReader输入流来读取URL的响应 BufferedReader reader = new BufferedReader(new InputStreamReader( conn.getInputStream())); while ((line = reader.readLine()) != null) { return line; } } catch (Exception e) { System.out.println("发送POST请求出现异常!" + e); } return line; } /** * 获取 WxAccessToken * @return */ public static String getWxAccessToken() { //参数 Map params = new HashMap<>(); params.put("grant_type", "client_credential"); params.put("appid", WX_APP_ID); params.put("secret", WX_SECRET); String result = HttpClientUtils.doGet(WX_GET_ACCESS_TOKEN, params); JSONObject jsonObject = JSON.parseObject(result); String accessToken = jsonObject.getString("access_token"); return accessToken; } /** * 压缩图片 * @param multipartFile */ public static InputStream compressImage(MultipartFile multipartFile){ //*************对不是jpg格式的图片转换成jpg格式*************** //获取文件名后缀,判断其格式 int begin = multipartFile.getOriginalFilename().lastIndexOf("."); int last = multipartFile.getOriginalFilename().length(); //获得文件后缀名 String houzuiFileName = multipartFile.getOriginalFilename().substring(begin, last); //创建临时文件 File tempFile = new File(multipartFile.getOriginalFilename()); //写入临时File文件 tempFile,将multipartFile转换成File try { //import org.apache.commons.io.FileUtils; FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), tempFile); } catch (IOException e) { e.printStackTrace(); } //如果文件不是jpg格式,转换其格式 if (!"jpg".equalsIgnoreCase(houzuiFileName)){ //ImageUtils是一个工具类,下面给出 //将png格式转换成jpg,输出到tempFile //测试OK ImageUtils.convert(multipartFile.getOriginalFilename(), "jpg", tempFile.getAbsolutePath()); //*************对不是jpg格式的图片转换成jpg格式*************** } try { //压缩图片 BufferedImage bufferedImage = Thumbnails.of(tempFile) .size(740, 1330)//指定压缩之后的图片尺寸 .outputQuality(0.8f)//图片压缩质量 .asBufferedImage(); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "jpg", os); InputStream inputStream = new ByteArrayInputStream(os.toByteArray()); // System.out.println(inputStream); return inputStream; } catch (IOException e) { e.printStackTrace(); }finally { // 会在本地产生临时文件,用完后需要删除 if (tempFile.exists()) { tempFile.delete(); } } return null; } }