Spring?Boot?如何生成微信小程序短連接及發(fā)送短信在短信中打開(kāi)小程序操作
需求描述,需要發(fā)送短信,通過(guò)短信中的短連接打開(kāi)小程序操作。
定義一個(gè)小程序配置類(lèi)
@Configuration @ConfigurationProperties("wx") public class WeiXinProperties { private String appid; private String secret; public String getAppid() { return appid; } public void setAppid(String appid) { this.appid = appid; } public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } }
定義小程序Token獲取類(lèi)
@Component public class TokenManager { private final static Logger log = LoggerFactory.getLogger(TokenManager.class); @Autowired private RedisTemplate redisTemplate; @Autowired private WeiXinProperties weiXinProperties; public String getAccessToken() { String accessToken = (String) redisTemplate.opsForValue().get(weiXinProperties.getAppid()); if(StringUtils.isNotEmpty(accessToken)){ return accessToken; } else { String grant_type = "client_credential"; String url = "https://api.weixin.qq.com/cgi-bin/stable_token"; String appId = weiXinProperties.getAppid(); String secret = weiXinProperties.getSecret(); Map<String, Object> paramMap = new HashMap<>(); paramMap.put("appid", appId); paramMap.put("secret", secret); paramMap.put("grant_type", grant_type); String res = HttpUtils.sendPost(url, JSON.toJSONString(paramMap)); JSONObject jsonObject = JSONObject.parseObject(res); accessToken = jsonObject.getString("access_token"); Integer expiresIn = jsonObject.getInteger("expires_in"); redisTemplate.opsForValue().set(weiXinProperties.getAppid(), accessToken, expiresIn, TimeUnit.SECONDS); return accessToken; } } }
短連接訪問(wèn)控制類(lèi)
@Component public class ShortLinkUtils { @Autowired private TokenManager rcwTokenManager; public String getShortLink(String dutyId){ String accessToken = rcwTokenManager.getAccessToken(); String url = "https://api.weixin.qq.com/wxa/generate_urllink?access_token="+accessToken; JSONObject jsonObject = new JSONObject(); jsonObject.put("path","pages/index/index"); jsonObject.put("query","id="+dutyId); jsonObject.put("expire_type",1); jsonObject.put("expire_interval",1); jsonObject.put("env_version","release"); String s = HttpUtil.doPostSSL(url, jsonObject.toJSONString()); return s; } }
HttpUtils工具類(lèi)
package com.video.videocall.utils; import com.video.videocall.core.constant.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.*; import java.io.*; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.security.cert.X509Certificate; /** * 通用http發(fā)送方法 * * @author Nihui */ public class HttpUtils { private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); /** * 向指定 URL 發(fā)送GET方法的請(qǐng)求 * * @param url 發(fā)送請(qǐng)求的 URL * @return 所代表遠(yuǎn)程資源的響應(yīng)結(jié)果 */ public static String sendGet(String url) { return sendGet(url, StringUtils.EMPTY); } /** * 向指定 URL 發(fā)送GET方法的請(qǐng)求 * * @param url 發(fā)送請(qǐng)求的 URL * @param param 請(qǐng)求參數(shù),請(qǐng)求參數(shù)應(yīng)該是 name1=value1&name2=value2 的形式。 * @return 所代表遠(yuǎn)程資源的響應(yīng)結(jié)果 */ public static String sendGet(String url, String param) { return sendGet(url, param, Constants.UTF8); } /** * 向指定 URL 發(fā)送GET方法的請(qǐng)求 * * @param url 發(fā)送請(qǐng)求的 URL * @param param 請(qǐng)求參數(shù),請(qǐng)求參數(shù)應(yīng)該是 name1=value1&name2=value2 的形式。 * @param contentType 編碼類(lèi)型 * @return 所代表遠(yuǎn)程資源的響應(yīng)結(jié)果 */ public static String sendGet(String url, String param, String contentType) { StringBuilder result = new StringBuilder(); BufferedReader in = null; try { String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url; log.info("sendGet - {}", urlNameString); URL realUrl = new URL(urlNameString); URLConnection connection = realUrl.openConnection(); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.connect(); in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); String line; while ((line = in.readLine()) != null) { result.append(line); } log.info("recv - {}", result); } catch (ConnectException e) { log.error("調(diào)用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("調(diào)用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("調(diào)用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("調(diào)用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); } finally { try { if (in != null) { in.close(); } } catch (Exception ex) { log.error("調(diào)用in.close Exception, url=" + url + ",param=" + param, ex); } } return result.toString(); } /** * 向指定 URL 發(fā)送POST方法的請(qǐng)求 * * @param url 發(fā)送請(qǐng)求的 URL * @param param 請(qǐng)求參數(shù),請(qǐng)求參數(shù)應(yīng)該是 name1=value1&name2=value2 的形式。 * @return 所代表遠(yuǎn)程資源的響應(yīng)結(jié)果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); try { log.info("sendPost - {}", url); URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); 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("Accept-Charset", "utf-8"); conn.setRequestProperty("contentType", "utf-8"); conn.setDoOutput(true); conn.setDoInput(true); out = new PrintWriter(conn.getOutputStream()); out.print(param); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null) { result.append(line); } log.info("recv - {}", result); } catch (ConnectException e) { log.error("調(diào)用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("調(diào)用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("調(diào)用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("調(diào)用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); } finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { log.error("調(diào)用in.close Exception, url=" + url + ",param=" + param, ex); } } return result.toString(); } public static String sendSSLPost(String url, String param) { StringBuilder result = new StringBuilder(); String urlNameString = url + "?" + param; try { log.info("sendSSLPost - {}", urlNameString); SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); URL console = new URL(urlNameString); HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); 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("Accept-Charset", "utf-8"); conn.setRequestProperty("contentType", "utf-8"); conn.setDoOutput(true); conn.setDoInput(true); conn.setSSLSocketFactory(sc.getSocketFactory()); conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); conn.connect(); InputStream is = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String ret = ""; while ((ret = br.readLine()) != null) { if (ret != null && !"".equals(ret.trim())) { result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8)); } } log.info("recv - {}", result); conn.disconnect(); br.close(); } catch (ConnectException e) { log.error("調(diào)用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("調(diào)用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("調(diào)用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("調(diào)用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); } return result.toString(); } private static class TrustAnyTrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } } private static class TrustAnyHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { return true; } } }
HttpUtil工具類(lèi)
package com.video.videocall.utils; import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; 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.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.security.GeneralSecurityException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Classname HttpUtil * @Description TODO 封裝HTTPS請(qǐng)求類(lèi) * @Date 2020/8/14 2:29 PM * @Created by nihui * @Version 1.0 * @Description HttpUtil @see nihui */ public class HttpUtil { private static final Logger log = LoggerFactory.getLogger(HttpUtil.class); private static PoolingHttpClientConnectionManager connMgr; private static RequestConfig requestConfig; private static final int MAX_TIMEOUT = 7000; static { // 設(shè)置連接池 connMgr = new PoolingHttpClientConnectionManager(); // 設(shè)置連接池大小 connMgr.setMaxTotal(100); connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal()); RequestConfig.Builder configBuilder = RequestConfig.custom(); // 設(shè)置連接超時(shí) configBuilder.setConnectTimeout(MAX_TIMEOUT); // 設(shè)置讀取超時(shí) configBuilder.setSocketTimeout(MAX_TIMEOUT); // 設(shè)置從連接池獲取連接實(shí)例的超時(shí) configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT); // 在提交請(qǐng)求之前 測(cè)試連接是否可用 configBuilder.setStaleConnectionCheckEnabled(true); requestConfig = configBuilder.build(); } /** * 發(fā)送 GET 請(qǐng)求(HTTP),不帶輸入數(shù)據(jù) * * @param url * @return */ public static String doGet(String url) { return doGet(url, new HashMap<String, Object>()); } /** * 發(fā)送 GET 請(qǐng)求(HTTP),K-V形式 * * @param url * @param params * @return */ public static String doGet(String url, Map<String, Object> params) { String apiUrl = url; StringBuffer param = new StringBuffer(); int i = 0; for (String key : params.keySet()) { if (i == 0) param.append("?"); else param.append("&"); param.append(key).append("=").append(params.get(key)); i++; } apiUrl += param; String result = null; log.info("請(qǐng)求地址 {}",apiUrl); HttpClient httpclient = new DefaultHttpClient(); try { HttpGet httpPost = new HttpGet(apiUrl); HttpResponse response = httpclient.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); log.info("執(zhí)行狀態(tài)碼 : " + statusCode); HttpEntity entity = response.getEntity(); if (entity != null) { InputStream instream = entity.getContent(); result = IOUtils.toString(instream, "UTF-8"); } } catch (IOException e) { e.printStackTrace(); } return result; } /** * 發(fā)送 POST 請(qǐng)求(HTTP),不帶輸入數(shù)據(jù) * * @param apiUrl * @return */ public static String doPost(String apiUrl) { return doPost(apiUrl, new HashMap<String, Object>()); } /** * 發(fā)送 POST 請(qǐng)求(HTTP),K-V形式 * * @param apiUrl API接口URL * @param params 參數(shù)map * @return */ public static String doPost(String apiUrl, Map<String, Object> params) { CloseableHttpClient httpClient = HttpClients.createDefault(); String httpStr = null; HttpPost httpPost = new HttpPost(apiUrl); CloseableHttpResponse response = null; try { httpPost.setConfig(requestConfig); List<NameValuePair> pairList = new ArrayList<>(params.size()); for (Map.Entry<String, Object> entry : params.entrySet()) { NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry .getValue().toString()); pairList.add(pair); } httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8"))); response = httpClient.execute(httpPost); log.info("請(qǐng)求響應(yīng) {}",response.toString()); HttpEntity entity = response.getEntity(); httpStr = EntityUtils.toString(entity, "UTF-8"); } catch (IOException e) { e.printStackTrace(); } finally { if (response != null) { try { EntityUtils.consume(response.getEntity()); } catch (IOException e) { e.printStackTrace(); } } } return httpStr; } /** * 發(fā)送 POST 請(qǐng)求(HTTP),JSON形式 * * @param apiUrl * @param json json對(duì)象 * @return */ public static String doPost(String apiUrl, Object json) { CloseableHttpClient httpClient = HttpClients.createDefault(); String httpStr = null; HttpPost httpPost = new HttpPost(apiUrl); CloseableHttpResponse response = null; try { httpPost.setConfig(requestConfig); StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");//解決中文亂碼問(wèn)題 stringEntity.setContentEncoding("UTF-8"); stringEntity.setContentType("application/json"); httpPost.setEntity(stringEntity); response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); log.info("POST請(qǐng)求響應(yīng) {}",response.getStatusLine().getStatusCode()); httpStr = EntityUtils.toString(entity, "UTF-8"); } catch (IOException e) { e.printStackTrace(); } finally { if (response != null) { try { EntityUtils.consume(response.getEntity()); } catch (IOException e) { e.printStackTrace(); } } } return httpStr; } /** * 發(fā)送 SSL POST 請(qǐng)求(HTTPS),K-V形式 * * @param apiUrl API接口URL * @param params 參數(shù)map * @return */ public static String doPostSSL(String apiUrl, Map<String, Object> params) { CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build(); HttpPost httpPost = new HttpPost(apiUrl); CloseableHttpResponse response = null; String httpStr = null; try { httpPost.setConfig(requestConfig); List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size()); for (Map.Entry<String, Object> entry : params.entrySet()) { NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString()); pairList.add(pair); } httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8"))); response = httpClient.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { return null; } HttpEntity entity = response.getEntity(); if (entity == null) { return null; } httpStr = EntityUtils.toString(entity, "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { EntityUtils.consume(response.getEntity()); } catch (IOException e) { e.printStackTrace(); } } } return httpStr; } /** * 發(fā)送 SSL POST 請(qǐng)求(HTTPS),JSON形式 * * @param apiUrl API接口URL * @param json JSON對(duì)象 * @return */ public static String doPostSSL(String apiUrl, Object json) { CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build(); HttpPost httpPost = new HttpPost(apiUrl); CloseableHttpResponse response = null; String httpStr = null; try { httpPost.setConfig(requestConfig); StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");//解決中文亂碼問(wèn)題 stringEntity.setContentEncoding("UTF-8"); stringEntity.setContentType("application/json"); httpPost.setEntity(stringEntity); response = httpClient.execute(httpPost); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { return null; } HttpEntity entity = response.getEntity(); if (entity == null) { return null; } httpStr = EntityUtils.toString(entity, "utf-8"); } catch (Exception e) { e.printStackTrace(); } finally { if (response != null) { try { EntityUtils.consume(response.getEntity()); } catch (IOException e) { e.printStackTrace(); } } } return httpStr; } /** * 創(chuàng)建SSL安全連接 * * @return */ private static SSLConnectionSocketFactory createSSLConnSocketFactory() { SSLConnectionSocketFactory sslsf = null; try { SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() { @Override public boolean verify(String arg0, SSLSession arg1) { return true; } @Override public void verify(String host, SSLSocket ssl) throws IOException { } @Override public void verify(String host, X509Certificate cert) throws SSLException { } @Override public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException { } }); } catch (GeneralSecurityException e) { e.printStackTrace(); } return sslsf; } }
到此這篇關(guān)于Spring Boot 如何生成微信小程序短連接,發(fā)送短信在短信中打開(kāi)小程序的文章就介紹到這了,更多相關(guān)Spring Boot 微信小程序短連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot項(xiàng)目實(shí)現(xiàn)短信發(fā)送接口開(kāi)發(fā)的實(shí)踐
- springboot整合RabbitMQ發(fā)送短信的實(shí)現(xiàn)
- SpringBoot使用榛子云實(shí)現(xiàn)手機(jī)短信發(fā)送驗(yàn)證碼
- Springboot實(shí)現(xiàn)Java阿里短信發(fā)送代碼實(shí)例
- SpringBoot實(shí)現(xiàn)發(fā)送短信的示例代碼
- SpringBoot+Security 發(fā)送短信驗(yàn)證碼的實(shí)現(xiàn)
- Springboot實(shí)現(xiàn)阿里云通信短信服務(wù)有關(guān)短信驗(yàn)證碼的發(fā)送功能
- Spring Boot實(shí)現(xiàn)微信小程序登錄
- Spring Boot 2結(jié)合Spring security + JWT實(shí)現(xiàn)微信小程序登錄
- springboot+jwt+springSecurity微信小程序授權(quán)登錄問(wèn)題
相關(guān)文章
SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用
OpenFeign對(duì)feign進(jìn)行進(jìn)一步的封裝,添加了springmvc的一些功能,更加強(qiáng)大,下面這篇文章主要給大家介紹了關(guān)于SpringCloud學(xué)習(xí)筆記之OpenFeign進(jìn)行服務(wù)調(diào)用的相關(guān)資料,需要的朋友可以參考下2022-01-01SpringBoot使用JPA實(shí)現(xiàn)查詢部分字段
這篇文章主要介紹了SpringBoot使用JPA實(shí)現(xiàn)查詢部分字段方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08從零開(kāi)始學(xué)SpringBoot如何開(kāi)始使用圖文詳解
這篇文章主要介紹了從零開(kāi)始學(xué)SpringBoot如何開(kāi)始使用,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Mybatis如何獲取insert新增數(shù)據(jù)id值
這篇文章主要介紹了Mybatis如何獲取insert新增數(shù)據(jù)id值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05MybatisX-Generator不生成domain文件夾的問(wèn)題及解決
在使用MybatisX-Generator生成數(shù)據(jù)庫(kù)表實(shí)體時(shí),如果發(fā)現(xiàn)沒(méi)有生成domain文件夾以及User.java文件,是因?yàn)镸ybatisX版本更新,最新版需要在options里額外勾選model才能生成domain,勾選model并點(diǎn)擊finish后,成功生成domain文件夾及User.java文件2025-01-01教你springboot+dubbo快速啟動(dòng)的方法
這篇文章主要介紹了springboot+dubbo快速啟動(dòng)的方法,dubbo的角色廣泛的分為三類(lèi)provider,comsumer,注冊(cè)中心,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下2022-04-04java實(shí)現(xiàn)菜單樹(shù)的示例代碼
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)菜單樹(shù)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12SpringBoot整合Web開(kāi)發(fā)之文件上傳與@ControllerAdvice
@ControllerAdvice注解是Spring3.2中新增的注解,學(xué)名是Controller增強(qiáng)器,作用是給Controller控制器添加統(tǒng)一的操作或處理。對(duì)于@ControllerAdvice,我們比較熟知的用法是結(jié)合@ExceptionHandler用于全局異常的處理,但其作用不止于此2022-08-08java實(shí)現(xiàn)兩臺(tái)服務(wù)器間文件復(fù)制的方法
這篇文章主要介紹了java實(shí)現(xiàn)兩臺(tái)服務(wù)器間文件復(fù)制的方法,是對(duì)單臺(tái)服務(wù)器上文件復(fù)制功能的升級(jí)與改進(jìn),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01