基于微信开发 专题

 

SDK下载
注意事项
腾讯QQ互联平台为广大开发者整理了以下SDK列表,辅助开发者快速接入QQ登录、分享等功能。
使用时请注意:
1. 以下有Connect_logo_1.png 标志的是QQ登录团队提供的官方版本。
2. 欢迎广大开发爱好者自行开发其他语言版本的SDK,并分享到开发者论坛-开源SDK共享(惊喜礼物等你拿!)
3. 对于非官方SDK包,由于腾讯未对其进行验证,因此无法保证其可用性。使用时遇到问题请直接与作者联系或在论坛上反馈,腾讯公司将不提供相关的技术支持。
4. 本页面提供的SDK全部基于OAuth2.0协议。原有基于OAuth1.0协议的SDK下载请见:SDK下载_OAuth1.0


SDK for 网站接入

http://wiki.open.qq.com/wiki/website/SDK%E4%B8%8B%E8%BD%BD

 

Weixin4J为Java微信开发爱好者提供的微信公众开发平台SDK,简化了Java对微信的开发。
https://gitee.com/weixin4j/weixin4j/
http://www.weixin4j.org



链接到往期回顾内容在自定义菜单中的页面地址中选择跳转到历史消息列表即可。该操作相当于复制历史消息列表链接到页面地址。

软件工具:微信公众平台

1、进入平台的自定义菜单,选择已有或者创建一个“往期回顾”菜单,在页面地址下点击“从公众号图文消息中选择”。

2、点击历史记录,选中“跳转到历史消息列表”。

https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzA3OTc4MTQ5NQ==#wechat_redirect

 


3、保存发布并发布,或者选择预览发送到测试号去看下效果。

4、预览效果。历史消息中显示之前所发布的消息。

 



微信开放平台--扫码登陆
微信开放平台https://open.weixin.qq.com

网站应用微信登录开发指南
准备工作
网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。
在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&lang=zh_CN

新增一个网站应用的入口https://open.weixin.qq.com/cgi-bin/frame?t=home/web_tmpl&lang=zh_CN

 实践:https://www.cnblogs.com/0201zcr/p/5133062.html



微信公众号开发:

微信-公众平台https://mp.weixin.qq.com

https://github.com/ihaolin/wechat

 

 

--获取用户信息中文乱码的解决方案

在微信开发中我们会经常需要获取用户的信息。
微信给我们提供了获取用户信息的api,
地址为

https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

将其中的access_token替换为我们的access_token 
openid为关注用户的openid就可以获取到用户的信息了。

问题描述

不过获取到的数据却是中文乱码

这里写图片描述

而用Java程序获取的结果也是一样的

这里写图片描述

解决方案

这个乱码主要是由于微信那边采用的是“ISO-8859-1”编码造成的。

我们对获取的结果进行编码

这里写图片描述

    String token = AccessTokenTool.getAccessToken();
    String URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
    // 原始json
    String jsonResult = HttpUtil.sendGet(URL.replace("OPENID", openid).replace("ACCESS_TOKEN", token));
    System.out.println(jsonResult);
    // 编码后的json
    String json = new String(jsonResult.getBytes("ISO-8859-1"), "UTF-8");
    System.out.println(json);

获取自定义菜单乱码也是一样的解决方法

这里写图片描述

参考文献

获取用户基本信息(UnionID机制) 
HttpUtil工具类参考

 http://blog.csdn.net/frankcheng5143/article/details/51612550

 


微信公众号开发小结:
使用了框架https://gitee.com/kingshine/FastBootWeixin
造型理由,基于spring boot,readme一看就懂,项目活跃。虽然个别地方还是不很理解
遇到的问题:
项目集成了spring security,要对FastBootWeixin相关的url进行权限处理 pass
点击按钮后需要跳转到相关url,这个时候需要附带能够标识用户的相关信息,譬如code或openId。目前采取的处理办法是这样的:
WxButton中写有一个url,这个url会盅到后台另一个url,这个url会redirect到获取code的url,然后微信回调第三个接口。
目前方案的流程:
btn Url-->后台api_1【redirect 获取用户信息的url https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842】-->微信服务器回调接口2 api_2  -->根据code从FastBootWeixin,至此就获取到用户的openId
--->根据openId获取到用户UserName,生成token--->redirect 前端页面地址?token=生成的用户token---->前端服务目前已经拿到token,相当于完成了登陆过程
===========================================================================
===========================================================================
上面的交互流程看看怎么优化下

