java調(diào)用微信接口實(shí)現(xiàn)網(wǎng)頁分享小功能
本文實(shí)例為大家分享了java調(diào)用微信接口實(shí)現(xiàn)網(wǎng)頁分享小功能的具體代碼,供大家參考,具體內(nèi)容如下
// 獲取access_token *注意* 經(jīng)過實(shí)際開發(fā)測試,微信分享不支持跨域請求,因此獲取access_token的請求必須從服務(wù)器發(fā)起,否則無法獲取到access_token所以以下都是服務(wù)端操作
微信接口說明參考地址
參考文章:Java微信分享接口開發(fā)詳解
一、微信util類
public class ShareConstants {
//微信獲取ticket的接口
public static final String TICKET_URL_TEST = "https://api.weixin.qq.com/cgi-bin/ticket/getticket" ;
public static final String type = "jsapi" ;
//微信獲取token的接口
public static final String GET_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
public static final String grant_type = "client_credential" ;
}
public class WeixinUtil {
private static Logger logger = LoggerFactory.getLogger(WeixinUtil.class) ;
public static boolean signatureCheck(String token,String timeStamp,String nonce,String signature) throws Exception{
List<String > list = new ArrayList<String>(3){
public String toString(){
return this.get(0)+this.get(1)+this.get(2) ;
}
} ;
list.add(token) ;
list.add(timeStamp) ;
list.add(nonce) ;
Collections.sort(list) ;
MessageDigest md = MessageDigest.getInstance("SHA-1") ;
byte[] digest = md.digest(list.toString().getBytes()) ;
String testStr = WeixinUtil.byteArrayToHexString(digest) ;
logger.info("token:{},timestamp:{},nonce:{},testStr:{}");
if(testStr.equalsIgnoreCase(signature.toUpperCase())){
return true;
}else{
return false ;
}
}
public static String signature(String jsapiTicket,String nonceStr,Long timestamp,String url) throws Exception{
String str = String.format("jsapi_ticket=%s&noncestr=%s×tamp=%d&url=%s",
jsapiTicket,nonceStr,timestamp,url) ;
logger.info("signature url:{}",str);
MessageDigest md = MessageDigest.getInstance("SHA-1") ;
byte[] digest = md.digest(str.getBytes()) ;
String sigStr = WeixinUtil.byteArrayToHexString(digest) ;
return sigStr ;
}
public static String byteArrayToHexString(byte[] array){
String strDigest = "" ;
for(int i = 0 ;i<array.length;i++){
strDigest+=byteToHexString(array[i]) ;
}
return strDigest ;
}
public static String byteToHexString(byte ib){
char[] Digit = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'} ;
char [] ob = new char[2] ;
ob[0] = Digit[(ib >>> 4) & 0X0F] ;
ob[1] = Digit[ib &0X0F] ;
String s = new String(ob) ;
return s ;
}
public static String getWeiXinShareToken(String appId,String secret) throws Exception{
Map<String,String> maps = new HashMap<String,String>() ;
maps.put("grant_type", ShareConstants.grant_type) ;
maps.put("appid",appId) ;
maps.put("secret",secret) ;
try{
String result = HttpInvokeUtil.httpGet(ShareConstants.GET_TOKEN_URL,maps) ;
JSONObject jsonObject = JSONObject.parseObject(result) ;
String access_token = (String) jsonObject.get("access_token") ;
Integer expires_in = (Integer) jsonObject.get("expires_in") ;
logger.debug("getToken access_token:{},expires_in:{}",access_token,expires_in);
if(access_token !=null && expires_in!=null && expires_in==7200)
return access_token ;
else
return null ;
}catch (Exception ex){
logger.error("ex:stack:{}",ex.getStackTrace().toString());
throw new Exception("get Token failed");
}
}
public static String getJsApiTicket(String token) throws Exception{
Map<String,String> maps = new HashMap<String,String>() ;
maps.put("access_token",token);
maps.put("type",ShareConstants.type);
try{
String result = HttpInvokeUtil.httpGet(ShareConstants.TICKET_URL_TEST,maps) ;
JSONObject jsonObject = JSONObject.parseObject(result) ;
Integer errcode = (Integer) jsonObject.get("errcode") ;
if(errcode==null || (errcode!=null &&errcode!=0)){
logger.error("get jsapiTicket is failed, errcode:{}",errcode);
return null ;
}else{
String ticket = (String) jsonObject.get("ticket") ;
return ticket ;
}
}catch (Exception ex){
logger.error("ex.stack:{}",ex.getStackTrace().toString());
throw new Exception("getJsApi Ticket is failed") ;
}
}
}
注意上面HttpInvokeUtil.httpGet()是httpclint這個(gè)可以自己去寫,只要能發(fā)請求就行,
二、controller層
//currUrl ==前端想要分享的網(wǎng)頁地址
@RequestMapping(value = "/getWConfig", method = RequestMethod.GET)
@ResponseBody
//@RequiredLogin
public FrameResp getWConfig(@Param("currUrl") String currUrl) throws UserException, Exception {
if (currUrl == null) {
return buildErrorResp(ErrorCodeConst.ERROR_PARAM_ERROR);
}
logger.info("get the encode currUrl {}", currUrl);
String urlTmp = URLDecoder.decode(currUrl, "UTF-8");
logger.info("decode currUrl {}", currUrl);
Long timestamp = new Date().getTime() / 1000;
String url = urlTmp.split("#")[0];
WConfigResp wConfigResp = new WConfigResp();
//修改為本地加載分享
//shareConfig.getAppId()==自己的appid
//shareConfig.getUxinAppSecret()==自己的AppSecret
String token = WeixinUtil.getWeiXinShareToken(shareConfig.getAppId(), shareConfig.getUxinAppSecret());
String ticket = WeixinUtil.getJsApiTicket(token);
if (ticket == null) {
logger.error("get jsApiTicketSec is failed");
throw new Exception("get jsApi is failed");
}
wConfigResp.setAppid(shareConfig.getAppId());
wConfigResp.setTimestamp(timestamp);
wConfigResp.setNonceStr(RandomStringUtils.random(10, true, true));
logger.info("appid:{},ticket:{},timestamp:{},nonceStr:{},url:{}", shareConfig.getAppId(), ticket, timestamp, wConfigResp.getNonceStr(), url);
String signature = WeixinUtil.signature(ticket, wConfigResp.getNonceStr(), wConfigResp.getTimestamp(), url);
if (signature != null) {
wConfigResp.setSignature(signature);
return buildSuccessResp(wConfigResp);
} else {
logger.error("getWcConfig is failed");
throw new Exception("error getWConfig");
}
}
三、自定義的返回值類-WConfigResp
@Data
public class WConfigResp extends BaseModel{
private String appid ;
private Long timestamp ;
private String nonceStr;
private String signature ;
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- JavaWeb項(xiàng)目打開網(wǎng)頁出現(xiàn)Session Error的異常解決方案
- java通過Jsoup爬取網(wǎng)頁過程詳解
- 詳解java實(shí)現(xiàn)簡單掃碼登錄功能(模仿微信網(wǎng)頁版掃碼)
- Java實(shí)現(xiàn)微信網(wǎng)頁授權(quán)的示例代碼
- Java實(shí)現(xiàn)的簡單網(wǎng)頁截屏功能示例
- java利用url實(shí)現(xiàn)網(wǎng)頁內(nèi)容的抓取
- 詳解JAVA抓取網(wǎng)頁的圖片,JAVA利用正則表達(dá)式抓取網(wǎng)站圖片
- Java導(dǎo)出網(wǎng)頁表格Excel過程詳解
相關(guān)文章
Spring Boot結(jié)合IDEA自帶Maven插件如何快速切換profile
IDEA是目前 Java 開發(fā)者中使用最多的開發(fā)工具,它有著簡約的設(shè)計(jì)風(fēng)格,強(qiáng)大的集成工具,便利的快捷鍵,這篇文章主要介紹了Spring Boot結(jié)合IDEA自帶Maven插件快速切換profile,需要的朋友可以參考下2023-03-03
Java多線程之定時(shí)器Timer的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java多線程中定時(shí)器Timer類的使用以及模擬實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10
Swagger2配置方式(解決404報(bào)錯(cuò))
這篇文章主要介紹了Swagger2配置方式(解決404報(bào)錯(cuò)),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
JavaWeb Refresh響應(yīng)頭代碼實(shí)例詳解
這篇文章主要介紹了JavaWeb Refresh響應(yīng)頭代碼實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
詳解SpringBoot中Session超時(shí)原理說明
本篇文章主要介紹了詳解SpringBoot中Session超時(shí)原理說明,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
Java Annotation注解相關(guān)原理代碼總結(jié)
這篇文章主要介紹了Java Annotation注解相關(guān)原理代碼總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
JFreeChart動(dòng)態(tài)畫折線圖的方法
這篇文章主要為大家詳細(xì)介紹了JFreeChart動(dòng)態(tài)畫折線圖的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06

