基于fastweixin的微信开发环境搭建

  由于公司业务需要,开发微信版本,才开始接触微信公众平台。在github折腾了几天,试过好几个微信sdk,最终选择fastweixin。个人觉得这个框架还是值得使用的,使用也简单。那么问题来了,很多人想使用fastweixin,苦于没有详细开发教程(官方只给出最简单的接入而已),本文是更为详细的微信接入开发教程,适合对微信有一定了解的开发者。

0.项目地址

项目主页:https://github.com/sd4324530/fastweixin
开源中国主页:http://git.oschina.net/pyinjava/fastweixin
csdn主页:https://code.csdn.net/sd4324530/fastweixin

1.对于maven项目,引用一下地址即可

<!-- fastweixin -->       
<dependency>
    <groupId>com.github.sd4324530</groupId>
    <artifactId>fastweixin</artifactId>
    <version>1.3.12</version>
</dependency>

 

2. 整合spring,将APIConfig单例管理,这里交由spring管理,配置如下;

application.properties 全局属性文件,将微信公众号信息配置进去

weixin.appid=APPID
weixin.secret=APP_SECRET
weixin.token=TOKEN

 applicationContext.xml  spring配置文件

<context:property-placeholder location="classpath:application.properties" />

<bean id="apiConfig" class="com.linkcm.weixin.api.config.ApiConfig">
      <constructor-arg name="appid" value="${weixin.appid}" />
      <constructor-arg name="secret" value="${weixin.secret}" />
</bean>

 

到这里为止,已经和spring整合完毕啦!

接下来,接入微信服务器准备,整合springmvc。

3. 整合springmvc

新建类WXController.java,继承weixinSupport,并实现相关方法,如果需要响应用户的消息/事件推送,可以直接重写相关方法,下面代码重写了几个常用的方法,加上少量的业务逻辑。

具体实现如下:

 

/**
 * 微信服务器入口
 * 
 * @author zenglong
 * @date 2016年8月19日 上午9:32:41
 */
@Controller
@RequestMapping("/wx")
public class WXController extends WeixinSupport {
    @Value("${weixin.token}")
    private String token;

    @Autowired
    private ApiConfig config;

    @Override
    protected String getToken() {
        return token;
    }

    @Override
    protected String getAppId() {
        return config.getAppid();
    }

    /**
     * 绑定服务器-get
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/bind", method = RequestMethod.GET)
    @ResponseBody
    public String bind(HttpServletRequest request, HttpServletResponse response) {
        if (isLegal(request)) {
            // 绑定微信服务器成功
            return request.getParameter("echostr");
        } else {
            // 绑定微信服务器失败
            return "";
        }
    }

    /**
     * 处理数据请求-post
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/bind", method = RequestMethod.POST, produces = MediaType.TEXT_XML_VALUE + ";charset=utf-8")
    @ResponseBody
    public String process(HttpServletRequest request,
            HttpServletResponse response) {
        log.debug("数据请求 S ...");
        if (isLegal(request)) {
            String result = processRequest(request);
            log.debug("数据请求 E ...    ," + result);
            return result;
        } else {
            log.debug("数据请求 E ...    ," + "空处理");
            return "";
        }
    }

    /********************** 消息处理 S ***************************/

    /**
     * 文本消息
     */
    @Override
    protected BaseMsg handleTextMsg(TextReqMsg msg) {
        // TODO Auto-generated method stub
        log.debug("文本消息...");
        // 回复文本
        // BaseMsg baseMsg = new TextMsg("你发送的是文本,内容为:" + msg.getContent() +
        // toEmoji(0x1F604));
        // baseMsg.setCreateTime(new Date().getTime());
        // baseMsg.setMsgType(ReqType.TEXT);

        // 回复图文等
        // MediaAPI mediaAPI = new MediaAPI(config);
        // UploadMediaResponse uploadMediaResponse = mediaAPI.uploadMedia(
        // com.linkcm.weixin.api.enums.MediaType.IMAGE,
        // new File("C:/Users/username/Desktop/images/putty.jpg"));
        // String mediaId = uploadMediaResponse.getMediaId();

        String mediaId4ikey = "59DJfSyZPO4fFIwedIews8iXFvsRBm3TzetDcuZz23d2Hg21G85Lae1GmCDfaCJd";
        String mediaId4finance = "GR4M2oXuim2sQghkq42Yc4k1UbMvPcuItgbHpWJRwXwfGMG2kOSr_klmQ_lY_gZX";

        String media_id = "yknEZ5F9yhQVHxbNWsGjyjVaixeV2vjzhjUPi12PglyH_rOm4zBJgy6MpkrvbWRw";
        String fileUrl = "http://a.hiphotos.baidu.com/image/h%3D360/sign=c6c7e73ebc389b5027ffe654b535e5f1/a686c9177f3e6709392bb8df3ec79f3df8dc55e3.jpg";
        Article article = new Article("源码在线首页", // 图文消息的作者
                "我的图文描述", // 图文消息的描述
                fileUrl, // 在图文消息页面点击“阅读原文”后的页面
                "http://vivof.com");
        Article article2 = new Article(
                "NodeJs首页", 
                "Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境", fileUrl,
                "http://www.baidu.com");
        Article article3 = new Article("Vue.js", "图文消息的描述  ", fileUrl,
                "http://www.baidu.com");
        BaseMsg baseMsg = new NewsMsg(
                Arrays.asList(article, article2, article3));

        return baseMsg;
    }

