使用jfinal框架
WechatController
package com.se.activities.module;
import com.jfinal.upload.UploadFile;
import com.se.BasicController;
import com.se.activities.model.BWeixinUserinfo;
import com.se.activities.model.WechatToken;
import com.se.activities.utils.*;
import com.se.config.EnumConst;
import com.se.ext.plugin.route.ControllerBind;
import com.se.sdk.oauth.util.HttpKit;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* Created by on 2017/2/24.
* jdk 1.8
*/
@ControllerBind(controllerKey = "/weChat")
public class WechatController extends BasicController {
private final static Logger logger = LoggerFactory.getLogger(WechatController.class);//日志
private String index_child = WechatConfig.getIndex_child();//项目域名
private String getCode = WechatConfig.getGetCode();//用户同意授权,获取code
private String appId = WechatConfig.getAppId();//公众号的唯一标识
private String getAccessToken = WechatConfig.getGetAccessToken();//用户凭证
private String appSecret = WechatConfig.getAppSecret();//公众号的appsecret
private String checkAccessToken = WechatConfig.getCheckAccessToken();//校验用户凭证
private String updateAccessToken = WechatConfig.getUpdateAccessToken();//更新用户凭证
private String getUserInfo = WechatConfig.getGetUserInfo();//获取用户详细信息
/**
* 接口:
* /weChat/list 参数goUrl 最后跳转的控制器 携带session:getSessionAttr("weChatUserInfo").toString();
* <p/>
* 例如:
* 请求 xxxxx/weChat/list?goUrl=xxxxx/admin/admin
* 最后客户端跳转: /admin/admin 控制器 携带session:getSessionAttr("weChatUserInfo").toString();
* 默认:
* 请求 xxxx/weChat/list
* 最后客户端跳转: /weChat/showUserInfo 携带session:getSessionAttr("weChatUserInfo").toString();
*/
//入口 获取 code 两个类型 snsapi_base 和 snsapi_userinfo
public void list() {
String scope = getPara("scope", "snsapi_base");//snsapi_base 默认取openid
String redirect_uri = getPara("redirect_uri", "0");//转转向控制器
String goUrl = getPara("goUrl", "0");//最后带用户信息存在session 转向的控制器
try {
if (redirect_uri.equals("0")) redirect_uri = index_child + "/weChat/openId?scope=" + scope;
if (!goUrl.equals("0")) redirect_uri = redirect_uri + "&goUrl=" + goUrl;
redirect_uri = URLEncoder.encode(redirect_uri, "UTF-8");
// System.out.println(redirect_uri);
String url = getCode.replace("APPID", appId).replace("REDIRECT_URI", redirect_uri)
.replace("SCOPE", scope).replace("STATE", CharacterUtils.getRandomString(6));
redirect(url);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
//微信回调接口 业务转向 取openid,access_token,refresh_token
public void openId() {
String scope = getPara("scope");
String goUrl = getPara("goUrl");//资源转向
String code = getPara("code", "0");
if (!code.equals("0")) {
String url = getAccessToken.replace("APPID", appId).replace("SECRET", appSecret)
.replace("CODE", code);
String res = HttpKit.get(url);
System.out.println("scope:" + scope + ">>>>>>");
System.out.println(res);
System.out.println("scope:" + scope + "<<<<<<<");
try {
JSONObject jsonObject = new JSONObject();
jsonObject = new JSONObject(res);
if (scope.equals("snsapi_base")) {//基础信息
getOrUpdateInfo(jsonObject.getString("openid"), 1, jsonObject, goUrl);
}
if (scope.equals("snsapi_userinfo")) {//获取信息
getOrUpdateInfo(jsonObject.getString("openid"), 2, jsonObject, goUrl);
}
} catch (JSONException e) {
// e.printStackTrace();
logger.error("转换jsonObject有错,或者不在参数", e);
}
} else {
System.out.println("");
logger.error("code不存在");
redirect(index_child + "/weChat/list");//重新拉取
}
}
/**
* 取用户信息或者更新用户信息
*
* @param openId 微信用户号凭证
* @param type 1是snsapi_base 2是snsapi_userinfo
* @param res 资源
* @param goUrl 资源转向
*/
private void getOrUpdateInfo(String openId, int type, JSONObject res, String goUrl) {
WechatToken wechatToken = WechatToken.dao.findById(openId);
String redirect_uri = index_child + "/weChat/list?scope=snsapi_userinfo";
String access_token = null;
String refresh_token = null;
String scope = null;
String expires_in = null;
try {
access_token = res.getString("access_token");//网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
refresh_token = res.getString("refresh_token");//用户刷新access_token
scope = res.getString("scope");//用户授权的作用域
expires_in = res.getInt("expires_in") + "";// access_token接口调用凭证超时时间,单位(秒)
} catch (JSONException e) {
e.printStackTrace();
}
if (type == 1) {
// logger.info("getOrUpdateInfo", res);
if (wechatToken == null) {//没有openId
wechatToken = new WechatToken();
wechatToken.set("id", openId).save();
redirect(redirect_uri);
} else {
checkToken(openId, access_token, refresh_token, goUrl);
}
} else {//存在
wechatToken.set("access_token", access_token)
.set("refresh_token", refresh_token)
.set("scope", scope)
.set("expires_in", expires_in).update();
checkToken(openId, access_token, refresh_token, goUrl);
}
}
/**
* 检查凭证是否有效 无效更新 页授权接口调用凭证
*
* @param openId 微信用户号凭证
* @param access_token 网页授权接口调用凭证
* @param refresh_token 用户刷新access_token 凭证
* @param goUrl 资源转向
*/
private void checkToken(String openId, String access_token, String refresh_token, String goUrl) {
String ACCESS_TOKEN = access_token;
String url = checkAccessToken.replace("OPENID", openId).replace("ACCESS_TOKEN", ACCESS_TOKEN);
String res = HttpKit.get(url);
String errmsg = "errmsg";
// logger.info("checkAccessToken", res);
try {
JSONObject jsonObject = new JSONObject(res);
errmsg = jsonObject.getString("errmsg");
} catch (JSONException e) {
// e.printStackTrace();
logger.error("转换jsonObject有错,或者不在参数", e);
}
if (!errmsg.equals("ok")) {//ACCESS_TOKEN无效
url = updateAccessToken.replace("APPID", appId).replace("REFRESH_TOKEN", refresh_token);
res = HttpKit.get(url);
System.out.println("==========updateAccessToken==========");
System.out.println(res);
System.out.println("==========updateAccessToken==========");
String scope = null;
String expires_in = null;
try {
JSONObject jsonObject = new JSONObject(res);
if (jsonObject.get("openid") == null) {
redirect(index_child + "/weChat/list?scope=snsapi_userinfo");
}
ACCESS_TOKEN = jsonObject.getString("access_token");
refresh_token = jsonObject.getString("refresh_token");
scope = jsonObject.getString("scope");
expires_in = jsonObject.getInt("expires_in") + "";
} catch (JSONException e) {
logger.error("转换jsonObject有错,或者不在参数", e);
}
//存表
WechatToken wechatToken = WechatToken.dao.findById(openId);
wechatToken.set("access_token", ACCESS_TOKEN)
.set("refresh_token", refresh_token)
.set("scope", scope)
.set("expires_in", expires_in).update();
}
getUserInfo(openId, ACCESS_TOKEN, goUrl);
}
/**
* 资源转向 并设置setSessionAttr("weChatUserInfo", res);
*
* @param openId 微信用户号凭证
* @param access_token 网页授权接口调用凭证
* @param goUrl 资源转向
*/
private void getUserInfo(String openId, String access_token, String goUrl) {
String url = getUserInfo.replace("OPENID", openId).replace("ACCESS_TOKEN", access_token);
String res = HttpKit.get(url);
// logger.info("getUserInfo资源", res);
setSessionAttr("weChatUserInfo", res);
if (goUrl == null) redirect(index_child + "/weChat/showUserInfo");//指向用户信息控制器
else redirect(goUrl);
}
/**
* 保存信息
*/
private WeChatUserInfo saveWeChatUserInfo() {
String res = getSessionAttr("weChatUserInfo").toString();
System.out.println("-------->getUserInfo<-------");
System.out.println(res);
System.out.println("------->>getUserInfo<<------");
String openid = "0";
String province = null;
String city = null;
String headimgurl = null;
int sex = 0;
String nickname = null;
try {
JSONObject jsonObject = new JSONObject(res);
openid = jsonObject.getString("openid");
province = jsonObject.getString("province");
city = jsonObject.getString("city");
headimgurl = jsonObject.getString("headimgurl");
sex = jsonObject.getInt("sex");
nickname = jsonObject.getString("nickname");
} catch (JSONException e) {
e.printStackTrace();
}
//更新微信用户信息
BWeixinUserinfo bWeixinUserinfo = BWeixinUserinfo.dao.getByOpenId(openid);
boolean isUpdate = bWeixinUserinfo == null ? false : true;
bWeixinUserinfo = bWeixinUserinfo == null ? new BWeixinUserinfo() : bWeixinUserinfo;
bWeixinUserinfo.set("location", province + "," + city)
.set("openid", openid)
.set("sex", sex)
.set("headimgurl", headimgurl)
.set("nickname", nickname);
if (isUpdate) {
bWeixinUserinfo.update();
} else {
bWeixinUserinfo.save();
}
//更新头像在本地资源
Integer id = bWeixinUserinfo.getInt("id");
UpdateHeadImgThread updateHeadImgThread = new UpdateHeadImgThread();
updateHeadImgThread.setId(id);
updateHeadImgThread.setHeaderHeadImgUrl(headimgurl);
new Thread(updateHeadImgThread).start();
WeChatUserInfo weChatUserInfo = new WeChatUserInfo();
weChatUserInfo.setCity(city);
weChatUserInfo.setHeadImgurl(headimgurl);
weChatUserInfo.setNickname(nickname);
weChatUserInfo.setOpenId(openid);
weChatUserInfo.setProvince(province);
weChatUserInfo.setSex(sex);
return weChatUserInfo;
}
/**
* 用户信息
*
* @weChatUserInfo getSessionAttr("weChatUserInfo").toString()
*/
public void showUserInfo() {
if (getSessionAttr("weChatUserInfo") != null) {
WeChatUserInfo weChatUserInfo = saveWeChatUserInfo();
} else {
redirect(index_child + "/weChat/list");
}
}
//图片上传 '1:image 2:voice 3:video 4:file 5:flash 6:media'
public void uploadPic() {
int type = getParaToInt("type", 1);
String picUrl = "";
UploadFile file = getFile();
Map<String, Object> map = new HashMap<>();
int code = EnumConst.RetCode.ERROR.getCode();
String msg = EnumConst.RetCode.ERROR.getValue();
if (file != null) {
picUrl = new DownloadFile().getByFile(file, type);
code = EnumConst.RetCode.SUCCESS.getCode();
msg = EnumConst.RetCode.SUCCESS.getValue();
map.put("error", 0);
} else {
map.put("message", "上传失败");
map.put("error", 1);
}
map.put("imgUrl", picUrl);
map.put("code", code);
map.put("msg", msg);
map.put("url", index_child+picUrl);
renderJson(map);
}
}
DownloadFile类
public class DownloadFile {
public static String weChatHeadPicDir = 物理路径;
public static String activitiesPicDir = 物理路径;
/**
* @param u 地址
* @param fileName 文件名称
* @param type '1:image 2:voice 3:video 4:file 5:flash 6:media'
* @return
*/
public String fromNet(String u, String fileName, int type) {
int byteSum = 0;
int byteRead = 0;
String returnUrl = "";
try {
URL url = new URL(u);
URLConnection conn = url.openConnection();
InputStream inStream = conn.getInputStream();
String filePath = weChatHeadPicDir + File.separatorChar + fileName + ".jpg";
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
FileOutputStream fs = new FileOutputStream(filePath);
byte[] buffer = new byte[1204];
while ((byteRead = inStream.read(buffer)) != -1) {
byteSum += byteRead;
fs.write(buffer, 0, byteRead);
}
BMedia media = new BMedia();
media.setPath(filePath).setType(type);
if (media.saveMedia() != null) {//保存到
returnUrl = PropertyUtil.getGrosseValue(PropertyUtil.SSO, "INDEX_CHILD").trim()
+ "/wx/web/showPic/" + media.getId();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return returnUrl;
}
}
WeChatUserInfo
public class WeChatUserInfo {
private String openId;
private String province;
private String city;
private String headImgurl;
private String nickname;
private int sex;
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getHeadImgurl() {
return headImgurl;
}
public void setHeadImgurl(String headImgurl) {
this.headImgurl = headImgurl;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
WechatConfig
public class WechatConfig {
/**
* 开发文档
* https://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html
*/
private static String appId = "xxxxx";// 公众号的唯一标识
private static String appSecret = "xxxxx";//公众号的appsecret
private static String index_child = PropertyUtil.getGrosseValue(PropertyUtil.SSO, "INDEX_CHILD").trim();//域名
private static String getCode = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";//用户同意授权,获取code 两个类型:snsapi_base和snsapi_userinfo
private static String getAccessToken = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";//通过code换取网页授权access_token
private static String updateAccessToken = "https://api.weixin.qq.com/sns/oauth2/refresh_token?" +
"appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";//由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token拥有较长的有效期(7天、30天、60天、90天),当refresh_token失效的后,需要用户重新授权。
private static String getUserInfo = "https://api.weixin.qq.com/sns/userinfo?" +
"access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";//拉取用户信息(需scope为 snsapi_userinfo)
private static String checkAccessToken = "https://api.weixin.qq.com/sns/auth?" +
"access_token=ACCESS_TOKEN&openid=OPENID";//检验授权凭证(access_token)是否有效
public static String getAppId() {
return appId;
}
public static void setAppId(String appId) {
WechatConfig.appId = appId;
}
public static String getAppSecret() {
return appSecret;
}
public static void setAppSecret(String appSecret) {
WechatConfig.appSecret = appSecret;
}
public static String getIndex_child() {
return index_child;
}
public static void setIndex_child(String index_child) {
WechatConfig.index_child = index_child;
}
public static String getGetCode() {
return getCode;
}
public static void setGetCode(String getCode) {
WechatConfig.getCode = getCode;
}
public static String getGetAccessToken() {
return getAccessToken;
}
public static void setGetAccessToken(String getAccessToken) {
WechatConfig.getAccessToken = getAccessToken;
}
public static String getUpdateAccessToken() {
return updateAccessToken;
}
public static void setUpdateAccessToken(String updateAccessToken) {
WechatConfig.updateAccessToken = updateAccessToken;
}
public static String getGetUserInfo() {
return getUserInfo;
}
public static void setGetUserInfo(String getUserInfo) {
WechatConfig.getUserInfo = getUserInfo;
}
public static String getCheckAccessToken() {
return checkAccessToken;
}
public static void setCheckAccessToken(String checkAccessToken) {
WechatConfig.checkAccessToken = checkAccessToken;
}
}
CharacterUtils
package com.se.activities.utils;
import java.util.Random;
/**
* Created by on 2017/2/25.
* jdk 1.8
*/
public class CharacterUtils {
public static String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; ++i) {
int number = random.nextInt(62);//[0,62)
sb.append(str.charAt(number));
}
return sb.toString();
}
public static String getRandomString2(int length) {
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; ++i) {
int number = random.nextInt(3);
long result = 0;
switch (number) {
case 0:
result = Math.round(Math.random() * 25 + 65);
sb.append(String.valueOf((char) result));
break;
case 1:
result = Math.round(Math.random() * 25 + 97);
sb.append(String.valueOf((char) result));
break;
case 2:
sb.append(String.valueOf(new Random().nextInt(10)));
break;
}
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(getRandomString(10));
System.out.println(getRandomString2(10));
}
}
UpdateHeadImgThread
public class UpdateHeadImgThread implements Runnable {
private int id ;
private String headerHeadImgUrl;
private String openId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getHeaderHeadImgUrl() {
return headerHeadImgUrl;
}
public void setHeaderHeadImgUrl(String headerHeadImgUrl) {
this.headerHeadImgUrl = headerHeadImgUrl;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
@Override
public void run() {
BWeixinUserinfo bWeixinUserinfo = BWeixinUserinfo.dao.findById(id);
if(bWeixinUserinfo!=null) {
DownloadFile downloadFile =new DownloadFile();
String picUrl = downloadFile.fromNet(headerHeadImgUrl,openId,1);//'1:image 2:voice 3:video 4:file 5:flash 6:media'
bWeixinUserinfo.set("headimgurl",picUrl).update();
}
}
}