第一步:设置js安全域名
第二步:设置IP白名单
第三步:初始化微信配置
js代码
$(function(){
$.ajax({
url: '../mini_Weixin_getConfig.action',
dataType: 'json',
type: 'GET',
data: {
"link": location.href.split("#")[0]
},
async: false,
success: function (data) {
if(data){
wx.config({
debug: false, // 开启调试模式为true后可以通过alert弹窗将公众号签名等结果反馈出来
appId: data.appid, // 必填,公众号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signature,// 必填,签名,见附录1
jsApiList: ['checkJsApi',
'chooseImage',
'uploadImage'
] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
}
}
});
});
后端代码
/**
* 获取jssdk所需配置参数
*/
public String getConfig(String link){
try {
String noncestr = UUID.randomUUID().toString().replaceAll("-", "");//随机数
String timestamp = getTimeStamp();//时间戳
//获取sign签名的相关参数
SortedMap<String, String> signParams = new TreeMap<String, String>();
signParams.put("jsapi_ticket", TokenThread.access_token.getJsapi_ticket());
signParams.put("noncestr", noncestr);
signParams.put("timestamp",timestamp);
signParams.put("url",link);
String signature = MiniUtil.createSHA1Sign(signParams);//JS-SDK使用权限签名
JSONObject jsonObject = new JSONObject();
jsonObject.put("url", link);
jsonObject.put("appid", TokenThread.appId);
jsonObject.put("timestamp", timestamp);
jsonObject.put("nonceStr", noncestr);
jsonObject.put("signature", signature);
logger.info("jssdk的相关参数jsonObject.toString()==="+jsonObject.toString());
return jsonObject.toString();
} catch (Exception e) {
e.printStackTrace();
logger.info(e);
}
return "";
}
Util类
/**
* TokenThread线程
*/
public class TokenThread implements Runnable {
public static AccessToken access_token = null;
public static String appId ="公众号appId";
public static String appsecret = "公众号appsecret";
@Override
public void run() {
while (true) {
try {
// 调用工具类获取access_token(每日最多获取100000次,每次获取的有效期为7200秒)
System.out.println("获取accessToken开始");
access_token = AccessToken.getAccessToken(appId, appsecret);// 微信公众号的凭证和秘钥
if (null != access_token) {
access_token = AccessToken.getMiniAccessToken(access_token, appId, appsecret);//获取accessToken
// 7000秒之后重新进行获取
Thread.sleep((access_token.getExpires_in() - 200) * 1000);
} else {
// 获取失败时,60秒之后尝试重新获取
System.out.println("获取失败时,60秒之后尝试重新获取");
Thread.sleep(60 * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class AccessToken {
static Logger logger = Logger.getLogger(AccessToken.class);
private String access_token;// 获取到的access_token
private int expires_in; // 有效时间(两个小时,7200s)
private String jsapi_ticket;// jsapi_ticket是公众号用于调用微信JS接口的临时票据。有效时间(两个小时,7200s)
private String access_token_mini;// 获取小程序的access_token
private int expires_in_mini; // 小程序有效时间(两个小时,7200s)
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public int getExpires_in() {
return expires_in;
}
public void setExpires_in(int expires_in) {
this.expires_in = expires_in;
}
public String getJsapi_ticket() {
return jsapi_ticket;
}
public void setJsapi_ticket(String jsapi_ticket) {
this.jsapi_ticket = jsapi_ticket;
}
public String getAccess_token_mini() {
return access_token_mini;
}
public void setAccess_token_mini(String access_token_mini) {
this.access_token_mini = access_token_mini;
}
public int getExpires_in_mini() {
return expires_in_mini;
}
public void setExpires_in_mini(int expires_in_mini) {
this.expires_in_mini = expires_in_mini;
}
/**
* 获取accessToken
* @param appID,微信公众号凭证
* @param appScret,微信公众号凭证秘钥
* @return
*/
public static AccessToken getAccessToken(String appID, String appScret) {
AccessToken token = new AccessToken();
// 访问微信服务器-获取accessToken
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+ appID + "&secret=" + appScret;
try {
URL getUrl = new URL(url);
HttpURLConnection http = (HttpURLConnection) getUrl.openConnection();
http.setRequestMethod("GET");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
InputStream is = http.getInputStream();
int size = is.available();
byte[] b = new byte[size];
is.read(b);
String message = new String(b, "UTF-8");
logger.info("getAccessToken.message=="+message);
JSONObject json = JSONObject.fromObject(message);
token.setAccess_token(json.getString("access_token"));
token.setExpires_in(new Integer(json.getString("expires_in")));
// 用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒
token = getJsapiTicket(token);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return token;
}
/**
* 获取jsapi_ticket
* 首先要先获取到access_token,再根据access_token获取jsapi_ticket
* @return
*/
public static AccessToken getJsapiTicket(AccessToken token) {
// 访问微信服务器-获取accessToken
String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+token.getAccess_token()+"&type=jsapi";
try {
URL getUrl = new URL(jsapi_ticket_url);
HttpURLConnection http = (HttpURLConnection) getUrl.openConnection();
http.setRequestMethod("GET");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
InputStream is = http.getInputStream();
int size = is.available();
byte[] b = new byte[size];
is.read(b);
String message = new String(b, "UTF-8");
System.out.println("getJsapiTicket.message=="+message);
JSONObject json = JSONObject.fromObject(message);
token.setJsapi_ticket(json.getString("ticket"));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return token;
}
/**
* 获取accessToken
* @param appID,微信小程序凭证
* @param appScret,微信小程序凭证秘钥
* @return
*/
public static AccessToken getMiniAccessToken(AccessToken token,String appID, String appScret) {
// 访问微信服务器-获取accessToken
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appID + "&secret=" + appScret;
try {
URL getUrl = new URL(url);
HttpURLConnection http = (HttpURLConnection) getUrl.openConnection();
http.setRequestMethod("GET");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
InputStream is = http.getInputStream();
int size = is.available();
byte[] b = new byte[size];
is.read(b);
String message = new String(b, "UTF-8");
System.out.println("getMiniAccessToken.message=="+message);
JSONObject json = JSONObject.fromObject(message);
token.setAccess_token_mini(json.getString("access_token"));
token.setExpires_in_mini(new Integer(json.getString("expires_in")));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return token;
}
}
第四步:js调用
//图片上传
function face(){
wx.ready(function(){
// 5 图片接口
// 5.1 拍照、本地选图
var images = {
localId: [],
serverId: []
};
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
images.localId = res.localIds;
//alert('已选择 ' + res.localIds.length + ' 张图片');
//$("#faceImg").attr("src", res.localIds[0]);//显示图片到页面上
if (images.localId.length == 0) {
alert('请先选择图片');
return;
}
$.showLoading("数据加载中");
var i = 0, length = images.localId.length;
images.serverId = [];
function upload() {
wx.uploadImage({
localId: images.localId[i],
success: function (res) {
i++;
//alert('已上传:' + i + '/' + length);
images.serverId.push(res.serverId);
if (i < length) {
upload();
}
getInfo(res.serverId);
},
fail: function (res) {
}
});
}
upload();
}
});
//初始化jsapi接口 状态
wx.error(function (res) {
alert("调用微信jsapi返回的状态:"+res.errMsg);
});
});
}
//图片下载至自己服务器
function getInfo(mediaId){
$.ajax({
type : "POST",
url :'../mini_downloadMedia.action',
data : {"mediaId":mediaId},
dataType : "json",
success : function(data) {
$.hideLoading();
var json = data;
}
});
}
后端代码
/**
* 下载微信图片至本地服务器
* imgPath:图片保存所在文件夹
*/
String imgPath = "wxImg"; //图片所在文件夹
public String downloadMedia(String mediaId){
HttpServletRequest request = ServletActionContext.getRequest();
String savePath = DirectoryUtil.getProjectParentPath(request).concat(File.separator).
concat(DirectoryUtil.getProjectName(request)).concat("Files")+"\\"+imgPath;//savePath根据自己的需求来获取保存路径
String fileName = DloadImgUtil.downloadMedia(mediaId, savePath);
//System.out.println(fileName);
return fileName;
}
图片下载Util类
/**
* 获取媒体文件
* @param accessToken 接口访问凭证
* @param mediaId 媒体文件id
* @param savePath 文件在本地服务器上的存储路径
* */
public static String downloadMedia( String mediaId, String savePath) {
String accessToken = TokenThread.access_token.getAccess_token();
String filePath = null;
String fileName = null;
// 拼接请求地址
String requestUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID";
requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("MEDIA_ID", mediaId);
try {
URL url = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setRequestMethod("GET");
if (!savePath.endsWith("/")) {
savePath += "/";
}
// 将mediaId作为文件名
//filePath = savePath + mediaId + fileExt;
fileName = IDUtil.getCustomUUID() + ".jpg";
filePath = savePath + fileName;
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
FileOutputStream fos = new FileOutputStream(new File(filePath));
byte[] buf = new byte[8096];
int size = 0;
while ((size = bis.read(buf)) != -1)
fos.write(buf, 0, size);
fos.close();
bis.close();
conn.disconnect();
String info = String.format("下载媒体文件成功,filePath=" + filePath);
logger.info(info);
} catch (Exception e) {
filePath = null;
String error = String.format("下载媒体文件失败:%s", e);
System.out.println(error);
logger.info(error);
}
return fileName;
}
第五步:启动项目,并开启定时获取access_token的线程
/**
* 初始化时启动定时获取access_token的线程
* 需在项目启动的时候启动该servlet
* @ClassName: GetAccessTokenServlet
* @author admin
*/
public class GetAccessTokenServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init() throws ServletException {
new Thread(new TokenThread()).start();// 启动定时获取access_token的线程
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
new Thread(new TokenThread()).start();
super.doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>loadCAServlet</servlet-name>
<servlet-class>com.servlet.GetAccessTokenServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>loadCAServlet</servlet-name>
<url-pattern>/loadCAServlet</url-pattern>
</servlet-mapping>
完成。。。