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ā)測(cè)試,微信分享不支持跨域請(qǐng)求,因此獲取access_token的請(qǐng)求必須從服務(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ā)請(qǐng)求就行,
二、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 ; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- JavaWeb項(xiàng)目打開網(wǎng)頁出現(xiàn)Session Error的異常解決方案
- java通過Jsoup爬取網(wǎng)頁過程詳解
- 詳解java實(shí)現(xiàn)簡(jiǎn)單掃碼登錄功能(模仿微信網(wǎng)頁版掃碼)
- Java實(shí)現(xiàn)微信網(wǎng)頁授權(quán)的示例代碼
- Java實(shí)現(xiàn)的簡(jiǎ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)文章
MyBatis自定義resultMap三種映射關(guān)系示例詳解
這篇文章主要介紹了MyBatis自定義resultMap三種映射關(guān)系,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08SpringBoot實(shí)現(xiàn)文件的上傳、下載和預(yù)覽功能
在Spring Boot項(xiàng)目中實(shí)現(xiàn)文件的上傳、下載和預(yù)覽功能,可以通過使用Spring MVC的MultipartFile接口來處理文件上傳,并使用HttpServletResponse或Resource來實(shí)現(xiàn)文件下載和預(yù)覽,下面是如何實(shí)現(xiàn)這些功能的完整示例,需要的朋友可以參考下2024-08-08Spring Boot優(yōu)化后啟動(dòng)速度快到飛起技巧示例
這篇文章主要為大家介紹了Spring Boot優(yōu)化后啟動(dòng)速度快到飛起的技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07springmvc字符編碼過濾器CharacterEncodingFilter的使用
這篇文章主要介紹了springmvc字符編碼過濾器CharacterEncodingFilter的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2021-08-08SpringData @Query和@Modifying注解原理解析
這篇文章主要介紹了SpringData @Query和@Modifying注解原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08