网上看了好多大佬的文章,发现都不太适合我这种小白来操作,so只能结合大部分代码来自己操作,捣鼓了2天终于可以实现转发带着图片和描述了,我认为的比较简单的整个流程是这样的(哪里不正确请大佬指教):通过api连接获得access_token>通过access_token来换取jsapi(ticket)>获取时间毫秒数/随即字符串/动态获取的url>把这四个参数放到str中并使用SHA1加密再传到前台即可,废话不多说,开始代码(servlet):
获取token和ticket的类:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
* 获取token 获取ticket
* @author Administrator
*
*/
public class JsapiTicketUtil {
public static String sendGet(String url, String charset, int timeout)
{
String result = "";
try
{
URL u = new URL(url);
try
{
URLConnection conn = u.openConnection();
conn.connect();
conn.setConnectTimeout(timeout);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
String line="";
while ((line = in.readLine()) != null)
{
result = result + line;
}
in.close();
} catch (IOException e) {
return result;
}
}
catch (MalformedURLException e)
{
return result;
}
return result;
}
/***
* 获取acess_token
* @return
*/
public static String getAccessToken(){
//获取token
String acess_token ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你自己的appid";
String token = sendGet(acess_token, "utf-8", 10000);
return token;
}
/***
* 获取jsapiTicket
*/
public static String getJSApiTicket(){
JsonParser jsonparer = new JsonParser();
JsonObject json = null;
JsonObject json2 = null;
//获取token
String acess_token= getAccessToken();
json = jsonparer.parse(acess_token).getAsJsonObject();
String access_token = json.get("access_token").getAsString();
//获取JsAPI
String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
String backData=sendGet(urlStr, "utf-8", 10000);
json2 = jsonparer.parse(backData).getAsJsonObject();
String ticket = json2.get("ticket").getAsString();
System.out.println(ticket);
return ticket;
}
}
获得随机字符串类:
import java.util.UUID;
/**
* 获取随即字符串
* @author Administrator
*
*/
public class Create_nonce_str {
public static String create_nonce_str() {
return UUID.randomUUID().toString();
}
}
SHA1加密类
import java.security.MessageDigest;
/**
* SHA1加密
* @author Administrator
*
*/
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);
}
}
}
处理和发送到前台的dopost方法
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
String timestamp = Long.toString(System.currentTimeMillis() / 1000);
String nonceStr = Create_nonce_str.create_nonce_str();
//这个url一定要动态获取,不能写死
String url="http://"+req.getServerName()+req.getContextPath()+"/";System.out.println("当前地址为:"+url);
String jsapi_ticket = JsapiTicketUtil.getJSApiTicket();
System.out.println("时间戳:"+timestamp+"随即串:"+nonceStr+"ticket:"+jsapi_ticket);
//所有参数必须小写且有序
String str = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonceStr +
"×tamp=" + timestamp +
"&url=" + url;
//sha1加密
String signature = SHA1.encode(str);
System.out.println("生成的签名:"+signature);
//将三个参数拼接成字符串到前台,再由逗号分割取出
String data = timestamp+","+nonceStr+","+signature;
out.print(data);
out.flush();
out.close();
}
前台代码(我是写在body中了):
<script type="text/javascript"
src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script type="text/javascript">
window.onload=function(){
//定义全局变量 接收后台传递的三个参数
var nonceStr;
var signature;
$.ajax({
type : "POST",
dataType : "text",
url : "${ctx}/GainWXServlet.do",
success : function(data) {
if (data != null) {
var arr=data.split(",");
timestamp = arr[0];
nonceStr = arr[1];
signature = arr[2];
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '你的id', // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature,// 必填,签名
jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表
});
wx.checkJsApi({
jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
}
});
wx.onMenuShareTimeline({
title: '分享标题', // 分享标题
link: '分享链接', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '分享图标', // 分享图标
success: function () {
// 用户点击了分享后执行的回调函数
}});
wx.onMenuShareAppMessage({
title: '', // 分享标题
desc: '', // 分享描述
link: 'http://fifa.dlscanyin.com/', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: 'http://fifa.dlscanyin.com/images/logo.jpg', // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户点击了分享后执行的回调函数
}
});
} else {
alert("数据没有获取到哦~");
}
}
});
};
</script>
PS:如果发生
{errmsg:config: invalid signature}
首先检查去微信的这个链接:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign,将自己的代码中的数据和它的数据做对比,如果还有问题,请检查url错误,可能最后的一个"/"都能引起这个错误,最后说下,我的代码比较简单,里面肯定有很多不合理的地方,请大佬多多指教