springMVC中使用单例模式以及微信开发遇到的问题

Lucare 发布于 2016/04/27 10:04
阅读 572
收藏 0

需求就是自己写了一个微信公众平台开发的小玩意,使用SSM框架,由于请求时基本都需要access_token,所以我让所有的controller都继承了一个BaseController:

public class BaseController {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    private static String access_token = null;

    public String getAccess_token(){
        if (access_token == null) {
            StringBuilder url = new StringBuilder();
            url.append("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential");
            url.append("&appid=").append(GlobalStatic.APPID);
            url.append("&secret=").append(GlobalStatic.SECRET);
            String result = WebUtils.sendGet(url.toString());
            JSONObject json = JSON.parseObject(result);
            access_token = (String) json.get("access_token");
        }
        return access_token;
    }

}



修改后的版本:
public class BaseController {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    public String getAccess_token(){
        return BaseHolder.access_token;
    }

    private static class BaseHolder{
        private static String access_token = getAccess_token();

        private static String getAccess_token(){
            StringBuilder url = new StringBuilder();
            url.append("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential");
            url.append("&appid=").append(GlobalStatic.APPID);
            url.append("&secret=").append(GlobalStatic.SECRET);
            String result = WebUtils.sendGet(url.toString());
            JSONObject json = JSON.parseObject(result);
            access_token = (String) json.get("access_token");
            return access_token;
        }
    }

}



这里有三个问题:

1.修改后的版本能否解决多线程访问重复请求access_token问题?(基于servlet的请求本来就是多线程吧)

2.关于access_token两小时过期,如何解决?

3.微信提供的接口在页面上直接访问存在跨域请求的问题,那么我转移到系统里模拟请求,页面先请求自己的系统,由自己的系统发起请求再去微信服务器。这个方法感觉不太合理,请求数据需要再包装,返回数据有时也要再处理。有什么好的解决方法没有?


请前辈们赐教!

加载中
0
Lucare
Lucare
帮顶!!!!
0
Lucare
Lucare
再来一发
0
J
JCod3r
token的过期时间你是知道的    你如果只是自己写着玩   完全可以在程序启动的时候去请求获取token   然后根据返回的过期时间起个定时任务没隔多久去请求一次token就可以了
0
Lucare
Lucare

引用来自“JCod3r”的评论

token的过期时间你是知道的    你如果只是自己写着玩   完全可以在程序启动的时候去请求获取token   然后根据返回的过期时间起个定时任务没隔多久去请求一次token就可以了
可以试试
0
@ccny
@ccny

1.重复的获取的问题:

  (1):设置为同步

  (2):在每次获取的时候,确认在容器里里面是否已经存在。

2.accessToken 过期怎么办:
   (1)  每次请求时,判断是否过期

 (2)单独线程解决。

0
Joyzhou
Joyzhou

1.持久化access_token,使用静态变量或者缓存

2.使用redis等缓存持久化access_token,设置过期时间,如果不使用当调用api时可抛出过期异常,再进行捕获处理。

0
Lucare
Lucare

引用来自“@ccny”的评论

1.重复的获取的问题:

  (1):设置为同步

  (2):在每次获取的时候,确认在容器里里面是否已经存在。

2.accessToken 过期怎么办:
   (1)  每次请求时,判断是否过期

 (2)单独线程解决。

这两个解决方法开销会不会太大。
@ccny
@ccny
想太多。当然。那种都可以解决。2种是保险一些。
0
Lucare
Lucare

引用来自“Joyzhou”的评论

1.持久化access_token,使用静态变量或者缓存

2.使用redis等缓存持久化access_token,设置过期时间,如果不使用当调用api时可抛出过期异常,再进行捕获处理。

这个方法可行。
0
南湖船老大
南湖船老大
这个跟多线程有什么关系,我想不出来。一旦你授权成功后,下一次微信再来访问你的时候会带有一个openid,和用户一一对应的,你只需要把token,openid和过期时间存数据库就好,做好过期检测就好
0
Lucare
Lucare

引用来自“南湖船老大”的评论

这个跟多线程有什么关系,我想不出来。一旦你授权成功后,下一次微信再来访问你的时候会带有一个openid,和用户一一对应的,你只需要把token,openid和过期时间存数据库就好,做好过期检测就好
access_tokern基本每个请求都需要,我没有保存到数据库,所以维持一个单例供所有控制器使用。
返回顶部
顶部