    /**
     * 位置消息
     */
    @Override
    protected BaseMsg handleLocationMsg(LocationReqMsg msg) {
        // TODO Auto-generated method stub
        log.debug("位置消息...");
        BaseMsg baseMsg = new TextMsg("你发送的是地理位置 " + toEmoji(0x1F604) + " ("
                + msg.getLocationX() + "," + msg.getLocationY() + ")");
        baseMsg.setCreateTime(new Date().getTime());
        baseMsg.setMsgType(ReqType.TEXT);
        return baseMsg;
    }

    /**
     * 链接消息
     */
    @Override
    protected BaseMsg handleLinkMsg(LinkReqMsg msg) {
        // TODO Auto-generated method stub
        log.debug("链接消息...");
        return super.handleDefaultMsg(msg);
    }

    /********************** 消息处理 E ***************************/

    /********************** 事件处理 S ***************************/

    /**
     * 关注事件
     */
    @Override
    protected BaseMsg handleSubscribe(BaseEvent event) {
        // TODO Auto-generated method stub
        log.debug("关注事件...");
        BaseMsg baseMsg = new TextMsg("欢迎关注源码在线服务,").addLink("点这里了解更多内容",
                "http://vivof.com");
        return baseMsg;
    }

    /**
     * 取消关注事件
     */
    @Override
    protected BaseMsg handleUnsubscribe(BaseEvent event) {
        // TODO Auto-generated method stub
        log.debug("取消关注事件...");
        return super.handleUnsubscribe(event);
    }

    /**
     * 点击事件
     */
    @Override
    protected BaseMsg handleMenuClickEvent(MenuEvent event) {
        // TODO Auto-generated method stub
        log.debug("单击事件...");
        String openid = event.getFromUserName();
        log.info("用户openid : " + openid);
        GetUserInfoResponse userInfo = new UserAPI(config).getUserInfo(openid);
        String unionid = userInfo.getUnionid();
        log.debug("openid 获取 unionid : " + unionid);

        // ... 业务逻辑,根据用户openid/unionid判断权限
        if (authentication(unionid)) {
            // BaseMsg baseMsg = new TextMsg("身份验证通过");
            log.info("身份验证通过...");
            String fileUrl = "http://a.hiphotos.baidu.com/image/h%3D360/sign=c6c7e73ebc389b5027ffe654b535e5f1/a686c9177f3e6709392bb8df3ec79f3df8dc55e3.jpg";
            Article article = new Article("源码在线首页", // 图文消息的作者
                    "我的图文描述", // 图文消息的描述
                    fileUrl, // 在图文消息页面点击“阅读原文”后的页面
                    "http://vivof.com");
            Article article2 = new Article(
                    "NodeJs首页", // 图文消息的作者
                    "Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境", fileUrl,
                    "http://www.baidu.com");
            Article article3 = new Article("Vue.js", "图文消息的描述  ", fileUrl,
                    "http://www.baidu.com");
            BaseMsg baseMsg = new NewsMsg(Arrays.asList(article, article2,
                    article3));

            return baseMsg;
        } else {
            BaseMsg baseMsg = new TextMsg("身份验证失败");
            baseMsg.setMsgType(ReqType.TEXT);
            return baseMsg;
        }
    }

    /**
     * 跳转事件
     */
    @Override
    protected BaseMsg handleMenuViewEvent(MenuEvent event) {
        // TODO Auto-generated method stub
        log.debug("跳转事件...");
        String openid = event.getFromUserName();
        log.info("用户openid : " + openid);
        GetUserInfoResponse userInfo = new UserAPI(config).getUserInfo(openid);
        log.debug("openid 获取 unionid : " + userInfo.getUnionid());

        // ... 自己的业务逻辑

        BaseMsg baseMsg = new TextMsg("文本消息");
        baseMsg.setMsgType(ReqType.TEXT);
        return baseMsg;
    }

    /**
     * 地理位置事件
     */
    @Override
    protected BaseMsg handleLocationEvent(LocationEvent event) {
        // TODO Auto-generated method stub
        log.debug("位置事件...");
        return super.handleLocationEvent(event);
    }

    /**
     * 扫描事件
     */
    @Override
    protected BaseMsg handleScanCodeEvent(ScanCodeEvent event) {
        // TODO Auto-generated method stub
        log.debug("扫描事件...");
        return super.handleScanCodeEvent(event);
    }