微信公众号的一些有用的功能,回复信息后,后台可以给予响应。这个地方也可以是一个好的入口

其它问题:
这个项目是前后端分离的,并且分开部署。微信公众号需要使用80端口,前端页面也要使用80端口。
这个时候要么分开部署到两台机器,要么使用nginx分流

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        #listen       80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;	
		client_max_body_size	10m;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location /{
            proxy_pass 	http://localhost:8081;
        }
		
        location /wx{
            proxy_pass 	http://localhost:8080;
        }

        location /api{
            proxy_pass 	http://localhost:8080;
        }		

        location /swagger-ui.html{
            proxy_pass http://localhost:8080;
        }
		
        location /swagger{
            proxy_pass http://localhost:8080;
        }
		
        location /swagger-resources{
            proxy_pass http://localhost:8080;
        }
		
        location /webjars{
            proxy_pass http://localhost:8080;
        }
		
        location /v2/api-docs{
            proxy_pass http://localhost:8080;
        } 
		

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

}

上面配置中两个坑:
(1)一个是前端的坑:前端的nodejs程序只listen了服务器的外网ip,所以上面的配置没有生效。
错误信息如下:
The page you are looking for is temporarily unavailable. Please try again later.
然后curl 一个这个localhost:8081 也是connect refuse的。尝试了几次,不行。然后问前端的同学,说没有监听localhost和127.0.0.1 (哭)
解决办法:

        location /{
            proxy_pass 	http://localhost:8081;
        }

改为

        location /{
            proxy_pass 	http://nodesjs监听的IP(引自为服务器的外网ip):8081;
        }

(2)FastBootWeixin框架在微信网页授权时,报错:

微信登录失败
授权回调域名校验出错,错误码:1003

解决办法:

        location /wx{
            proxy_pass 	http://localhost:8080;
        }

更改为:

        location /wx{
            proxy_set_header   Host $host; //解决getRequestURL、getServerName、getServerPort
                                           //如果nginx是80服务,上面就够,代表默认servlet_port是80;否则需要Host $host:$server_port,不配置servlet_port会导致丢失端口
            proxy_pass 	http://localhost:8080;
        }

Tips:授权域名回调,此处回调的域名在正规企业号中配置的地方:
开发--->接口权限-->网页授权获取用户基本信息 后面的“修改”-->公众号设置-->功能设置-->网页授权域名

PS:在企业号或服务号中设置域名时,还需要一个文件MP_verify_s48K3hK0cfXLUMMn.txt,如果需要nginx 转发,配置办法如下:

        location = /MP_verify_s48K3hK0cfXLUMMn.txt{
              proxy_set_header   Host $host;
              proxy_pass        http://localhost:8080;
        }

上面配置中有两个注意事项:
1:location后面要加空格,否则会报错:

[root@localhost nginx]# nginx -s reload
nginx: [emerg] unknown directive "location=/MP_verify_s48K3hK0cfXLUMMn.txt" in /etc/nginx/nginx.conf:64

2: 扩展名的点号"."前不需要加转义符“\”,因为使用“=”时,是直接匹配,没有使用正则表达式

一、语法规则:
location [=|~|~*|^~] /uri/ { … }
= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
~ 开头表示区分大小写的正则匹配
~*  开头表示不区分大小写的正则匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
/ 通用匹配,任何请求都会匹配到。
多个location配置的情况下匹配顺序为(参考资料而来,还未实际验证,试试就知道了,不必拘泥,仅供参考):
首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。
例子,有如下匹配规则:
location = / {
   #规则A
}
location = /login {
   #规则B
}
location ^~ /static/ {
   #规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
   #规则D
}
location ~* \.png$ {
   #规则E
}
location !~ \.xhtml$ {
   #规则F
}
location !~* \.xhtml$ {
   #规则G
}
location / {
   #规则H
}
那么产生的效果如下:
访问根目录/, 比如http://localhost/ 将匹配规则A
访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
访问 http://localhost/static/a.html 将匹配规则C
访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不起作用,而 http://localhost/static/c.png 则优先匹配到规则C
访问 http://localhost/a.PNG 则匹配规则E,而不会匹配规则D,因为规则E不区分大小写。
访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会用到。
访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存在。

