使用Myeclipse+Java+图灵API开发微信公众号并发布到BAE测试

一、创建web工程
二、项目工程图
这里写图片描述
三、WechatServlet

package demo.servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import demo.process.SignUtil;
import demo.process.WechatProcess;
/**
 * 微信服务端收发消息接口
 * 
 */
public class WechatServlet extends HttpServlet {
    //验证
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
         // 微信加密签名  
        String signature = request.getParameter("signature");  
        // 时间戳  
        String timestamp = request.getParameter("timestamp");  
        // 随机数  
        String nonce = request.getParameter("nonce");  
        // 随机字符串  
        String echostr = request.getParameter("echostr");  

        PrintWriter out = response.getWriter();  
        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败  
        if (SignUtil.checkSignature(signature, timestamp, nonce)) {  
            out.print(echostr); 
            out.close();  
            out = null; 
        } 
    }
    //接收数据并返回
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        StringBuffer sb = new StringBuffer();
        InputStream is = request.getInputStream();
        InputStreamReader isr = new InputStreamReader(is, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String s = "";
        while ((s = br.readLine()) != null) {
            sb.append(s);
        }
        String xml = sb.toString(); //此即为接收到微信端发送过来的xml数据

        //返回结果
        String  result = new WechatProcess().processWechatMag(xml);

        try {
            OutputStream os = response.getOutputStream();
            os.write(result.getBytes("UTF-8"));
            os.flush();
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

四、ReceiveXmlEntity

package demo.entity;
/**
 * 接收到的微信xml实体类
 * @author pamchen-1
 *
 */
public class ReceiveXmlEntity {
    private String ToUserName="";
    private String FromUserName="";
    private String CreateTime="";
    private String MsgType="";
    private String MsgId="";
    private String Event="";
    private String EventKey="";
    private String Ticket="";
    private String Latitude="";
    private String Longitude="";
    private String Precision="";
    private String PicUrl="";
    private String MediaId="";
    private String Title="";
    private String Description="";
    private String Url="";
    private String Location_X="";
    private String Location_Y="";
    private String Scale="";
    private String Label="";
    private String Content="";
    private String Format="";
    private String Recognition="";

    public String getRecognition() {
        return Recognition;
    }
    public void setRecognition(String recognition) {
        Recognition = recognition;
    }
    public String getFormat() {
        return Format;
    }
    public void setFormat(String format) {
        Format = format;
    }
    public String getContent() {
        return Content;
    }
    public void setContent(String content) {
        Content = content;
    }
    public String getLocation_X() {
        return Location_X;
    }
    public void setLocation_X(String locationX) {
        Location_X = locationX;
    }
    public String getLocation_Y() {
        return Location_Y;
    }
    public void setLocation_Y(String locationY) {
        Location_Y = locationY;
    }
    public String getScale() {
        return Scale;
    }
    public void setScale(String scale) {
        Scale = scale;
    }
    public String getLabel() {
        return Label;
    }
    public void setLabel(String label) {
        Label = label;
    }
    public String getTitle() {
        return Title;
    }
    public void setTitle(String title) {
        Title = title;
    }
    public String getDescription() {
        return Description;
    }
    public void setDescription(String description) {
        Description = description;
    }
    public String getUrl() {
        return Url;
    }
    public void setUrl(String url) {
        Url = url;
    }
    public String getPicUrl() {
        return PicUrl;
    }
    public void setPicUrl(String picUrl) {
        PicUrl = picUrl;
    }
    public String getMediaId() {
        return MediaId;
    }
    public void setMediaId(String mediaId) {
        MediaId = mediaId;
    }
    public String getEventKey() {
        return EventKey;
    }
    public void setEventKey(String eventKey) {
        EventKey = eventKey;
    }
    public String getTicket() {
        return Ticket;
    }
    public void setTicket(String ticket) {
        Ticket = ticket;
    }
    public String getLatitude() {
        return Latitude;
    }
    public void setLatitude(String latitude) {
        Latitude = latitude;
    }
    public String getLongitude() {
        return Longitude;
    }
    public void setLongitude(String longitude) {
        Longitude = longitude;
    }
    public String getPrecision() {
        return Precision;
    }
    public void setPrecision(String precision) {
        Precision = precision;
    }
    public String getEvent() {
        return Event;
    }
    public void setEvent(String event) {
        Event = event;
    }
    public String getMsgId() {
        return MsgId;
    }
    public void setMsgId(String msgId) {
        MsgId = msgId;
    }
    public String getToUserName() {
        return ToUserName;
    }
    public void setToUserName(String toUserName) {
        ToUserName = toUserName;
    }
    public String getFromUserName() {
        return FromUserName;
    }
    public void setFromUserName(String fromUserName) {
        FromUserName = fromUserName;
    }
    public String getCreateTime() {
        return CreateTime;
    }
    public void setCreateTime(String createTime) {
        CreateTime = createTime;
    }
    public String getMsgType() {
        return MsgType;
    }
    public void setMsgType(String msgType) {
        MsgType = msgType;
    }
}

五、SignUtil,这个类的token需要与后面微信公众号配置的token一致

package demo.process;

import java.security.MessageDigest;  
import java.security.NoSuchAlgorithmException;  
import java.util.Arrays;  

/** 
 * 请求校验工具类 
 *  
 */  
public class SignUtil {  
    // 与接口配置信息中的Token要一致,自己配置
    private static String token = "Token";  

    /** 
     * 验证签名 
     *  
     * @param signature 
     * @param timestamp 
     * @param nonce 
     * @return 
     */  
    public static boolean checkSignature(String signature, String timestamp, String nonce) {  
        String[] arr = new String[] { token, timestamp, nonce };  
        // 将token、timestamp、nonce三个参数进行字典序排序  
        Arrays.sort(arr);  
        StringBuilder content = new StringBuilder();  
        for (int i = 0; i < arr.length; i++) {  
            content.append(arr[i]);  
        }  
        MessageDigest md = null;  
        String tmpStr = null;  

        try {  
            md = MessageDigest.getInstance("SHA-1");  
            // 将三个参数字符串拼接成一个字符串进行sha1加密  
            byte[] digest = md.digest(content.toString().getBytes());  
            tmpStr = byteToStr(digest);  
        } catch (NoSuchAlgorithmException e) {  
            e.printStackTrace();  
        }  

        content = null;  
        // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信  
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;  
    }  

    /** 
     * 将字节数组转换为十六进制字符串 
     *  
     * @param byteArray 
     * @return 
     */  
    private static String byteToStr(byte[] byteArray) {  
        String strDigest = "";  
        for (int i = 0; i < byteArray.length; i++) {  
            strDigest += byteToHexStr(byteArray[i]);  
        }  
        return strDigest;  
    }  

    /** 
     * 将字节转换为十六进制字符串 
     *  
     * @param mByte 
     * @return 
     */  
    private static String byteToHexStr(byte mByte) {  
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };  
        char[] tempArr = new char[2];  
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];  
        tempArr[1] = Digit[mByte & 0X0F];  

        String s = new String(tempArr);  
        return s;  
    }  
}  