    /**
     * 消息模版
     */
    @Override
    protected BaseMsg handleTemplateMsgEvent(TemplateMsgEvent event) {
        // TODO Auto-generated method stub
        log.debug("消息模版...");
        return super.handleTemplateMsgEvent(event);
    }

    /********************** 事件处理 E ***************************/

    /********************** emoji表情 S ***************************/

    /**
     * 发送emoji表情
     * 
     * @param hexEmoji
     * @return
     */
    private String toEmoji(int hexEmoji) {
        log.debug("发送emoji表情...");
        return String.valueOf(Character.toChars(hexEmoji));
    }

    /********************** emoji表情 E ***************************/

    /********************** 帮助方法 S ***************************/

    /**
     * 微信用户根据unionid身份认证
     * 
     * @param unionid
     * @return
     */
    private boolean authentication(String unionid) {
        log.debug("身份认证开始...");
        WechatUser wechatUser = null;
        // ... 业务逻辑,如查数据库匹配信息
        // WechatUser wechatUser = userService.getWechatUser(unionid);
        log.debug("微信用户信息:" + wechatUser);
        if (null != wechatUser
                && StringUtils.isNotBlank(wechatUser.getNickname())) {
            log.debug("身份认证通过...");
            return true;
        } else {
            log.debug("身份认证失败...");
            return false;
        }
    }

    /********************** 帮助方法 E ***************************/

    /************************* 页面跳转 S ******************************/

    @RequestMapping("/callback/page/{page}")
    public void toPge(@PathVariable String page, String code,
            HttpServletResponse response) throws Exception {
        log.info("即将跳转到 页面: " + page);
        OauthAPI api = new OauthAPI(config);
        OauthGetTokenResponse token = null;
        try {
            token = api.getToken(code);
        } catch (Exception e) {
            log.info("获取token失败...");
            throw new APIException(e.getMessage());
        }
        log.info("token : " + token);

        // .. 根据业务逻辑跳转
        redirect(page, response);
    }

    /**
     * 页面回调路由
     * 
     * @return
     */
    private Map<String, String> initPageMapping() {
        String basePath = "http://hsk20160127.imwork.net/finance-wap/";
        Map<String, String> map = new HashMap<String, String>();
        map.put("sub11", basePath + "card/cardfolder/0.html");
        map.put("sub12", basePath + "card/cardfolder/0.html");
        map.put("sub13", basePath + "folder/0.html");
        map.put("sub14", basePath + "folder/1.html");
        map.put("sub15", basePath + "folder/2.html");

        map.put("sub21", basePath + "macroeconomy");
        map.put("sub22", basePath + "industrydata");
        return map;
    }

    /**
     * 根据路由进行页面跳转
     * 
     * @param page
     * @param response
     * @throws PageException
     * @throws IOException
     */
    private void redirect(String page, HttpServletResponse response)
            throws Exception {
        Map<String, String> pageMapping = initPageMapping();

        if (pageMapping.containsKey(page)) {
            response.sendRedirect(pageMapping.get(page));
        } else {
            // 页面参数错误
            throw new PageException("回调页面参数错误");
        }
    }

    /************************* 页面跳转 E ******************************/
}

 

 这样就整合springmvc完毕。

 接下来就是相关设置与本地环境的搭建了。

4. 域名解析

  花生壳域名解析还是可以的。去官网注册一个,好像好几块钱什么费用就可以免费使用了,感觉还是不错的。设置如下

这样就可以使用网址 http://hsk20160127.imwork.net/weixin  来访问项目了。

说明:虽然微信开发需要使用80端口(项目是8080端口),因为使用了花生壳,这些已经帮我们搞定了,外网80端口映射到本地的8080tomcat项目端口,我们只管使用网址访问我们的项目就可以。

 

5. 公众号设置

  这里重点讲解fastweixin框架的使用,公众号设置就不在赘述。以下是简要叙述需要设置的项,文字不重要,看图。

5.1 接入地址

  填写上面controller中的绑定方法bind()的get请求,也就是  /项目名/wx/bind,如果你使用花生壳等域名解析工具,访问完整路径为  http://XXX.imwork.net/项目名/wx/bind

填好,点击确定,发现绑定配置失败~~~~  是不是项目还没启动呢    ^_^  ,继续往下看 

 

5.2 授权回调地址

点击修改

确认即可。

5.3 js域名回调

  这里没用上,可不填写。

 

6. 启动项目,因为花生壳映射的8080端口,所以设置tomcat的访问端口为8080,然后启动项目。回到回调地址页面,点击确定即可接入成功。

 

OK。觉得有帮助记得给个赞哈 ^_^。

 

如有疑问可联系QQ:303483090 ,一起讨论交流。

 

转载于:https://www.cnblogs.com/zenglong/p/fastweixin.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值