微信公众平台申请消息接口--struts2(jsp)实现

  微信公众平台的高级功能为我们提供了“编辑模式”和“开发模式”两种高级功能。在“编辑模式”下,可以通过简单的界面编辑,来设置自动回复,或公众号底部自定义菜单等功能。但是,如果你还想自定义更加自由灵活的功能,就需要用开发者模式了。在此模式下,开发者可以通过公众平台提供的接口,实现自动回复、获取订阅者、自定义菜单消息等功能。甚至像小黄鸡这样的自动对话系统,都是在开发模式下完成的。

  好了,进入正题。要进入开发模式,首先需要申请消息接口。消息接口就是你的服务器上处理微信消息的地址,以后你的收听者给你发送的微信消息都会被转发到这个地址上进行处理。接口申请的大致过程是这样的。

  首先,你需要一个绑定了域名的服务器,然后填写一个处理接口申请的url地址和你自己的token(因为是你自己填写的,所以该token可以用于确认接口申请是你发出的而不是别人冒充的)。

  然后,微信服务器将发送GET请求到你填写的URL上,并且带上四个参数:

参数描述
signature 微信加密签名
timestamp 时间戳
nonce 随机数
echostr 随机字符串

  最后,就是你(开发者)需要做的的处理,即通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,否则接入失败。

  signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。

    加密/校验流程:

    1. 将token、timestamp、nonce三个参数进行字典序排序
    2. 将三个参数字符串拼接成一个字符串进行sha1加密
    3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
参见官方文档:http://mp.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3%E6%8C%87%E5%8D%97 中的“2 申请消息接口”
  
代码实现很简单。新建一个action用于处理微信服务器发过来的接口确认请求,假设命名为InterfaceConfirm
public class InterfaceConfirm extends ActionSupport {}

  以下是该action的execute()方法实现


@Override
    public String execute() throws Exception {
        // 获取请求和响应
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        //获取请求参数
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostring = request.getParameter("echostr");
        String token = "***";    //你自己填写的token
        //对请求参数和自己的token进行排序,并连接排序后的结果为一个字符串
        String[] strSet = new String[]{token, timestamp, nonce};
        java.util.Arrays.sort(strSet);
        String total = "";
        for (String string : strSet) {
            total = total + string;
        }
        //SHA-1加密实例
        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
        sha1.update(total.getBytes());
        byte[] codedBytes = sha1.digest();
        String codedString = new BigInteger(1, codedBytes).toString(16);//将加密后的字节数组转换成字符串。参见http://hi.baidu.com/aotori/item/c94813c4f15caa60f6c95d4a
        if (codedString.equals(signature)) { //将加密的结果与请求参数中的signature比对,如果相同,原样返回echostr参数内容
            OutputStream os = response.getOutputStream();
            BufferedWriter resBr = new BufferedWriter(new OutputStreamWriter(os));
            resBr.write(echostring);
            resBr.flush();
            resBr.close();
        }
        return SUCCESS;
    }

  接着配置一下这个action,并将配置的路径填写到第二张图中的URL里面,最后点击“提交”,如果参数响应正确,会提示成功,并跳转到成功提示页,“你已成为开发者”!!

  PS:其实以上验证过程还可以更简单,就是不加验证,直接返回echostr内容,如果你想这样做的话。因为这会带来一个安全问题,就是任何另外一个开发者,只要知道你这个action的地址,再随便填写一个token都可以通过接口申请验证。这样的话,任何发送到另外一个开发者的公众账号上的消息,实际上都会被微信服务器转发到你的服务器上。更进一步的后果就不得而知了。

 

posted on 2013-05-06 11:38  balabala已被注册  阅读(5068)  评论(3编辑  收藏  举报

导航