生成带参数的二维码以及长链接转短链接
第一步:找到包com.wtz.vo,新建类WeixinQRCode.java
1 package com.wtz.vo; 2 3 /** 4 * @author wangtianze QQ:864620012 5 * @date 2017年4月25日 下午3:01:57 6 * <p>version:1.0</p> 7 * <p>description:临时二维码信息</p> 8 */ 9 public class WeixinQRCode { 10 //获取的二维码ticket 11 private String ticket; 12 //二维码的有效时间,单位为秒,最大不超过2592000 13 private int expireSeconds; 14 15 public String getTicket() { 16 return ticket; 17 } 18 public void setTicket(String ticket) { 19 this.ticket = ticket; 20 } 21 public int getExpireSeconds() { 22 return expireSeconds; 23 } 24 public void setExpireSeconds(int expireSeconds) { 25 this.expireSeconds = expireSeconds; 26 } 27 }
第二步:找到包com.wtz.util,修改类AdvancedUtil.java
1 package com.wtz.util; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedReader; 5 import java.io.File; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.io.InputStreamReader; 10 import java.io.OutputStream; 11 import java.net.HttpURLConnection; 12 import java.net.MalformedURLException; 13 import java.net.URL; 14 import java.text.SimpleDateFormat; 15 import java.util.Date; 16 import java.util.List; 17 18 import javax.net.ssl.HttpsURLConnection; 19 20 import net.sf.json.JSONArray; 21 import net.sf.json.JSONObject; 22 23 import org.slf4j.Logger; 24 import org.slf4j.LoggerFactory; 25 26 import com.wtz.vo.UserInfo; 27 import com.wtz.vo.UserList; 28 import com.wtz.vo.WeixinMedia; 29 import com.wtz.vo.WeixinQRCode; 30 31 /** 32 * @author wangtianze QQ:864620012 33 * @date 2017年4月24日 下午7:36:03 34 * <p>version:1.0</p> 35 * <p>description:高级接口工具类</p> 36 */ 37 public class AdvancedUtil { 38 private static Logger log = LoggerFactory.getLogger(AdvancedUtil.class); 39 40 /** 41 * 获取用户信息 42 * 43 * @param accessToken 接口访问凭证 44 * @param openId 用户凭证 45 * @return WeixinUserInfo 46 */ 47 public static UserInfo getUserInfo(String accessToken,String openId){ 48 UserInfo weixinUserInfo = null; 49 //拼接请求地址 50 String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID"; 51 requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken).replace("OPENID",openId); 52 //获取用户信息 53 JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "GET", null); 54 55 if(null != jsonObject){ 56 try{ 57 weixinUserInfo = new UserInfo(); 58 59 //用户的标识 60 weixinUserInfo.setOpenId(jsonObject.getString("openid")); 61 62 //关注状态(1是关注,0是未关注),未关注时获取不到其余信息 63 weixinUserInfo.setSubscribe(jsonObject.getInt("subscribe")); 64 65 //用户关注时间 66 weixinUserInfo.setSubscribeTime(jsonObject.getString("subscribe_time")); 67 68 //昵称 69 weixinUserInfo.setNickname(jsonObject.getString("nickname")); 70 71 //用户的性别(1是男性,2是女性,0是未知) 72 weixinUserInfo.setSex(jsonObject.getInt("sex")); 73 74 //用户所在的国家 75 weixinUserInfo.setCountry(jsonObject.getString("country")); 76 77 //用户所在的省份 78 weixinUserInfo.setProvince(jsonObject.getString("province")); 79 80 //用户所在的城市 81 weixinUserInfo.setCity(jsonObject.getString("city")); 82 83 //用户的语言,简体中文为zh_CN 84 weixinUserInfo.setLanguage(jsonObject.getString("language")); 85 86 //用户头像 87 weixinUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl")); 88 89 //uninonid 90 weixinUserInfo.setUnionid(jsonObject.getString("unionid")); 91 }catch(Exception e){ 92 if(0 == weixinUserInfo.getSubscribe()){ 93 log.error("用户{}已取消关注",weixinUserInfo.getOpenId()); 94 }else{ 95 int errorCode = jsonObject.getInt("errcode"); 96 String errorMsg = jsonObject.getString("errmsg"); 97 log.error("获取用户信息失败 errorcode:{} errormsg:{}",errorCode,errorMsg); 98 } 99 } 100 } 101 return weixinUserInfo; 102 } 103 104 /** 105 * 获取关注者列表 106 * 107 * @param accessToken 调用接口凭证 108 * @param nextOpenId 第一个拉取nextOpenId,不填默认从头开始拉取 109 * @return WeixinUserList 110 */ 111 @SuppressWarnings({ "deprecation", "unchecked" }) 112 public static UserList getUserList(String accessToken,String nextOpenId){ 113 UserList weixinUserList = null; 114 if(null == nextOpenId){ 115 nextOpenId = ""; 116 } 117 //拼接请求地址 118 String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID"; 119 120 requestUrl.replace("ACCESS_TOKEN", accessToken).replace("NEXT_OPENID",nextOpenId); 121 122 //获取关注者列表 123 JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "GET", null); 124 125 //如果请求成功 126 if(null != jsonObject){ 127 weixinUserList = new UserList(); 128 weixinUserList.setTotal(jsonObject.getInt("total")); 129 weixinUserList.setCount(jsonObject.getInt("count")); 130 weixinUserList.setNextOpenId(jsonObject.getString("next_openid")); 131 JSONObject dataObject = (JSONObject)jsonObject.get("data"); 132 weixinUserList.setOpenIdList(JSONArray.toList(dataObject.getJSONArray("openid"),List.class)); 133 } 134 135 return weixinUserList; 136 } 137 138 /** 139 * 上传媒体文件 140 * @param accessToken 接口访问凭证 141 * @param type 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file) 142 * @param media form-data中媒体文件标识,有filename、filelength、content-type等信息 143 * @param mediaFileUrl 媒体文件的url 144 * 上传的媒体文件限制 145 * 图片(image):1MB,支持JPG格式 146 * 语音(voice):2MB,播放长度不超过60s,支持AMR格式 147 * 视频(video):10MB,支持MP4格式 148 * 普通文件(file):10MB 149 * */ 150 public static WeixinMedia uploadMedia(String accessToken, String type, String mediaFileUrl) { 151 WeixinMedia weixinMedia = null; 152 // 拼装请求地址 153 String uploadMediaUrl = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"; 154 uploadMediaUrl = uploadMediaUrl.replace("ACCESS_TOKEN", accessToken).replace("TYPE", type); 155 156 // 定义数据分隔符 157 String boundary = "------------7da2e536604c8"; 158 try { 159 URL uploadUrl = new URL(uploadMediaUrl); 160 HttpURLConnection uploadConn = (HttpURLConnection) uploadUrl.openConnection(); 161 uploadConn.setDoOutput(true); 162 uploadConn.setDoInput(true); 163 uploadConn.setRequestMethod("POST"); 164 // 设置请求头Content-Type 165 uploadConn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); 166 // 获取媒体文件上传的输出流(往微信服务器写数据) 167 OutputStream outputStream = uploadConn.getOutputStream(); 168 169 URL mediaUrl = new URL(mediaFileUrl); 170 HttpURLConnection meidaConn = (HttpURLConnection) mediaUrl.openConnection(); 171 meidaConn.setDoOutput(true); 172 meidaConn.setRequestMethod("GET"); 173 174 // 从请求头中获取内容类型 175 String contentType = meidaConn.getHeaderField("Content-Type"); 176 // 根据内容类型判断文件扩展名 177 String fileExt = WeixinUtil.getFileExt(contentType); 178 // 请求体开始 179 outputStream.write(("--" + boundary + " ").getBytes()); 180 outputStream.write(String.format("Content-Disposition: form-data; name="media"; filename="file1%s" ", fileExt).getBytes()); 181 outputStream.write(String.format("Content-Type: %s ", contentType).getBytes()); 182 183 // 获取媒体文件的输入流(读取文件) 184 BufferedInputStream bis = new BufferedInputStream(meidaConn.getInputStream()); 185 byte[] buf = new byte[8096]; 186 int size = 0; 187 while ((size = bis.read(buf)) != -1) { 188 // 将媒体文件写到输出流(往微信服务器写数据) 189 outputStream.write(buf, 0, size); 190 } 191 // 请求体结束 192 outputStream.write((" --" + boundary + "-- ").getBytes()); 193 outputStream.close(); 194 bis.close(); 195 meidaConn.disconnect(); 196 197 // 获取媒体文件上传的输入流(从微信服务器读数据) 198 InputStream inputStream = uploadConn.getInputStream(); 199 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); 200 BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 201 StringBuffer buffer = new StringBuffer(); 202 String str = null; 203 while ((str = bufferedReader.readLine()) != null) { 204 buffer.append(str); 205 } 206 bufferedReader.close(); 207 inputStreamReader.close(); 208 // 释放资源 209 inputStream.close(); 210 inputStream = null; 211 uploadConn.disconnect(); 212 213 // 使用JSON-lib解析返回结果 214 JSONObject jsonObject = JSONObject.fromObject(buffer.toString()); 215 // 测试打印结果 216 System.out.println("打印测试结果"+jsonObject); 217 weixinMedia = new WeixinMedia(); 218 weixinMedia.setType(jsonObject.getString("type")); 219 // type等于 缩略图(thumb) 时的返回结果和其它类型不一样 220 if ("thumb".equals(type)) 221 weixinMedia.setMediaId(jsonObject.getString("thumb_media_id")); 222 else 223 weixinMedia.setMediaId(jsonObject.getString("media_id")); 224 weixinMedia.setCreatedAt(jsonObject.getInt("created_at")); 225 } catch (Exception e) { 226 weixinMedia = null; 227 String error = String.format("上传媒体文件失败:%s", e); 228 System.out.println(error); 229 } 230 return weixinMedia; 231 } 232 233 /** 234 * 获取媒体文件 235 * @param accessToken 接口访问凭证 236 * @param media_id 媒体文件id 237 * @param savePath 文件在服务器上的存储路径 238 * */ 239 public static String downloadMedia(String accessToken, String mediaId, String savePath) { 240 String filePath = null; 241 // 拼接请求地址 242 String requestUrl = "https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID"; 243 requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("MEDIA_ID", mediaId); 244 System.out.println(requestUrl); 245 try { 246 URL url = new URL(requestUrl); 247 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 248 conn.setDoInput(true); 249 conn.setRequestMethod("GET"); 250 251 if (!savePath.endsWith("/")) { 252 savePath += "/"; 253 } 254 // 根据内容类型获取扩展名 255 String fileExt = WeixinUtil.getFileExt(conn.getHeaderField("Content-Type")); 256 // 将mediaId作为文件名 257 filePath = savePath + mediaId + fileExt; 258 259 BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); 260 FileOutputStream fos = new FileOutputStream(new File(filePath)); 261 byte[] buf = new byte[8096]; 262 int size = 0; 263 while ((size = bis.read(buf)) != -1){ 264 fos.write(buf, 0, size); 265 } 266 fos.close(); 267 bis.close(); 268 269 conn.disconnect(); 270 String info = String.format("下载媒体文件成功,filePath=" + filePath); 271 System.out.println(info); 272 } catch (Exception e) { 273 filePath = null; 274 String error = String.format("下载媒体文件失败:%s", e); 275 System.out.println(error); 276 } 277 return filePath; 278 } 279 280 /** 281 * 创建临时带参二维码 282 * 283 * @param accessToken 接口访问凭证 284 * @param expireSeconds 二维码有效时间,单位为秒,最大不超过2592000 285 * @param sceneId 场景ID 286 * @return WeixinQRCode 287 */ 288 public static WeixinQRCode createTemoraryQRCode(String accessToken, int expireSeconds, int sceneId){ 289 WeixinQRCode weixinQRCode = null; 290 //拼接请求地址 291 String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; 292 requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken); 293 //需要提交的json数据 294 String jsonMsg = "{"expire_seconds": %d, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": %d}}}"; 295 //创建临时带参的二维码 296 JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg,expireSeconds,sceneId)); 297 298 if(jsonObject != null){ 299 weixinQRCode = new WeixinQRCode(); 300 weixinQRCode.setTicket(jsonObject.getString("ticket")); 301 weixinQRCode.setExpireSeconds(jsonObject.getInt("expire_seconds")); 302 log.info("创建临时带参二维码成功 ticket:{} expire_seconds:{}",weixinQRCode.getTicket(),weixinQRCode.getExpireSeconds()); 303 } 304 305 return weixinQRCode; 306 } 307 308 /** 309 * 创建永久带参二维码 310 * 311 * @param accessToken 接口访问凭证 312 * @param sceneId 场景ID 313 * @return WeixinQRCode 314 */ 315 public static String createPermanentQRCode(String accessToken, int sceneId){ 316 String ticket = null; 317 //拼接请求地址 318 String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; 319 requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken); 320 //需要提交的json数据 321 String jsonMsg = "{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": %d}}}"; 322 //创建永久带参的二维码 323 JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg,sceneId)); 324 325 if(jsonObject != null){ 326 ticket = jsonObject.getString("ticket"); 327 log.info("创建永久带参二维码成功 ticket:{}",ticket); 328 } 329 330 return ticket; 331 } 332 333 /** 334 * 根据ticket换取二维码 335 * 336 * @param ticket 二维码ticket 337 * @param savePath 保存路径 338 * @return filePath 永久二维码保存路径 339 */ 340 public static String getQRCode(String ticket,String savePath){ 341 String filePath = null; 342 //拼接请求地址 343 String requestUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET"; 344 requestUrl = requestUrl.replace("TICKET", WeixinUtil.urlEncodeUTF8(ticket)); 345 try { 346 URL url = new URL(requestUrl); 347 HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); 348 conn.setDoInput(true); 349 conn.setRequestMethod("GET"); 350 351 if(!savePath.endsWith("/")){ 352 savePath += "/"; 353 } 354 355 //将ticket作为文件名 356 filePath = savePath + ticket + ".jpg"; 357 //将微信服务器返回的输入流写入文件 358 BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); 359 FileOutputStream fos = new FileOutputStream(new File(filePath)); 360 361 byte[] buf = new byte[8096]; 362 int size = 0; 363 364 while((size = bis.read(buf)) != -1){ 365 fos.write(buf,0,size); 366 } 367 368 fos.close(); 369 bis.close(); 370 371 conn.disconnect(); 372 log.info("根据ticket获取永久二维码成功,filePath:{}",filePath); 373 } catch (MalformedURLException e) { 374 // TODO Auto-generated catch block 375 e.printStackTrace(); 376 } catch (IOException e) { 377 // TODO Auto-generated catch block 378 e.printStackTrace(); 379 } 380 381 return filePath; 382 } 383 384 /** 385 * 长链接转短链接 386 * 387 * @param accessToken 接口访问凭证 388 * @param longUrl 长链接 389 * @return shortUrl 390 */ 391 public static String longUrl2shortUrl(String accessToken,String longUrl){ 392 String shortUrl = null; 393 //拼接请求地址 394 String requestUrl = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=ACCESS_TOKEN"; 395 requestUrl = requestUrl.replace("ACCESS_TOKEN",accessToken); 396 //需要提交的json数据 397 String jsonMsg = "{"action":"long2short","long_url":"%s"}"; 398 //创建永久带参的二维码 399 JSONObject jsonObject = WeixinUtil.httpsRequest(requestUrl, "POST", String.format(jsonMsg,longUrl)); 400 401 if(jsonObject != null){ 402 shortUrl = jsonObject.getString("short_url"); 403 log.info("返回的短链接为 shortUrl:{}",shortUrl); 404 } 405 406 return shortUrl; 407 } 408 409 public static void main(String[] args){ 410 //获取接口访问凭证 411 String accessToken = WeixinUtil.getToken(Parameter.appId,Parameter.appSecret).getAccessToken(); 412 System.out.println("accessToken:" + accessToken); 413 414 //获取关注者列表 415 UserList weixinUserList = getUserList(accessToken,""); 416 System.out.println("总关注用户数:" + weixinUserList.getTotal()); 417 System.out.println("本次获取用户数:" + weixinUserList.getCount()); 418 System.out.println("OpenId列表:" + weixinUserList.getOpenIdList().toString()); 419 System.out.println("next_openid" + weixinUserList.getNextOpenId()); 420 421 UserInfo user = null; 422 List<String> list = weixinUserList.getOpenIdList(); 423 for(int i = 0; i < list.size(); i++){ 424 //获取用户信息 425 user = getUserInfo(accessToken,(String)list.get(i)); 426 System.out.println("OpenId:" + user.getOpenId()); 427 System.out.println("关注状态:" + user.getSubscribe()); 428 System.out.println("关注时间:" + (new SimpleDateFormat("yyyy-MM-dd HH:mm-ss").format(new Date(new Long(user.getSubscribeTime()))))); 429 System.out.println("昵称:" + user.getNickname()); 430 System.out.println("性别:" + user.getSex()); 431 System.out.println("国家:" + user.getCountry()); 432 System.out.println("省份:" + user.getProvince()); 433 System.out.println("城市:" + user.getCity()); 434 System.out.println("语言:" + user.getLanguage()); 435 System.out.println("头像:" + user.getHeadImgUrl()); 436 System.out.println("unionid:" + user.getUnionid()); 437 System.out.println("====================================="); 438 } 439 440 /** 441 * 上传多媒体文件 442 */ 443 //地址 444 WeixinMedia weixinMedia = uploadMedia(accessToken, "image", "http://localhost:8080/weixinClient/images/a.jpg"); 445 //media_id 446 System.out.println("media_id:"+weixinMedia.getMediaId()); 447 //类型 448 System.out.println("类型:"+weixinMedia.getType()); 449 //时间戳 450 System.out.println("时间戳:"+weixinMedia.getCreatedAt()); 451 //打印结果 452 if(null != weixinMedia){ 453 System.out.println("上传成功!"); 454 } 455 456 /** 457 * 下载多媒体文件 458 */ 459 String savePath = downloadMedia(accessToken, weixinMedia.getMediaId(), "C:/download"); 460 System.out.println("下载成功之后保存在本地的地址为:"+savePath); 461 } 462 }
第三步:找到包com.wtz.util,修改类ProcessService.java,可以在这里修改用户扫描带参数的二维码的事件(这里我就不做了)
生成带参数的二维码以及长链接转短链接完成,暂时先做到这