微信绑定用户服务端代码-根据code获取openId然后绑定用户

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信绑定用户服务端代码-根据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&timestamp=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[0] + str[1] + str[2]; // 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(0);
      // 文本消息
      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("1")) {
               sex = "";
           } else if(sex.equals("2")) {
               sex = "";
           } else if(sex.equals("0")) {
               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 微信用户绑定java获取用户信息报40163错误,怎么重新获取code

微信小程序怎么记录登录用户操作信息?

微信小程序 获取用户openid

小程序微信小程序绑定企业微信后怎样获取到用户信息