http://blog.csdn.net/oranyujian/article/details/42169597




注意事项:
1、回调页面域名或路径需使用字母、数字及“-”的组合(例:wx.qq.com或wx.qq.com/mp),不支持IP地址、端口号及短链域名。填写的域名或路径需与实际回调URL中的域名或路径相同。
2、填写的域名须通过ICP备案的验证。
3、将文件MP_verify_s48K3hK0cfXLUMMn.txt(点击下载)上传至填写域名或路径指向的web服务器(或虚拟主机)的目录(若填写域名,将文件放置在域名根目录下,例如wx.qq.com/MP_verify_s48K3hK0cfXLUMMn.txt;若填写路径,将文件放置在路径目录下,例如wx.qq.com/mp/MP_verify_s48K3hK0cfXLUMMn.txt),并确保可以访问。



在测试号中设置时,点“修改”会直接弹出对话框,让填写需要回调的域名

 

http://blog.sina.com.cn/s/blog_56d8ea900102vhaj.html
http://blog.csdn.net/sondx/article/details/7593540
原因解析:
已经确认过“网页授权获取用户基本信息”中配置的url是没有错误的
后与FastBootWeinxin项目的作者光正 联系(在此处要感谢一个光正,赞)
确定回调地址是这样的

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd63033623663454d&redirect_uri=http%3A%2F%2Flocalhost%3A9090%2Fwx%2Fv1%2Fnavigate%2Findex%2Fbtn&response_type=code&scope=snsapi_userinfo&state&connect_redirect=1#wechat_redirect

,原因是redirect_uri是通过下面的api获取的

String redirectUrl = request.getRequestURL() + (StringUtils.isEmpty(request.getQueryString()) ? "" : "?" + request.getQueryString());

来获取的,然后
但是因为你这个通过nginx代理,所以导致取requestURL时取到的是localhost



使用nginx后后端



差点忘记了,还有一个大坑:
接入指南https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319
项目中使用了com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter,然后就凭空出了一个坑:
返回的echostr,加了一个双引号一个双引号,
然后微信服务器认证就不通过

解决办法:
在com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter前面添加org.springframework.http.converter.StringHttpMessageConverter就不会出现这个问题

   @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        // See SPR-7316,for weixin token verify.fastjson will convert string 123 to "123"
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        stringHttpMessageConverter.setWriteAcceptCharset(false);
        //增加两个优先处理的转换类型.
        converters.add(new ByteArrayHttpMessageConverter());
        converters.add(stringHttpMessageConverter);

        FastJsonHttpMessageConverter httpMessageConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
                SerializerFeature.WriteEnumUsingToString,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.DisableCircularReferenceDetect);
        fastJsonConfig.setSerializeFilters((ValueFilter) (o, s, source) -> {
            if (source == null) {
                return "";
            }
            if (source instanceof Date) {
                return ((Date) source).getTime();
            }
            return source;
        });
        httpMessageConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(httpMessageConverter);
    }

spring3.0开始引用org.springframework.http.converter.HttpMessageConverter


定义上面报错原因的途径:
在postman中带上微信服务器的参数【日志中有】,去访问配置的接口,查看返回值即可



还有一个坑,差点忘掉:
使用nginx后,swaager上展示的接口不能调用,所以的请求地址都变成对127.0.0.1主机的请求,显示是不对的【应该是部署的服务器地址】
解决办法

swagger.host=1gepingguo.cn 

这样调用的接口,就会请求http://1gepingguo.cn/具体的api接口

Spring MVC中jsessionid所引起的问题
多余的jsessionid,spring boot+spring-boot-starter-web时,@Controller时,return "redirect:"+url;时,redirect被额外添加了一个“;jsessionid=xxx”,导致前端不能正常处理

