首先在公众号后台获取卡券id,获取公众号的appid和accessToken,opendid(小程序端):小程序登陆时获取存起来
导入weixin4j包
java代码,小程序略
package com.enation.app.shop.wechat.controller;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.weixin4j.WeixinException;
import org.weixin4j.http.HttpsClient;
import org.weixin4j.http.Response;
import com.enation.app.shop.wechat.model.AccessToken;
import com.enation.app.shop.wechat.model.ApiTicket;
import com.enation.app.shop.wechat.model.WeixinSignature;
import com.enation.app.shop.wechat.utils.WeChatCart;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller
@RequestMapping("/")
public class WechatGetTicket {
public static ApiTicket ticket = null;//使用全局静态变量存储ApiTicket对象,当然如果使用缓存框架保存当然更好,这边只是做一个简单示例
private final static String string = "0123456789";
final private static char[] chars = string.toCharArray();
/**
* @Description: 获取领取卡券获取签名等参数
* @param cardId:需要领取的卡券的cardId
* @return
* @throws WeixinException
* @throws JsonParseException
* @throws JsonMappingException
* @throws IOException
*/
@RequestMapping("/")
@ResponseBody
public Map getCardSign(String cardId) throws WeixinException, JsonParseException, JsonMappingException, IOException{
Map ret = new HashMap();
//先要获取api_ticket,由于请求api_ticket的接口访问有次数限制,所以最好将获得到的api_ticket保存到缓存中,这边做法比较简单,直接使用的静态变量
if(ticket == null || ticket.getExpires_in() < System.currentTimeMillis()){
//创建请求对象
HttpsClient http = new HttpsClient();
ObjectMapper mapper = new ObjectMapper();
AccessToken token = WeChatCart.getToken();//这里获取的token就是最上方代码保存的微信公众号全局静态变量token
System.out.println(token.getErrcode());
//通过access_token调用获取api_ticket接口
Response res = http.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token.getAccess_token() + "&type=wx_card");
System.out.println("api_ticket:===========>"+res.asString());
ticket = mapper.readValue(res.asString(), ApiTicket.class);
}
ret = sign(ticket.getTicket(), cardId);//生成领取卡券需要的签名,并返回相关的参数
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
}
return ret;
}
/**
* @param api_ticket:
* @param cardId:需要领取的卡券的cardId
* @return
* @Description: 生成卡券需要的签名并返回参数
*/
public static Map sign(String api_ticket, String cardId) {
Map ret = new HashMap();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String signature = "";
WeixinSignature signatures = new WeixinSignature(api_ticket, timestamp, cardId, nonce_str);
ret.put("card_id", cardId);
ret.put("api_ticket", api_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signatures.sign());
return ret;
}
/**
* 返回时间戳(秒)
* @return
*/
private static String create_timestamp() {
return String.valueOf(new Date().getTime() / 1000);
}
/**
* 返回随机字符串
* @return
*/
private static String create_nonce_str() {
String nonce = new String();
for (int i = 0; i < 32; i++) {
int rannum = (int) (Math.random() * 1000) % (chars.length);
nonce += chars[rannum];
}
return nonce;
}
/**
* Convert byte[] to hex string
* @param src byte[] data
* @return hex string
*/
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
}
package com.enation.app.shop.wechat.base;
public class BaseResponse {
private int errcode;
private String errmsg;
public int getErrcode() {
return errcode;
}
public void setErrcode(int errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
}
package com.enation.app.shop.wechat.model;
import com.enation.app.shop.wechat.base.BaseResponse;
public class AccessToken extends BaseResponse{
private String access_token;
private long expires_in;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public long getExpires_in() {
return expires_in;
}
public void setExpires_in(long expires_in) {
this.expires_in = System.currentTimeMillis() + (expires_in - 100) * 1000;//原expires_in是有效时长,比如:7200,现改为过期的时间戳
}
}
package com.enation.app.shop.wechat.model;
import com.enation.app.shop.wechat.base.BaseResponse;
public class ApiTicket extends BaseResponse{
private String ticket;
private long expires_in;
public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public long getExpires_in() {
return expires_in;
}
public void setExpires_in(long expires_in) {
this.expires_in = System.currentTimeMillis() + (expires_in - 100) * 1000;//原expires_in是有效时长,比如:7200,现改为过期的时间戳
}
}
package com.enation.app.shop.wechat.model;
public class OAuthJsToken {
private String openid; //用户唯一标识
private int expires_in = 7200; //凭证有效时间,单位:秒
private String session_key; //会话密匙
private long exprexpiredTime; //过期时间
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public int getExpires_in() {
return expires_in;
}
public void setExpires_in(int expires_in) {
this.expires_in = expires_in;
this.exprexpiredTime = System.currentTimeMillis() + expires_in * 1000;
}
public String getSession_key() {
return session_key;
}
public void setSession_key(String session_key) {
this.session_key = session_key;
}
public long getExprexpiredTime() {
return exprexpiredTime;
}
public void setExprexpiredTime(long exprexpiredTime) {
this.exprexpiredTime = exprexpiredTime;
}
/**
* 判断用户凭证是否过期
*
* @return 过期返回 true,否则返回false
*/
public boolean isExprexpired() {
return System.currentTimeMillis() >= this.exprexpiredTime;
}
}
package com.enation.app.shop.wechat.model;
import java.util.Arrays;
import com.enation.app.shop.wechat.utils.GetSha1;
public class WeixinSignature
{
private String api_ticket;
private String timestamp;
private String card_id;
private String nonce_str;
public WeixinSignature(String api_ticket, String timestamp, String card_id, String nonce_str)
{
this.api_ticket = api_ticket;
this.timestamp = timestamp;
this.card_id = card_id;
this.nonce_str = nonce_str;
}
public String sign()
{
String[] str = { this.api_ticket, this.timestamp, this.card_id, this.nonce_str };
System.out.println("加密调用的加密参数" + str.toString());
Arrays.sort(str);
String string = new String();
for (int i = 0; i < 4; i++) {
string = string + str[i];
}
String signature = null;
signature = GetSha1.getSha1(string);
return signature;
}
}
package com.enation.app.shop.wechat.utils;
import java.security.MessageDigest;
public class GetSha1
{
public static String getSha1(String str)
{
if ((str == null) || (str.length() == 0)) {
return null;
}
char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
mdTemp.update(str.getBytes("UTF-8"));
byte[] md = mdTemp.digest();
int j = md.length;
char[] buf = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
buf[(k++)] = hexDigits[(byte0 >>> 4 & 0xF)];
buf[(k++)] = hexDigits[(byte0 & 0xF)];
}
return new String(buf);
} catch (Exception e) {
}
return null;
}
}