java微信分享功能(分享给好友/分享到朋友圈)

1 篇文章 0 订阅

加密

package com.itsoft.customer.commons.wx;


import java.security.MessageDigest;

public class Sha1 {

    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }

    public static String encode(String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

随机字符串

package com.itsoft.customer.commons.wx;

import java.util.Random;

public class RandomStr {

    private static char ch[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
            'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
            'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
            'x', 'y', 'z', '0', '1' };//最后又重复两个0和1,因为需要凑足数组长度为64

    private static Random random = new Random();

    //生成指定长度的随机字符串
    public static String createRandomString(int length) {
        if (length > 0) {
            int index = 0;
            char[] temp = new char[length];
            int num = random.nextInt();
            for (int i = 0; i < length % 5; i++) {
                temp[index++] = ch[num & 63];//取后面六位,记得对应的二进制是以补码形式存在的。
                num >>= 6;//63的二进制为:111111
                // 为什么要右移6位?因为数组里面一共有64个有效字符。为什么要除5取余?因为一个int型要用4个字节表示,也就是32位。
            }
            for (int i = 0; i < length / 5; i++) {
                num = random.nextInt();
                for (int j = 0; j < 5; j++) {
                    temp[index++] = ch[num & 63];
                    num >>= 6;
                }
            }
            return new String(temp, 0, length);
        }
        else if (length == 0) {
            return "";
        }
        else {
            throw new IllegalArgumentException();
        }
    }

    public static void main(String[] args) {
        System.out.println(createRandomString(16));
    }
}

发送请求

package com.itsoft.customer.controller;

import cn.hutool.json.JSONUtil;
import com.itsoft.customer.commons.interceptor.ResponseResult;
import com.itsoft.customer.commons.wx.RandomStr;
import com.itsoft.customer.commons.wx.Sha1;
import com.itsoft.framework.core.data.DataMap;
import com.itsoft.framework.core.data.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URI;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping(value = "/frontendGetWx", produces = "application/json;charset=UTF-8")
@ResponseResult
@Api(value = "(getWx)getWx 微信权限", tags  = "(getWx)getWx 微信权限")
public class ShareController extends CommonController{

    /**
     * 微信公众号的appid
     */
    private String appid="wx";

    /**
     * 微信公众号的appSecret
     */
    private String secret="db";


    /**
     * 获取微信分享配置的请求  方法只写了主要方法,需要根据自己的要求 完善代码
     * @param url 前台传过来的当前页面的请求地址
     * @return
     */
    @ApiOperation(notes = "获取微信分享配置的请求  方法只写了主要方法,需要根据自己的要求 完善代码", value = "获取微信分享配置的请求  方法只写了主要方法,需要根据自己的要求 完善代码")
    @RequestMapping(value = "/getWxConfig",method = RequestMethod.POST)
    public Result share(String url){
        long timestamp = System.currentTimeMillis() / 1000;
        String noncestr = RandomStr.createRandomString(16);
        String ticket =getJsapiTicket();
        String str = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
        logger.info("===============签名str:{}============" , str);
        String signature = Sha1.encode(str);

        //这只是简单写法,没有做错误判断
        Map map=new HashMap();
        map.put("appId",appid);
        map.put("timestamp",timestamp);
        map.put("nonceStr",noncestr);
        map.put("signature",signature);

        //这里使用了hutool工具将map转为String
       // String json = JSONUtil.toJsonStr(map);

        return Result.success(map);
    }

    /**
     * 官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#62
     *
     * 获取jsapi_ticket
     *
     *
     *  生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。
     *  正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。
     *  由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
     *
     * 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):
     * https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
     *
     * 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):
     * https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
     *
     * @return
     */
    public String getJsapiTicket() {
        String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
        tokenUrl = tokenUrl + "&appid=" + appid + "&secret=" + secret;
        JSONObject tokenJson=new JSONObject();
        tokenJson=getUrlResponse(tokenUrl);
        logger.info("===============tokenJson:{}============" , tokenJson.toString());
        String token="";
        try {
            token=tokenJson.getString("access_token");
        } catch (JSONException e) {
            e.printStackTrace();
            logger.info("===============报错了{}============" , e);
            System.out.println("报错了");
            return null;
        }

        String jsapiTicketUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
        JSONObject jsapiTickeJson=new JSONObject();
        System.out.println("getJsapiTicket:获取token:"+token);
        if(StringUtils.isNotBlank(token)){
            jsapiTicketUrl = jsapiTicketUrl.replace("ACCESS_TOKEN",token);
            jsapiTickeJson=getUrlResponse(jsapiTicketUrl);
           // System.out.println("tokenJson:"+jsapiTickeJson.toString());
            logger.info("===============tokenJson:{}============" ,jsapiTickeJson.toString());
            try {
                return (String) jsapiTickeJson.get("ticket");
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }
        }else{
            return null;
        }
    }

    private  JSONObject getUrlResponse(String url){
        CharsetHandler handler = new CharsetHandler("UTF-8");
        try {
            HttpGet httpget = new HttpGet(new URI(url));
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            //HttpClient
            CloseableHttpClient client = httpClientBuilder.build();
            client = (CloseableHttpClient) wrapClient(client);
            return new JSONObject(client.execute(httpget, handler));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    private static HttpClient wrapClient(HttpClient base) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLSv1");
            X509TrustManager tm = new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] xcs,
                                               String string) throws CertificateException {
                }

                public void checkServerTrusted(X509Certificate[] xcs,
                                               String string) throws CertificateException {
                }

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "TLSv1" }, null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            return httpclient;

        } catch (Exception ex) {
            return null;
        }
    }

    private class CharsetHandler implements ResponseHandler<String> {
        private String charset;

        public CharsetHandler(String charset) {
            this.charset = charset;
        }

        public String handleResponse(HttpResponse response)
                throws ClientProtocolException, IOException {
            StatusLine statusLine = response.getStatusLine();
            if (statusLine.getStatusCode() >= 300) {
                throw new HttpResponseException(statusLine.getStatusCode(),
                        statusLine.getReasonPhrase());
            }
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                if (!StringUtils.isBlank(charset)) {
                    return EntityUtils.toString(entity, charset);
                } else {
                    return EntityUtils.toString(entity);
                }
            } else {
                return null;
            }
        }
    }

}
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值