微信绑定用户服务端代码-根据code获取openId然后绑定用户
目录结构:
isa.qa.core.weixin.message.resp包和isa.qa.core.weixin.util包中为微信绑定的工具类,就不一一贴出代码,详见附件,下载地址:
http://files.cnblogs.com/files/007sx/weixin_util.zip
jar包(包括了微信支付所需jar此处一起列出) pom.xml
<!-- weixin -->
<dependency>
<groupId>com.ning</groupId>
<artifactId>async-http-client</artifactId>
<version>1.8.13</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>com.gson</groupId>
<artifactId>wechat</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.14.4</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.7</version>
</dependency>
注意com.gson wechat 1.0.8 maven中央仓库没有,需要自己导入本地仓库使用,wechat-1.0.8.jar下载地址:
http://files.cnblogs.com/files/007sx/wechat-1.0.8.zip
WeixinResource.java-连接微信服务器代码接口:
package isa.qa.frame.controller; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import isa.qa.frame.dao.UserDao;
import isa.qa.frame.model.User;
import isa.qa.frame.wechat.message.resp.TextMessage;
import isa.qa.frame.wechat.util.MessageUtil;
import isa.qa.frame.wechat.util.WeixinToken;
import net.sf.json.JSONObject; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import com.gson.util.SHA1; /**
* REST controller for managing WorkOrder.
*/
@Controller
@RequestMapping("/api/wechat")
public class WeixinResource {
@Autowired
private UserDao userDao; private final Logger log = LoggerFactory.getLogger(this.getClass()); // @Resource(name = "memberServiceImpl")
// public MemberService memberService; private static Map<String,String> TIME_OPENID_MAP = new HashMap<String,String>(); /**
* POST /menus -> Create weixin menus.
*/ //http://localhost:8080/api/wechat/gateway?signature=123432×tamp=12343&nonce=1234&echostr=1223434
@RequestMapping(value = "/gateway",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String weChatValidate(HttpServletRequest request,HttpServletResponse response) throws Exception {
System.out.println("enter weChatValidate!");
String _token = "mylng";
String outPut = "error";
String signature = request.getParameter("signature");// 微信加密签名
String timestamp = request.getParameter("timestamp");// 时间戳
TIME_OPENID_MAP.put(timestamp, "");
String nonce = request.getParameter("nonce");// 随机数 1413789908
String echostr = request.getParameter("echostr");//
System.out.println("in get nonce: "+nonce);
String[] str = { _token, timestamp, nonce };
Arrays.sort(str); // 字典序排序
String bigStr = str[] + str[] + str[]; // SHA1加密
String digest = SHA1.encode(bigStr);
if (digest.equals(signature)) {
outPut = echostr;
System.out.println("check success!");
}
System.out.println("write response:"+outPut);
PrintWriter writer = response.getWriter();
writer.write(outPut);
writer.flush();
writer.close();
return null;
} @RequestMapping(value = "/gateway",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public void handleWechatMessage(HttpServletRequest request,HttpServletResponse response) throws Exception {
System.out.println("received wechat event!");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String nonce = request.getParameter("nonce");
System.out.println("in post nonce: "+nonce);
request.getSession().setAttribute("nonce", nonce);
// 调用核心业务类接收消息、处理消息
String respMessage = processRequest(request,response);
// 响应消息
PrintWriter out = response.getWriter();
out.print(respMessage);
out.close();
} /**
* 处理微信发来的请求
*
* @param request
* @return
*/
public String processRequest(HttpServletRequest request,HttpServletResponse response) {
String respMessage = null;
try {
// 默认返回的文本消息内容
String respContent = "请求处理异常,请稍候尝试!";
// xml请求解析
Map<String, String> requestMap = MessageUtil.parseXml(request);
// 发送方帐号(open_id)
String fromUserName = requestMap.get("FromUserName");
request.setAttribute("openId", fromUserName);
HttpSession session=request.getSession();
session.setAttribute("openId", fromUserName); System.out.println("from:"+fromUserName);
// 公众帐号
String toUserName = requestMap.get("ToUserName");
// 消息类型
String msgType = requestMap.get("MsgType");
System.out.println("MsgType:"+msgType);
// 回复文本消息
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
textMessage.setFuncFlag();
// 文本消息
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
respContent = "您发送的是文本消息!";
}
// 图片消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
respContent = "您发送的是图片消息!";
}
// 地理位置消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
respContent = "您发送的是地理位置消息!";
}
// 链接消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
respContent = "您发送的是链接消息!"+requestMap.get("EventKey");
}
// 音频消息
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
respContent = "您发送的是音频消息!";
}
// 事件推送
else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
// 事件类型
String eventType = requestMap.get("Event");
// 订阅
if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { String access_token = WeixinToken.getRecentToken(); String urlStr = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+access_token+"&openid="+fromUserName;
URL url = new URL(urlStr);
BufferedReader bufr = new BufferedReader(new InputStreamReader(new BufferedInputStream(url.openStream()), "utf-8"));
String line;
StringBuffer sb=new StringBuffer();
while((line=bufr.readLine())!=null){
sb.append(line);
}
bufr.close();
JSONObject jsonObject = JSONObject.fromObject(sb.toString());
if(jsonObject.get("errcode") != null){
throw new Exception(jsonObject.getString("errmsg"));
} String nick = String.valueOf(jsonObject.get("nickname"));
String sex = String.valueOf(jsonObject.get("sex"));
if (sex.equals("")) {
sex = "男";
} else if(sex.equals("")) {
sex = "女";
} else if(sex.equals("")) {
sex = "未知";
}
String city = String.valueOf(jsonObject.get("city"));
String province = String.valueOf(jsonObject.get("province"));
String country = String.valueOf(jsonObject.get("country"));
String headimgurl = String.valueOf(jsonObject.get("headimgurl")); User user = new User();
user.setOpenId(fromUserName);
user.setNick(nick);
user.setSex(sex);
user.setCity(city);
user.setProvince(province);
user.setCountry(country);
user.setHeadimgurl(headimgurl); userDao.save(user); respContent = "谢谢您的关注!";
log.debug("关注成功"); }
// 取消订阅
else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
// TODO 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息
}
// 自定义菜单点击事件
else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {
// TODO 自定义菜单权没有开放,暂不处理该类消息
String key = requestMap.get("EventKey");
if(key.equals("MAINTAIN")){
respContent = "服务热线:400-008-7070";
}
if(key.equals("INFO")){
respContent = "我是爱车,我为主人服务!";
}
System.out.println("event key:"+key);
}
// 自定义view界面
else if (eventType.equals(MessageUtil.EVENT_TYPE_VIEW)){
String url = requestMap.get("EventKey");
System.out.println("url:"+url);
// String[] urls = url.split("&redirect_uri=");
// String lastUrl = "";
// String lastUrl2 = "";
// Member user = memberService.findByWeixinOpenId(fromUserName);
/*if (user == null) {
lastUrl = urls[1];
String[] urls1 = lastUrl.split("&response_type=");
String str1 = urls1[0] + "?openId=" + fromUserName;
String url0 = URLEncoder.encode(str1,"UTF-8");
lastUrl2 = urls[0] + "&redirect_uri=" + url0 + "&response_type=" + urls1[1];
} else { // JsonConfig config = new JsonConfig();
// config.setIgnoreDefaultExcludes(false);
// config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
//这里是核心,过滤掉不想使用的属性
// config .setExcludes(filterNames) ; // JsonConfig config = new JsonConfig();
// config.setJsonPropertyFilter(new PropertyFilter(){
// public boolean apply(Object source, String name, Object value) {
// if(name.equals("lockedDate") || name.equals("loginDate") || name.equals("loginPhoneDate") || name.equals("birth") || name.equals("loginDate")) { // loginPhoneDate checkDate birth
// return true;
// } else {
// return false;
// }
// }
// }); // JSONObject json = JSONObject.fromObject(user, config);//将java对象转换为json对象
// String userJson = json.toString();//将json对象转换为字符串 // System.out.println("userJson:"+userJson);
lastUrl = urls[0] + "&member=" + user.toString() + "#w" + urls[1];
}*/
}
}
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
} catch (Exception e) {
e.printStackTrace();
}
return respMessage; } }
wechat.properties-配置微信AppId和AppSecret (注意该文件所在位置为ConfKit.java所在包所在的src/main/java下)
#ht AppId = wxd5609f7b5b4dd051
AppSecret = 2d1c183c1e99c378c7a60b595c825e03 MessageProcessingHandlerImpl=com.gson.MessageProcessingHandlerImpl
WeixinLoginController.java
openId绑定用户的代码,根据实际项目绑定代码按需修改,注意项目中如果使用了权限管理,注意把微信相关接口不拦截。
package isa.qa.blep.admin.controller; import java.util.HashMap;
import java.util.Map; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import isa.qa.core.common.BoqumaConstant;
import isa.qa.core.dao.EcshopUserDao;
import isa.qa.core.dto.EcshopUserDto;
import isa.qa.core.model.EcshopUsers;
import isa.qa.core.weixin.util.WeixinToken; @CrossOrigin
@Controller
@RequestMapping(value = "/api")
public class WeixinLoginController {
@Autowired
private EcshopUserDao userDao; /**
* 获取openId
* @param wxCode
* @param req
* @return
*/
@RequestMapping(value = "/weixin/code/{wxCode}/wxcode",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Object getWeiXinOpenId(@PathVariable String wxCode){
System.out.println("wxCode--》》》:"+wxCode);
if ("undefined".equals(wxCode)) {
return null;
}
String wxOpenId = "";
EcshopUsers user = null;
try {
wxOpenId = WeixinToken.getWeChatId(wxCode);
System.out.println("根据code获取得的wxOpenId:"+wxOpenId);
user = userDao.findOneByOpenId(wxOpenId);
if (user == null) {
System.out.println("返回的openid:"+wxOpenId);
Map<String, String> map = new HashMap<String, String>();
map.put("openId", wxOpenId);
return map;
}
} catch (Exception e) {
e.printStackTrace();
}
return user; } /**
* 微信登陆(绑定)
* @param ecshopUserDto
* @param openId
* @return
*/
@RequestMapping(value = "/weixin/{openId}/member",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Object checkMember(@RequestBody EcshopUserDto ecshopUserDto, @PathVariable String openId){
String userName = ecshopUserDto.getUserName();
Md5PasswordEncoder md5 = new Md5PasswordEncoder();
md5.setEncodeHashAsBase64(true);
String encryptedPassword = md5.encodePassword(ecshopUserDto.getPassword(),BoqumaConstant.SALT);
System.out.println("微信登录用户--UserName:"+userName);
EcshopUsers user = userDao.findOneByUserNameAndPassword(userName,encryptedPassword);
if (user == null) {
System.out.println("用户名或密码错误!");
Map<String, String> map = new HashMap<String, String>();
map.put("hint", "用户名或密码错误!");
return map;
} else {
user.setOpenId(openId);
userDao.save(user);
System.out.println("绑定成功!");
return user;
} }
}
补充:
微信菜单的配置示例:
{
"button":[
{
"name" : "优惠活动",
"sub_button" : [
{
"type": "view",
"name": "最新促销",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/sales-list&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
},{
"type": "view",
"name": "近期活动",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/near-activities&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
},{
"type": "view",
"name": "产品展厅",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/products&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
}
]
},
{
"name" : "预约服务",
"sub_button" : [
{
"type": "view",
"name": "试驾预约",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/repairAppointment/try///carId//&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
},{
"type": "view",
"name": "维修预约",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/repairAppointment////carId//&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
},{
"type": "view",
"name": "保养预约",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/repairAppointment/protect///carId//&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
} ]
},
{
"name" : "我的地盘",
"sub_button" : [
{
"type": "view",
"name": "一键救援",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/oneKey&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
},{
"type": "view",
"name": "在线客服",
"url": "http://kefu.easemob.com/webim/im.html?tenantId=6137"
},{
"type": "view",
"name": "优惠券",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/packetlist&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
},{
"type": "view",
"name": "会员中心",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx195166055e5eddb2&redirect_uri=http://carowl.cn/app/index.html#/member-center&response_type=code&scope=snsapi_base&state=wx&connect_redirect=1#wechat_redirect"
},{
"type": "view",
"name": "APP下载",
"url": "http://carowl.cn/download_page/index.html"
} ]
}
]
}
公众号配置的一些流程:
1.登录公众号 https://mp.weixin.qq.com/
2.启用开发者模式
3.进入开发-基本配置
4.填入相关信息,之一URL和Token都要对应上上面所配置的接口和设置的Token
5.网页授权获取用户信息 修改 修改为上一部URL中的 wechat.htib.com.cn
6.微信菜单的配置:
(1).进入在线接口调试工具
(2).配置菜单(先基础配置得到access_token,再使用access_token配置菜单)
微信绑定用户服务端代码-根据code获取openId然后绑定用户的更多相关文章
- java实现微信小程序服务端(登录)
微信小程序如今被广泛使用,微信小程序按照微信官网的定义来说就是: 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验. 这就是微信小程序的魅力所在,有 ...
- openssl实现双向认证教程(服务端代码+客户端代码+证书生成)
一.背景说明 1.1 面临问题 最近一份产品检测报告建议使用基于pki的认证方式,由于产品已实现https,商量之下认为其意思是使用双向认证以处理中间人形式攻击. <信息安全工程>中接触过 ...
- 使用 git post-receive 钩子部署服务端代码
在 git 中提交服务器源码的时候,如果能够直接更新到测试服务器,并且重启服务使其生效,会节省懒惰的程序员们大量的时间. git 的 Server-side hook (服务端钩子/挂钩)可以用来做件 ...
- Socket通信客户端和服务端代码
这两天研究了下Socket通信,简单实现的客户端和服务端代码 先上winfrom图片,客户端和服务端一样 服务端代码: using System; using System.Collections.G ...
- IOS IAP APP内支付 Java服务端代码
IOS IAP APP内支付 Java服务端代码 场景:作为后台需要为app提供服务,在ios中,app内进行支付购买时需要进行二次验证. 基础:可以参考上一篇转载的博文In-App Purcha ...
- Photon Server 实现注册与登录(二) --- 服务端代码整理
一.有的代码前端和后端都会用到.比如一些请求的Code.使用需要新建项目存放公共代码. 新建项目Common存放公共代码: EventCode :存放服务端自动发送信息给客户端的code Operat ...
- 根据wsdl,apache cxf的wsdl2java工具生成客户端、服务端代码
根据wsdl,apache cxf的wsdl2java工具生成客户端.服务端代码 apache cxf的wsdl2java工具的简单使用: 使用步骤如下: 一.下载apache cxf的包,如apac ...
- 使用Jacoco统计服务端代码覆盖情况实践
一.背景 随着需求的迭代,需求增加的同时,有可能会伴随着一些功能的下线.如果不对系统已经不用的代码进行梳理并删除不需要的代码,那么就会增加系统维护成本以及理解成本.但经历比较长的迭代以及系统交接,可能 ...
- 微信支付 第一篇 JSAPI 支付配置与获取 OpenID
开通微信支付支付产品 首先要在微信支付申请成为 微信支付商户. 选择开通具体的支付产品 成为微信支付商户后在管理后台选择微信支付中的具体支付产品并申请开通如 JSAPI . 将支付商户与公众号关联 这 ...
随机推荐
- Hadoop权威指南学习笔记一
Hadoop简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考,有什么不到之处还望指出.一起学习一起进步. 转载请注明:http://blog.csdn.net/ ...
- LeetCode: Regular Expression Matching 解题报告
Roman to IntegerGiven a roman numeral, convert it to an integer. Input is guaranteed to be within th ...
- const在c和c++中地位不同
先测试C语言的const: #include<stdio.h> int main() { ; //等价于 //int const a = 10; //a = 11;//err ; cons ...
- c++深/浅拷贝 && 构造函数析构函数调用顺序练习题
1.深/浅拷贝 编译器为我们提供的合成拷贝构造函数以及合成的拷贝赋值运算符都是浅拷贝.浅拷贝只是做简单的复制,如果在类的构造函数中new出了内存,浅拷贝只会简单的复制一份指向该内存的指针,而不会再开辟 ...
- 【C++程序员学 python】python 之变量
既然学过C++,那么就应该知道变量是什么,常量是什么. python 相比于C++,在使用变量之前不用先声明. 而是直接使用,python 会根据你的变量自动识别其类型. 假如a = 123 那么a ...
- linux下getrlimit与sysconf函数
#include <stdio.h> #include <sys/time.h> #include <sys/resource.h> int main(int ar ...
- datagridview导出到excel
Microsoft.Office.Interop.Excel.Range range = null; string saveFileName = ""; bool fileSave ...
- am335x gpio 模拟 spi 驱动添加
kernel 内 make menuconfig // make menuconfig Device Drivers ---> [*] SPI support ---> <*> ...
- kafkaStream执行过程中出现TimeoutException异常退出
日志中出现以下异常信息,程序中断退出. 目前参考别人的修改下面的配置,原来使用的hostname,改成IP,再观察观察. advertised.listeners=PLAINTEXT://192.1 ...
- div 背景自适应
.bg { background: url(images/title_bg.jpg); filter: "progid:DXImageTransform.Microsoft.AlphaIma ...