http://youhuale.cn/;jsessionid=7037A79EACA055A2F6DA8137990472D3?token=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMzg0ZmM5MS03YmFjLTQ4NmEtYWQ2Ny1hNjgxZTBmNTkxNWUiLCJleHAiOjE1MTE4NzkxMzcsImlhdCI6MTUxMTgzNTkzNywiaXNzIjoiaGoiLCJhdWQiOiJhcHAifQ.xrdiokjHhSH0V0smi8x19zJ-AUi99KQ2Vepr9Kl3er1UcNAMPlSn9SSVtKKv9C77ZBjaMWjigoqNopSNRjgRgg


解决办法:

不通过Spring MVC做重定向,自己直接调用:
response.sendRedirect(url);

encodeRedirectURL()仅在无法确定浏览器是否支持cookie的时候才会在url后面附加上jsessionid,如果它能找到一个jsessionid的cookie,它就认为浏览器是支持cookie的。因此可以自己创建一个jsessionid的cookie来欺骗encodeRedirectURL()。
Cookie cookie = new Cookie("jsessionid", "2jcligmgi6fh");
cookie.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookie);
然后再调用Spring MVC的重定向功能就没有问题了:
return new ModelAndView("redirect:"+url);

无疑,这里最好的方法是第3种方法。

 

原因:
在Spring MVC当使用RedirectView或者"redirect:"前缀来做重定向时,Spring MVC最后会调用:
response.sendRedirect(response.encodeRedirectURL(url));

对于IE来说,打开一个新的浏览器窗口,第一次访问服务器时,encodeRedirectURL()会在url后面附加上一段jsessionid,如果初始的url为"http://www.sina.com.cn",最终得到的url为"http://www.sina.com.cn;jsessionid=2jcligmgi6fh"。

这是典型的Java做事的方式,其他语言的服务器端平台并不会这样做。这个jsessionid很多时候会引起严重的问题,例如,如果你使用上述带有jsessionid的url直接访问新浪的网站,IE会向你报告:找不到服务器。

http://blog.csdn.net/zshake/article/details/37658147

相关问题:

Spring MVC项目中页面重定向一般使用return "redirect:/other/controller/";即可。而Spring Boot使用了@RestController注解,上述写法只能返回字符串,解决方法如下:

将一个HttpServletResponse参数添加到处理程序方法然后调用response.sendRedirect("some-url");

@RestController
public class FooController {

  @RequestMapping("/foo")
  void handleFoo(HttpServletResponse response) throws IOException {
    response.sendRedirect("some-url");
  }

}

https://www.cnblogs.com/EasonJim/p/7459486.html

mysql中的case when

SELECT
    tu.id userId,
    tu.real_name realName,
    cdp.id developPlanId,
    cdp.doing,
    cdp.ability,
    cdp.wealth,
    cdp.living_location livingLocation,
    CASE
WHEN cdp.stage_type = 0 THEN
    'Now'
WHEN cdp.stage_type = 1 THEN
    '一两年后的'
WHEN cdp.stage_type = 127 THEN
    'Future'
END stageType
FROM
    career_develop_plan cdp
JOIN tb_user tu ON cdp.user_id = tu.id
ORDER BY
    cdp.id ASC,
    stage_type DESC

http://blog.csdn.net/qq_35620807/article/details/52665383
MySql 中 case when then else end 的用法 https://www.cnblogs.com/renpei/p/5485730.html

用户没有关注公众号,通过https://open.weixin.qq.com/connect/oauth2/authorize来获取用户的openId时,可以不要求用户关注公众号,就可获取到openId,但不能获取用户的nickName及头像信息


Oauth2在微信这一点的请求流程:

用fiddler拦截的相关数据如下:
重定向的是这个地址:
Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxdbadbfd67fdf29c8&redirect_uri=http%3A%2F%2Fyouhuale.cn%2Fwx%2Fv3%2Fnavigate%2Findex&response_type=code&scope=snsapi_userinfo&state#wechat_redirect 
之后又重定向到这个
http://youhuale.cn/wx/v3/navigate/index?code=001xnDOx1L0Bsg0DaDQx1mMxOx1xnDOV&state= 
也就是说code其实拿到了

 







 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值