六、TulingApiProcess

package demo.process;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * 调用图灵机器人api接口,获取智能回复内容
 */
public class TulingApiProcess {
    /**
     * 调用图灵机器人api接口,获取智能回复内容,解析获取自己所需结果
     * @param content
     * @return
     */
    public String getTulingResult(String content){
        String result = "";
        /** 此处为图灵api接口,参数key需要自己去注册申请,先以11111111代替,
         * ps:我申请的不是官网的,个人选择 */
        String apiUrl = "http://op.juhe.cn/robot/index?key=111111111&info=";
        String param = "";
        try {
            param = apiUrl+URLEncoder.encode(content,"utf-8");
        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } //将参数转为url编码

        /** 发送httpget请求 */
        HttpGet request = new HttpGet(param);

        try {
            HttpResponse response = HttpClients.createDefault().execute(request);
            if(response.getStatusLine().getStatusCode()==200){
                result = EntityUtils.toString(response.getEntity());
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        /** 请求失败处理 */
        if(null==result){
            return "对不起,你说的话真是太高深了……";
        }

        try {
            result = new JSONObject(result).getString("result");
            JSONObject json = new JSONObject(result);
            //以code=10000为例,参考图灵机器人api文档
            if(100000==json.getInt("code")){
                result = json.getString("text");
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }
}

七、WechatProcess

package demo.process;

import java.util.Date;

import demo.entity.ReceiveXmlEntity;

/**
 * 微信xml消息处理流程逻辑类
 * @author pamchen-1
 *
 */
public class WechatProcess {
    /**
     * 解析处理xml、获取智能回复结果(通过图灵机器人api接口)
     * @param xml 接收到的微信数据
     * @return  最终的解析结果(xml格式数据)
     */
    public String processWechatMag(String xml){
        /** 解析xml数据,返回ReceiveXmlEntity实例化对象 */
        ReceiveXmlEntity xmlEntity = new ReceiveXmlProcess().getMsgEntity(xml);

        /** 以文本消息为例,调用图灵机器人api接口,获取回复内容 */
        String result = "";
        if("text".endsWith(xmlEntity.getMsgType())){
            result = new TulingApiProcess().getTulingResult(xmlEntity.getContent());
        }

        /** 此时,如果用户输入的是“你好”,在经过上面的过程之后,result为“你也好”类似的内容 
         *  因为最终回复给微信的也是xml格式的数据,所有需要将其封装为文本类型返回消息
         * */
        result = new FormatXmlProcess().formatXmlAnswer(xmlEntity.getFromUserName(), xmlEntity.getToUserName(), result);

        return result;
    }
}

八、ReceiveXmlProcess

package demo.process;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import demo.entity.ReceiveXmlEntity;
/**
 * 解析接收到的微信xml,返回消息对象
 */
public class ReceiveXmlProcess {
    /**
     * 解析微信xml消息
     * @param strXml
     * @return
     */
    public ReceiveXmlEntity getMsgEntity(String strXml){
        ReceiveXmlEntity msg = null;
        try {
            if (strXml.length() <= 0 || strXml == null)
                return null;

            // 将字符串转化为XML文档对象
            Document document = DocumentHelper.parseText(strXml);
            // 获得文档的根节点
            Element root = document.getRootElement();
            // 遍历根节点下所有子节点
            Iterator<?> iter = root.elementIterator();

            // 遍历所有结点
            msg = new ReceiveXmlEntity();
            //利用反射机制,调用set方法
            //获取该实体的元类型
            Class<?> c = Class.forName("demo.entity.ReceiveXmlEntity");
            msg = (ReceiveXmlEntity)c.newInstance();//创建这个实体的对象

            while(iter.hasNext()){
                Element ele = (Element)iter.next();
                //获取set方法中的参数字段(实体类的属性)
                Field field = c.getDeclaredField(ele.getName());
                //获取set方法,field.getType())获取它的参数数据类型
                Method method = c.getDeclaredMethod("set"+ele.getName(), field.getType());
                //调用set方法
                method.invoke(msg, ele.getText());
            }
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println("xml 格式异常: "+ strXml);
            e.printStackTrace();
        }
        return msg;
    }
}

九、FormatXmlProcess

package demo.process;

import java.util.Date;
/**
 * 封装最终的xml格式结果
 * @author pamchen-1
 *
 */
public class FormatXmlProcess {
    /**
     * 封装文字类的返回消息
     * @param to
     * @param from
     * @param content
     * @return
     */
    public String formatXmlAnswer(String to, String from, String content) {
        StringBuffer sb = new StringBuffer();
        Date date = new Date();
        sb.append("<xml><ToUserName><![CDATA[");
        sb.append(to);
        sb.append("]]></ToUserName><FromUserName><![CDATA[");
        sb.append(from);
        sb.append("]]></FromUserName><CreateTime>");
        sb.append(date.getTime());
        sb.append("</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[");
        sb.append(content);
        sb.append("]]></Content><FuncFlag>0</FuncFlag></xml>");
        return sb.toString();
    }
}

XML配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>WechatServlet</servlet-name>
    <servlet-class>demo.servlet.WechatServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>WechatServlet</servlet-name>
    <url-pattern>/wechat</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

完整项目代码下载地址http://download.csdn.net/detail/qq_35489188/9651529

接下来就可以使用百度BAE快速搭建免费微信公众平台后台服务器。
http://jingyan.baidu.com/article/fec4bce27bfd19f2608d8b7e.html
1.完成到第三步创建好订单就行了
这里写图片描述

2.圆圈位置点击复制svn地址
3.myeclipe使用svn教程http://www.cnblogs.com/xdp-gacl/p/3497016.html
4..使用SVN检出我们在BAE上创建的项目,SVN–>从SVN检出项目–>Next–>选择使用现有的资源库位置–>选择我们的资源库,一路next,最后按下图操作,项目名称不用改(后面直接替换该工程下面的ROOT.war上传到BAE即可,还可以把我们的工程命名为与在BAE上一直的名)

注意是SVN账号密码是百度云的账号密码

这里写图片描述
之后Next–>Finish即可,这样我们就得到了在BAE上默认的工程,该工程下面有两个文件
这里写图片描述
5.把写好的微信工程发布到BAE的步骤:
1).右键写好的微信工程(注意不是从BAE上检出的微信工程,而是自己在Eclipse上创建的和BAE上同名的微信工程)–>Export–>WAR file,接下来按下图操作,注意war包需命名为ROOT.war,因为我们从BAE上检出的项目下就是ROOT.war,发布的时候直接替换咱们检出的工程下面的ROOT.war就可以了

这里写图片描述
6.发布微信工程到BAE,删除下面的ROOT.war包,把我们刚导出的微信工程的ROOT.war包放到该工程下,提交该工程到BAE即可,具体提交方法:右键点击该工程–>Team–>提交即可,

7.打开百度云管理中心,点击红圈的快捷发布即可
这里写图片描述

接下来需要申请微信公众号,目前我们可以用测试号进行测试,开始开发–>接口测试帐号申请
http://mp.weixin.qq.com/wiki/home/index.html

注意此处token需与之前项目的token一致,URL为项目域名+xml配置的Mapping路径

这里写图片描述

接下来就可以扫码测试啦!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值