Java微信二次开发(十)
生成带参数的二维码以及长链接转短链接
第一步:找到包com.wtz.vo,新建类WeixinQRCode.java
package com.wtz.vo; /**
* @author wangtianze QQ:864620012
* @date 2017年4月25日 下午3:01:57
* <p>version:1.0</p>
* <p>description:临时二维码信息</p>
*/
public class WeixinQRCode {
//获取的二维码ticket
private String ticket;
//二维码的有效时间,单位为秒,最大不超过2592000
private int expireSeconds; public String getTicket() {
return ticket;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public int getExpireSeconds() {
return expireSeconds;
}
public void setExpireSeconds(int expireSeconds) {
this.expireSeconds = expireSeconds;
}
}
第二步:找到包com.wtz.util,修改类AdvancedUtil.java
package com.wtz.util; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import javax.net.ssl.HttpsURLConnection; import net.sf.json.JSONArray;
import net.sf.json.JSONObject; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.wtz.vo.UserInfo;
import com.wtz.vo.UserList;
import com.wtz.vo.WeixinMedia;
import com.wtz.vo.WeixinQRCode; /**
* @author wangtianze QQ:864620012
* @date 2017年4月24日 下午7:36:03
* <p>version:1.0</p>
* <p>description:高级接口工具类</p>
*/
public class AdvancedUtil {
private static Logger log = LoggerFactory.getLogger(AdvancedUtil.class); /**
* 获取用户信息
*
* @param accessToken 接口访问凭证
* @param openId 用户凭证
* @return WeixinUserInfo
*/
public static UserInfo getUserInfo(String accessToken,String openId){
UserInfo weixinUserInfo = null;
//拼接请求地址
String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken).replace("OPENID",openId);
//获取用户信息
JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "GET", null); if(null != jsonObject){
try{
weixinUserInfo = new UserInfo(); //用户的标识
weixinUserInfo.setOpenId(jsonObject.getString("openid")); //关注状态(1是关注,0是未关注),未关注时获取不到其余信息
weixinUserInfo.setSubscribe(jsonObject.getInt("subscribe")); //用户关注时间
weixinUserInfo.setSubscribeTime(jsonObject.getString("subscribe_time")); //昵称
weixinUserInfo.setNickname(jsonObject.getString("nickname")); //用户的性别(1是男性,2是女性,0是未知)
weixinUserInfo.setSex(jsonObject.getInt("sex")); //用户所在的国家
weixinUserInfo.setCountry(jsonObject.getString("country")); //用户所在的省份
weixinUserInfo.setProvince(jsonObject.getString("province")); //用户所在的城市
weixinUserInfo.setCity(jsonObject.getString("city")); //用户的语言,简体中文为zh_CN
weixinUserInfo.setLanguage(jsonObject.getString("language")); //用户头像
weixinUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl")); //uninonid
weixinUserInfo.setUnionid(jsonObject.getString("unionid"));
}catch(Exception e){
if(0 == weixinUserInfo.getSubscribe()){
log.error("用户{}已取消关注",weixinUserInfo.getOpenId());
}else{
int errorCode = jsonObject.getInt("errcode");
String errorMsg = jsonObject.getString("errmsg");
log.error("获取用户信息失败 errorcode:{} errormsg:{}",errorCode,errorMsg);
}
}
}
return weixinUserInfo;
} /**
* 获取关注者列表
*
* @param accessToken 调用接口凭证
* @param nextOpenId 第一个拉取nextOpenId,不填默认从头开始拉取
* @return WeixinUserList
*/
@SuppressWarnings({ "deprecation", "unchecked" })
public static UserList getUserList(String accessToken,String nextOpenId){
UserList weixinUserList = null;
if(null == nextOpenId){
nextOpenId = "";
}
//拼接请求地址
String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID"; requestUrl.replace("ACCESS_TOKEN", accessToken).replace("NEXT_OPENID",nextOpenId); //获取关注者列表
JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "GET", null); //如果请求成功
if(null != jsonObject){
weixinUserList = new UserList();
weixinUserList.setTotal(jsonObject.getInt("total"));
weixinUserList.setCount(jsonObject.getInt("count"));
weixinUserList.setNextOpenId(jsonObject.getString("next_openid"));
JSONObject dataObject = (JSONObject)jsonObject.get("data");
weixinUserList.setOpenIdList(JSONArray.toList(dataObject.getJSONArray("openid"),List.class));
} return weixinUserList;
} /**
* 上传媒体文件
* @param accessToken 接口访问凭证
* @param type 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
* @param media form-data中媒体文件标识,有filename、filelength、content-type等信息
* @param mediaFileUrl 媒体文件的url
* 上传的媒体文件限制
* 图片(image):1MB,支持JPG格式
* 语音(voice):2MB,播放长度不超过60s,支持AMR格式
* 视频(video):10MB,支持MP4格式
* 普通文件(file):10MB
* */
public static WeixinMedia uploadMedia(String accessToken, String type, String mediaFileUrl) {
WeixinMedia weixinMedia = null;
// 拼装请求地址
String uploadMediaUrl = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
uploadMediaUrl = uploadMediaUrl.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type); // 定义数据分隔符
String boundary = "------------7da2e536604c8";
try {
URL uploadUrl = new URL(uploadMediaUrl);
HttpURLConnection uploadConn = (HttpURLConnection) uploadUrl.openConnection();
uploadConn.setDoOutput(true);
uploadConn.setDoInput(true);
uploadConn.setRequestMethod("POST");
// 设置请求头Content-Type
uploadConn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
// 获取媒体文件上传的输出流(往微信服务器写数据)
OutputStream outputStream = uploadConn.getOutputStream(); URL mediaUrl = new URL(mediaFileUrl);
HttpURLConnection meidaConn = (HttpURLConnection) mediaUrl.openConnection();
meidaConn.setDoOutput(true);
meidaConn.setRequestMethod("GET"); // 从请求头中获取内容类型
String contentType = meidaConn.getHeaderField("Content-Type");
// 根据内容类型判断文件扩展名
String fileExt = WeixinUtil.getFileExt(contentType);
// 请求体开始
outputStream.write(("--" + boundary + "\r\n").getBytes());
outputStream.write(String.format("Content-Disposition: form-data; name=\"media\"; filename=\"file1%s\"\r\n", fileExt).getBytes());
outputStream.write(String.format("Content-Type: %s\r\n\r\n", contentType).getBytes()); // 获取媒体文件的输入流(读取文件)
BufferedInputStream bis = new BufferedInputStream(meidaConn.getInputStream());
byte[] buf = new byte[8096];
int size = 0;
while ((size = bis.read(buf)) != -1) {
// 将媒体文件写到输出流(往微信服务器写数据)
outputStream.write(buf, 0, size);
}
// 请求体结束
outputStream.write(("\r\n--" + boundary + "--\r\n").getBytes());
outputStream.close();
bis.close();
meidaConn.disconnect(); // 获取媒体文件上传的输入流(从微信服务器读数据)
InputStream inputStream = uploadConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuffer buffer = new StringBuffer();
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
uploadConn.disconnect(); // 使用JSON-lib解析返回结果
JSONObject jsonObject = JSONObject.fromObject(buffer.toString());
// 测试打印结果
System.out.println("打印测试结果"+jsonObject);
weixinMedia = new WeixinMedia();
weixinMedia.setType(jsonObject.getString("type"));
// type等于 缩略图(thumb) 时的返回结果和其它类型不一样
if ("thumb".equals(type))
weixinMedia.setMediaId(jsonObject.getString("thumb_media_id"));
else
weixinMedia.setMediaId(jsonObject.getString("media_id"));
weixinMedia.setCreatedAt(jsonObject.getInt("created_at"));
} catch (Exception e) {
weixinMedia = null;
String error = String.format("上传媒体文件失败:%s", e);
System.out.println(error);
}
return weixinMedia;
} /**
* 获取媒体文件
* @param accessToken 接口访问凭证
* @param media_id 媒体文件id
* @param savePath 文件在服务器上的存储路径
* */
public static String downloadMedia(String accessToken, String mediaId, String savePath) {
String filePath = null;
// 拼接请求地址
String requestUrl = "https://qyapi.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);
System.out.println(requestUrl);
try {
URL url = new URL(requestUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setRequestMethod("GET"); if (!savePath.endsWith("/")) {
savePath += "/";
}
// 根据内容类型获取扩展名
String fileExt = WeixinUtil.getFileExt(conn.getHeaderField("Content-Type"));
// 将mediaId作为文件名
filePath = savePath + mediaId + fileExt; 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);
System.out.println(info);
} catch (Exception e) {
filePath = null;
String error = String.format("下载媒体文件失败:%s", e);
System.out.println(error);
}
return filePath;
} /**
* 创建临时带参二维码
*
* @param accessToken 接口访问凭证
* @param expireSeconds 二维码有效时间,单位为秒,最大不超过2592000
* @param sceneId 场景ID
* @return WeixinQRCode
*/
public static WeixinQRCode createTemoraryQRCode(String accessToken, int expireSeconds, int sceneId){
WeixinQRCode weixinQRCode = null;
//拼接请求地址
String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";
requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken);
//需要提交的json数据
String jsonMsg = "{\"expire_seconds\": %d, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": %d}}}";
//创建临时带参的二维码
JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg,expireSeconds,sceneId)); if(jsonObject != null){
weixinQRCode = new WeixinQRCode();
weixinQRCode.setTicket(jsonObject.getString("ticket"));
weixinQRCode.setExpireSeconds(jsonObject.getInt("expire_seconds"));
log.info("创建临时带参二维码成功 ticket:{} expire_seconds:{}",weixinQRCode.getTicket(),weixinQRCode.getExpireSeconds());
} return weixinQRCode;
} /**
* 创建永久带参二维码
*
* @param accessToken 接口访问凭证
* @param sceneId 场景ID
* @return WeixinQRCode
*/
public static String createPermanentQRCode(String accessToken, int sceneId){
String ticket = null;
//拼接请求地址
String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN";
requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken);
//需要提交的json数据
String jsonMsg = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": %d}}}";
//创建永久带参的二维码
JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg,sceneId)); if(jsonObject != null){
ticket = jsonObject.getString("ticket");
log.info("创建永久带参二维码成功 ticket:{}",ticket);
} return ticket;
} /**
* 根据ticket换取二维码
*
* @param ticket 二维码ticket
* @param savePath 保存路径
* @return filePath 永久二维码保存路径
*/
public static String getQRCode(String ticket,String savePath){
String filePath = null;
//拼接请求地址
String requestUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
requestUrl = requestUrl.replace("TICKET", WeixinUtil.urlEncodeUTF8(ticket));
try {
URL url = new URL(requestUrl);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setDoInput(true);
conn.setRequestMethod("GET"); if(!savePath.endsWith("/")){
savePath += "/";
} //将ticket作为文件名
filePath = savePath + ticket + ".jpg";
//将微信服务器返回的输入流写入文件
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();
log.info("根据ticket获取永久二维码成功,filePath:{}",filePath);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return filePath;
} /**
* 长链接转短链接
*
* @param accessToken 接口访问凭证
* @param longUrl 长链接
* @return shortUrl
*/
public static String longUrl2shortUrl(String accessToken,String longUrl){
String shortUrl = null;
//拼接请求地址
String requestUrl = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=ACCESS_TOKEN";
requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken);
//需要提交的json数据
String jsonMsg = "{\"action\":\"long2short\",\"long_url\":\"%s\"}";
//创建永久带参的二维码
JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg,longUrl)); if(jsonObject != null){
shortUrl = jsonObject.getString("short_url");
log.info("返回的短链接为 shortUrl:{}",shortUrl);
} return shortUrl;
} public static void main(String[] args){
//获取接口访问凭证
String accessToken = WeixinUtil.getToken(Parameter.appId,Parameter.appSecret).getAccessToken();
System.out.println("accessToken:" + accessToken); //获取关注者列表
UserList weixinUserList = getUserList(accessToken,"");
System.out.println("总关注用户数:" + weixinUserList.getTotal());
System.out.println("本次获取用户数:" + weixinUserList.getCount());
System.out.println("OpenId列表:" + weixinUserList.getOpenIdList().toString());
System.out.println("next_openid" + weixinUserList.getNextOpenId()); UserInfo user = null;
List<String> list = weixinUserList.getOpenIdList();
for(int i = 0; i < list.size(); i++){
//获取用户信息
user = getUserInfo(accessToken,(String)list.get(i));
System.out.println("OpenId:" + user.getOpenId());
System.out.println("关注状态:" + user.getSubscribe());
System.out.println("关注时间:" + (new SimpleDateFormat("yyyy-MM-dd HH:mm-ss").format(new Date(new Long(user.getSubscribeTime())))));
System.out.println("昵称:" + user.getNickname());
System.out.println("性别:" + user.getSex());
System.out.println("国家:" + user.getCountry());
System.out.println("省份:" + user.getProvince());
System.out.println("城市:" + user.getCity());
System.out.println("语言:" + user.getLanguage());
System.out.println("头像:" + user.getHeadImgUrl());
System.out.println("unionid:" + user.getUnionid());
System.out.println("=====================================");
} /**
* 上传多媒体文件
*/
//地址
WeixinMedia weixinMedia = uploadMedia(accessToken, "image", "http://localhost:8080/weixinClient/images/a.jpg");
//media_id
System.out.println("media_id:"+weixinMedia.getMediaId());
//类型
System.out.println("类型:"+weixinMedia.getType());
//时间戳
System.out.println("时间戳:"+weixinMedia.getCreatedAt());
//打印结果
if(null != weixinMedia){
System.out.println("上传成功!");
} /**
* 下载多媒体文件
*/
String savePath = downloadMedia(accessToken, weixinMedia.getMediaId(), "C:/download");
System.out.println("下载成功之后保存在本地的地址为:"+savePath);
}
}
第三步:找到包com.wtz.util,修改类ProcessService.java,可以在这里修改用户扫描带参数的二维码的事件(这里我就不做了)
生成带参数的二维码以及长链接转短链接完成,暂时先做到这
Java微信二次开发(十)的更多相关文章
- Java微信二次开发(一)
准备用Java做一个微信二次开发项目,把流程写在这里吧. 第一天,做微信请求验证 需要导入库:servlet-api.jar 第一步:新建包com.wtz.service,新建类LoginServle ...
- Java微信公众平台开发(十二)--微信用户信息的获取
转自:http://www.cuiyongzhi.com/post/56.html 前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信 ...
- Java微信公众平台开发(十六)--微信网页授权(OAuth2.0授权)获取用户基本信息
转自:http://www.cuiyongzhi.com/post/78.html 好长时间没有写文章了,主要是最近的工作和生活上的事情比较多而且繁琐,其实到现在我依然还是感觉有些迷茫,最后还是决定静 ...
- Java微信公众平台开发(十)--微信用户信息的获取
前面的文章有讲到微信的一系列开发文章,包括token获取.菜单创建等,在这一篇将讲述在微信公众平台开发中如何获取微信用户的信息,在上一篇我们有说道微信用户和微信公众账号之间的联系可以通过Openid关 ...
- Java微信二次开发(五)
消息加密 需要到入库:commons-io-2.4.jar,commons-codec-1.9.jar(在官网的Java微信加密demo下) 第一步:访问https://mp.weixin.qq.co ...
- Java微信公众平台开发(十二)--微信JSSDK的使用
在前面的文章中有介绍到我们在微信web开发过程中常常用到的 [微信JSSDK中Config配置],但是我们在真正的使用中我们不仅仅只是为了配置Config而已,而是要在我们的项目中真正去使用微信JS- ...
- Java微信公众平台开发(十五)--微信JSSDK的使用
转自:http://www.cuiyongzhi.com/post/63.html 在前面的文章中有介绍到我们在微信web开发过程中常常用到的 [微信JSSDK中Config配置] ,但是我们在真正的 ...
- Java微信公众平台开发(十)--微信自定义菜单的创建实现
转自:http://www.cuiyongzhi.com/post/48.html 自定义菜单这个功能在我们普通的编辑模式下是可以直接在后台编辑的,但是一旦我们进入开发模式之后我们的自定义菜单就需要自 ...
- Java微信二次开发(七)
自定义菜单 第一步:新建包com.wtz.menu,新建类Button.java package com.wtz.menu; /** * @author wangtianze QQ:864620012 ...
随机推荐
- Dubbo高级篇4
https://blog.csdn.net/moonpure/article/details/52842115 线程模型 http://dubbo.io/User+Guide-zh.htm 用户指南& ...
- JMS和AMQP的区别
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信 ...
- 2-(基础入门篇)Air202下载开发入门(给Air202下载第一个程序)
http://www.cnblogs.com/yangfengwu/p/8887933.html 资料链接 链接:https://pan.baidu.com/s/1-SRfsKGQ7rZVvFmp1O ...
- C语言中getch()、getche()和getchar()
本文章为转载文章,文档贡献者wdzhangxiang 个人网址:www.baidu.com/p/wdzhangxiang 首先不要忘了,要用getch()必须引入头文件conio.h,以前学C语言的时 ...
- [05] EL表达式
1.概述 EL = Expression Language 表达式语言,用来在JSP中替代<%=%>的数据表达方式,EL更简洁,它的语法如下: ${...} 1 1 ${...} ...
- Luogu P2279 [HNOI2003]消防局的设立
这真的是一道SB题.去你的树形DP 我们看到题目就开始考虑贪心,怎么搞? 一个显然的思路,每次找出一个深度最大且未被覆盖的点,然后建一个消防局? 但这样的话,动用简单的人类思维就可以知道:我TM的还不 ...
- [Oracle]Oracle Fail Safe 与 SQLNET.AUTHENTICATION_SERVICES关系
现象: 在使用 OFS (Oracle Fail Safe)的环境中,把数据库的 SQLNET.AUTHENTICATION_SERVICES 从 NTS 改为 NONE之后,当从 Oracle Fa ...
- [数据可视化之一]Pandas单变量画图
Pandas单变量画图 Bar Chat Line Chart Area Chart Histogram df.plot.bar() df.plot.line() df.plot.area() df. ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(八)线上Mysql数据库崩溃事故的原因和处理
前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...
- Azure Load Balancer : 支持 IPv6
越来越多的网站开始支持 IPv6,即使是哪些只提供 api 服务的站点也需要支持 IPv6,比如苹果应用商店中的 app 早就强制要求服务器端支持 IPv6 了.笔者在前文<Azure Load ...