| pom.xml | ●●●●● patch | view | raw | blame | history | |
| src/main/java/org/springblade/common/utils/HttpClientUtils.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/org/springblade/common/utils/ImageUtils.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/org/springblade/common/utils/WeiXinSecurityUtil.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/org/springblade/modules/resource/endpoint/OssEndpoint.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/org/springblade/modules/resource/utils/ImageUtil.java | ●●●●● 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; } }