zhongrj
2024-03-20 51efdf5191bc7ecd4efdd22a46139a45af66b7a5
集成微信图片安全检测
3 files modified
3 files added
1182 ■■■■■ changed files
pom.xml 7 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/HttpClientUtils.java 596 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/ImageUtils.java 39 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/WeiXinSecurityUtil.java 321 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/resource/endpoint/OssEndpoint.java 48 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/resource/utils/ImageUtil.java 171 ●●●●● patch | view | raw | blame | history
pom.xml
@@ -257,6 +257,13 @@
            <artifactId>tess4j</artifactId>
            <version>4.5.4</version>
        </dependency>
        <!--压缩图片-->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>
    </dependencies>
src/main/java/org/springblade/common/utils/HttpClientUtils.java
New file
@@ -0,0 +1,596 @@
package org.springblade.common.utils;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import sun.misc.BASE64Encoder;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
public class HttpClientUtils {
    /**
     * 执行有参GET请求
     *
     * @param url
     * @param params
     * @return
     */
    public static String doGet(String url, Map<String, String> params) {
//获取httpclient客户端
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (null != params) {
                for (String key : params.keySet()) {
                    builder.setParameter(key, params.get(key));
                }
            }
            HttpGet get = new HttpGet(builder.build());
            response = httpclient.execute(get);
            System.out.println(response.getStatusLine());
            if (200 == response.getStatusLine().getStatusCode()) {
                HttpEntity entity = response.getEntity();
                resultString = EntityUtils.toString(entity, "utf-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    /**
     * 执行有参GET请求,带请求头
     *
     * @param url 请求url
     * @param params 参数
     * @param key 请求头Key
     * @param secretKey 秘钥
     * @return
     */
    public static String doGetHeader(String url, String key, String secretKey,Map<String, String> params) {
//获取httpclient客户端
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (null != params) {
                for (String keys : params.keySet()) {
                    builder.addParameter(keys,params.get(keys));
//builder.setParameter(keys, params.get(keys));
                }
            }
            HttpGet httpGet = new HttpGet(builder.build());
//设置请求头
            httpGet.addHeader(key,secretKey);
// 传输的类型
            httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded");
//执行Http请求调用
            response = httpclient.execute(httpGet);
//判断是否请求成功返回
            if (200 == response.getStatusLine().getStatusCode()) {
                HttpEntity entity = response.getEntity();
                resultString = EntityUtils.toString(entity, "utf-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    /**
     * 执行有参GET请求,带请求头,接收图片流
     *
     * @param url 请求url
     * @param params 参数
     * @param key 请求头Key
     * @param secretKey 秘钥
     * @return
     */
    public static String doGetHeaderPictureBase64(String url, String key, String secretKey,Map<String, String> params) {
//获取httpclient客户端
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (null != params) {
                for (String keys : params.keySet()) {
                    builder.addParameter(keys,params.get(keys));
                }
            }
            HttpGet httpGet = new HttpGet(builder.build());
//设置请求头
            httpGet.addHeader(key,secretKey);
// 传输的类型
            httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded");
//执行Http请求调用
            response = httpclient.execute(httpGet);
// 将返回的图片或者文件转化成字节数组的形式
            byte[] data = EntityUtils.toByteArray(response.getEntity());
            BASE64Encoder encoder = new BASE64Encoder();
//String imageBase64 = "data:image/png;base64," + encoder.encodeBuffer(data).trim();
            return encoder.encodeBuffer(data).trim().replaceAll("\n", "").replaceAll("\r", "").replaceAll(" ", "");//删除 \r\n
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    /**
     * 执行无参GET请求
     *
     * @param url
     * @return
     */
    public static String doGet(String url) {
        return doGet(url, null);
    }
    /**
     * 执行有参POST请求
     *
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, Map<String, String> params) {
/**
 * 在4.0及以上httpclient版本中,post需要指定重定向的策略,如果不指定则按默认的重定向策略。
 *
 * 获取httpclient客户端
 */
        CloseableHttpClient httpclient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            HttpPost post = new HttpPost(url);
            List<NameValuePair> paramaters = new ArrayList<>();
            if (null != params) {
                for (String key : params.keySet()) {
                    paramaters.add(new BasicNameValuePair(key, params.get(key)));
                }
// 构造一个form表单式的实体
                UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramaters);
// 将请求实体设置到httpPost对象中
                post.setEntity(formEntity);
            }
/**
 * HTTP/1.1 403 Forbidden
 *   原因:
 *      有些网站,设置了反爬虫机制
 *   解决的办法:
 *      设置请求头,伪装浏览器
 */
            post.addHeader("user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
            response = httpclient.execute(post);
            System.out.println(response.getStatusLine());
            if (200 == response.getStatusLine().getStatusCode()) {
                HttpEntity entity = response.getEntity();
                resultString = EntityUtils.toString(entity, "utf-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpclient) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultString;
    }
    public static String doPost(String url) {
        return doPost(url, null);
    }
    public static void main(String[] args) {
        Map<String, String> params = new HashMap<>();
        params.put("scope", "project");
        params.put("q", "数据库");
//
//    System.out.println(doGet("http://www.baidu.com/s",params));
        /**
         * 有一部分网站,禁止爬虫技术访问网站。
         *
         * 解决方案:
         *    伪装浏览器
         *    post.addHeader("user-agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
         */
        System.out.println(doPost("http://www.oschina.net/search", params));
    }
    /**
     * post 请求 header 带 秘钥
     * @param url
     * @param appKey
     * @param appKeyValue
     * @param map
     * @return
     */
    public static String httpPost(String url, String appKey, String appKeyValue, Map<String, String> map) {
// 返回body
        String body = null;
// 获取连接客户端工具
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
// 2、创建一个HttpPost请求
        HttpPost post = new HttpPost(url);
// 5、设置header信息
        /**header中通用属性*/
//        post.setHeader("Accept", "*/*");
//        post.setHeader("Accept-Encoding", "gzip, deflate");
//        post.setHeader("Cache-Control", "no-cache");
//        post.setHeader("Connection", "keep-alive");
        post.setHeader("Content-Type", "application/json;charset=UTF-8");
/**业务参数*/
        post.setHeader(appKey, appKeyValue);
// 设置参数
        if (map != null) {
            try {
                StringEntity entity1 = new StringEntity(JSON.toJSONString(map), "UTF-8");
                entity1.setContentEncoding("UTF-8");
                entity1.setContentType("json/form-data");
                post.setEntity(entity1);
// 7、执行post请求操作,并拿到结果
                httpResponse = httpClient.execute(post);
// 获取结果实体
                HttpEntity entity = httpResponse.getEntity();
                if (entity != null) {
// 按指定编码转换结果实体为String类型
                    body = EntityUtils.toString(entity, "UTF-8");
                }
                try {
                    httpResponse.close();
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return body;
    }
    public static SSLContext createIgnoreVerifySSL() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
        SSLContext sc = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        }).build();
        return sc;
    }
    //适用于post请求并传送form-data数据(同样适用于post的Raw类型的application-json格式)
    public static String postParams(String url, String appKey, Map<String, String> map) {
        SSLContext sslcontext = null;
        try {
            sslcontext = createIgnoreVerifySSL();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
// 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(sslcontext))
            .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
//创建自定义的httpclient对象
        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();
        HttpPost post = new HttpPost(url);
        post.setHeader("appKey", appKey);
        CloseableHttpResponse res = null;
        try {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                nvps.add(new BasicNameValuePair(key, map.get(key)));
            }
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            res = client.execute(post);
            HttpEntity entity = res.getEntity();
            return EntityUtils.toString(entity, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                res.close();
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
    //适用于post请求并传送form-data数据(同样适用于post的Raw类型的application-json格式)
    public static String postParams(String url, Map<String, Object> map) {
        SSLContext sslcontext = null;
        try {
            sslcontext = createIgnoreVerifySSL();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
// 设置协议http和https对应的处理socket链接工厂的对象
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.INSTANCE)
            .register("https", new SSLConnectionSocketFactory(sslcontext))
            .build();
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
//创建自定义的httpclient对象
        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();
        HttpPost post = new HttpPost(url);
//        post.setHeader(appKey, appKeyValue);
        CloseableHttpResponse res = null;
        try {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                nvps.add(new BasicNameValuePair(key, map.get(key).toString()));
            }
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            res = client.execute(post);
            HttpEntity entity = res.getEntity();
            return EntityUtils.toString(entity, "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                res.close();
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url    发送请求的 URL
     * @param params 请求的参数集合
     * @return 远程资源的响应结果
     */
    @SuppressWarnings("unused")
    public static String sendPost(String url, Map<String, String> params) {
        OutputStreamWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try {
            URL realUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
// 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
// POST方法
            conn.setRequestMethod("POST");
// 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.connect();
// 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
// 发送请求参数
            if (params != null) {
                StringBuilder param = new StringBuilder();
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    if (param.length() > 0) {
                        param.append("&");
                    }
                    param.append(entry.getKey());
                    param.append("=");
                    param.append(entry.getValue());
// System.out.println(entry.getKey()+":"+entry.getValue());
                }
// System.out.println("param:"+param.toString());
                out.write(param.toString());
            }
// flush输出流的缓冲
            out.flush();
// 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
// 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result.toString();
    }
    /**
     * json  body
     * @param url
     * @param json
     * @return
     * @throws IOException
     */
    public static String httpPostWithjson(String url, String json) throws IOException {
        String result = "";
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        try {
            BasicResponseHandler handler = new BasicResponseHandler();
            //解决中文乱码问题
            StringEntity entity = new StringEntity(json, "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            result = httpClient.execute(httpPost, handler);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}
src/main/java/org/springblade/common/utils/ImageUtils.java
@@ -8,6 +8,7 @@
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
@@ -16,6 +17,44 @@
public class ImageUtils {
    /**
     * 几种常见的图片格式
     */
    public static String IMAGE_TYPE_GIF = "gif";// 图形交换格式
    public static String IMAGE_TYPE_JPG = "jpg";// 联合照片专家组
    public static String IMAGE_TYPE_JPEG = "jpeg";// 联合照片专家组
    public static String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式
    public static String IMAGE_TYPE_PNG = "png";// 可移植网络图形
    public static String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop
    /**
     * 程序入口:用于测试
     * @param args
     */
    public static void main(String[] args) {
        // -图像类型转换:
        ImageUtils.convert("D:/IMG_20180811_222034.png", "jpg", "D:/test.jpg");//测试OK
    }
    /**
     * 图像类型转换:GIF->JPG、GIF->PNG、PNG->JPG、PNG->GIF(X)、BMP->PNG
     * @param srcImageFile 源图像地址
     * @param formatName 包含格式非正式名称的 String:如JPG、JPEG、GIF等
     * @param destImageFile 目标图像地址
     */
    public static void convert(String srcImageFile, String formatName, String destImageFile) {
        try {
            File f = new File(srcImageFile);
            f.canRead();
            f.canWrite();
            BufferedImage src = ImageIO.read(f);
            ImageIO.write(src, formatName, new File(destImageFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static String getBase64ByImgUrl(String url){
src/main/java/org/springblade/common/utils/WeiXinSecurityUtil.java
New file
@@ -0,0 +1,321 @@
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<String, String> 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;
    }
}
src/main/java/org/springblade/modules/resource/endpoint/OssEndpoint.java
@@ -16,10 +16,14 @@
 */
package org.springblade.modules.resource.endpoint;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPObject;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springblade.common.utils.ImageUtils;
import org.springblade.common.utils.WeiXinSecurityUtil;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.oss.model.OssFile;
@@ -37,6 +41,15 @@
import org.springblade.modules.resource.service.IAttachService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
 * 对象存储端点
@@ -158,7 +171,7 @@
        // 修改link
        changeLink(bladeFile);
        // 返回
        return R.data(bladeFile);
        return R.data(200,bladeFile,"");
    }
    /**
@@ -227,15 +240,27 @@
     *
     * @param file 文件
     * @param prefixPath 文件
     * @param isCheck 是否校验
     * @return ObjectStat
     */
    @SneakyThrows
    @PostMapping("/put-file-by-prefix-path")
    public R<BladeFile> putFileByPrefixPath(@RequestParam MultipartFile file,@RequestParam(required = false) String prefixPath) {
    public R<BladeFile> putFileByPrefixPath(@RequestParam MultipartFile file,
                                            @RequestParam(required = false) String prefixPath,
                                            @RequestParam(required = false) Integer isCheck) {
        // 不传默认不检验
        if(null!=isCheck){
            String checkResult = WeiXinSecurityUtil.checkImg(file);
            JSONObject jsonObject = JSONObject.parseObject(checkResult);
            Integer errorCode = Integer.parseInt(jsonObject.getString("errcode"));
            if (errorCode!=0){
                return R.data(201,null,"图片存在敏感内容,请更换其他图片!");
            }
        }
        BladeFile bladeFile = ossBuilder.templateByPrefixPath(prefixPath).putFile(file.getOriginalFilename(), file.getInputStream());
        // 修改link
        changeLink(bladeFile);
        return R.data(bladeFile);
        return R.data(200,bladeFile,"");
    }
    /**
@@ -243,11 +268,23 @@
     *
     * @param file 文件
     * @param prefixPath 文件
     * @param isCheck 是否校验
     * @return ObjectStat
     */
    @SneakyThrows
    @PostMapping("/put-file-attach-by-prefix-path")
    public R<BladeFile> putFileAttachByPrefixPath(@RequestParam MultipartFile file,@RequestParam(required = false) String prefixPath) {
    public R<BladeFile> putFileAttachByPrefixPath(@RequestParam MultipartFile file,
                                                  @RequestParam(required = false) String prefixPath,
                                                  @RequestParam(required = false) Integer isCheck) {
        // 不传默认不检验
        if(null!=isCheck){
            String checkResult = WeiXinSecurityUtil.checkImg(file);
            JSONObject jsonObject = JSONObject.parseObject(checkResult);
            Integer errorCode = Integer.parseInt(jsonObject.getString("errcode"));
            if (errorCode!=0){
                return R.data(201,null,"图片存在敏感内容,请更换其他图片!");
            }
        }
        String fileName = file.getOriginalFilename();
        BladeFile bladeFile = ossBuilder.templateByPrefixPath(prefixPath).putFile(file.getOriginalFilename(), file.getInputStream());
        Long attachId = buildAttach(fileName, file.getSize(), bladeFile);
@@ -255,7 +292,7 @@
        bladeFile.setAttachId(attachId);
        // 修改link
        changeLink(bladeFile);
        return R.data(bladeFile);
        return R.data(200,bladeFile,"");
    }
    /**
@@ -329,4 +366,5 @@
        return R.success("操作成功");
    }
}
src/main/java/org/springblade/modules/resource/utils/ImageUtil.java
New file
@@ -0,0 +1,171 @@
package org.springblade.modules.resource.utils;
import lombok.extern.slf4j.Slf4j;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
/**
 * @author arsn
 * @className ImageUtil
 * @Description 图片缩放
 **/
@Slf4j
public class ImageUtil {
    /**
     * 缩放比例系数
     */
    private static double SCALING = 0.56;
    /**
     * 符合base64的宽
     */
    private static int MAX_WIDTH = 560;
    /**
     * 最大高
     */
    private static int MAX_HEIGHT = 1000;
    /**
     * @Author 小帅丶
     * @Description 根据图片公网地址转BufferedImage
     * @Date  2020/9/29 10:52
     * @param url 图片公网地址
     * @return java.awt.image.BufferedImage
     **/
    public static BufferedImage imgUrlConvertBufferedImage(String url) throws Exception {
        URL urls = new URL(url);
        Image image = Toolkit.getDefaultToolkit().getImage(urls);
        BufferedImage bufferedImage = toBufferedImage(image);
        return bufferedImage;
    }
    /**
     * @Author 小帅丶
     * @Description 根据BufferedImage处理图片并返回byte[]
     * @Date  2020/9/29 10:55
     * @param bufferedImage
     * @return byte[]
     **/
    public static byte[] zoomImageByte(BufferedImage bufferedImage) throws Exception {
        ByteArrayOutputStream outputStreamZoom = new ByteArrayOutputStream();
        ByteArrayOutputStream outputStreamSource = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "jpg", outputStreamSource);
        BufferedImage bufferedImageZoom = zoomImage(outputStreamSource.toByteArray());
        //写入缩减后的图片
        ImageIO.write(bufferedImageZoom, "jpg", outputStreamZoom);
        return outputStreamZoom.toByteArray();
    }
    /**
     * @Author 小帅丶
     * @Description 根据byte[]处理图片并返回byte[]
     * @Date  2020/9/29 10:55
     * @param src
     * @return byte[]
     **/
    public static byte[] zoomImageByte(byte[] src) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        BufferedImage bufferedImage = zoomImage(src);
        //写入缩减后的图片
        ImageIO.write(bufferedImage, "jpg", outputStream);
        return outputStream.toByteArray();
    }
    /**
     * 图片缩放 仅适用于微信内容图片安全检测使用
     *
     * @param src 为源文件byte
     */
    public static BufferedImage zoomImage(byte[] src) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(src);
        double wr = 0, hr = 0;
        BufferedImage bufferedImage = null;
        //读取图片
        BufferedImage bufImg = ImageIO.read(in);
        int height = bufImg.getHeight();
        int width = bufImg.getWidth();
        int cHeight = height;
        int cWidth = width;
        double Scaling = width / height;
        if (Scaling < SCALING) {
            if (height > MAX_HEIGHT) {
                cHeight = MAX_HEIGHT;
                cWidth = (width * MAX_HEIGHT) / height;
            }
            //以宽为缩放比例
        } else {
            if (width > MAX_WIDTH) {
                cWidth = MAX_WIDTH;
                cHeight = (height * MAX_WIDTH) / width;
            }
        }
        //获取缩放后的宽高
        log.info("宽{},高{}", cWidth, cHeight);
        //设置缩放目标图片模板
        Image Itemp = bufImg.getScaledInstance(width, cHeight, BufferedImage.SCALE_SMOOTH);
        //获取缩放比例
        wr = cWidth * 1.0 / width;
        hr = cHeight * 1.0 / height;
        log.info("宽比例{},高比例{}", wr, hr);
        AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(wr, hr), null);
        Itemp = ato.filter(bufImg, null);
        try {
            //写入缩减后的图片
            ImageIO.write((BufferedImage) Itemp, "jpg", outputStream);
            ByteArrayInputStream inNew = new ByteArrayInputStream(outputStream.toByteArray());
            bufferedImage = ImageIO.read(inNew);
        } catch (Exception ex) {
            log.info("缩放图片异常{}", ex.getMessage());
        } finally {
            if (null != outputStream) {
                outputStream.close();
            }
            if (null != in) {
                in.close();
            }
        }
        return bufferedImage;
    }
    /**
     * @Description Image转BufferedImage
     * @param image 通过url获取的image对象
     * @return java.awt.image.BufferedImage
     **/
    public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();
        try {
            int transparency = Transparency.OPAQUE;
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(image.getWidth(null),
                image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            bimage = new BufferedImage(image.getWidth(null),
                image.getHeight(null), type);
        }
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
        return bimage;
    }
}