微信订阅号自定义菜单java开发

小弟应运营要求要更改公众号菜单,本以为是在公众号官网上进行配置即可,,谁知道 竟然是开发者模式编辑的。无奈,从未接触过公众号开发的我。有开始啃开了微信开发的api,原来的做这个得小伙伴,跑路了。但没有交接。哎~~~

废话不多说。开启流程。

1、小弟这个仅仅是【订阅号】的开发。进入公众号后左边菜单找到

这是该公众号开发时用到的关键参数列表,如下:

这里介绍下几个开发中用到的重要参数:

1、开发者ID(AppId):就是开发人员在开发该订阅号  的账号

2、开发者密码(AppSecret) : 就是开发人员在开发该订阅号  的密码

3、IP白名单:该参数是微信服务器的一个ip白名单的验证,如果没有该白名单,微信服务器就不会承认你的地址是安全的。不能获取access_token参数

4、服务器地址(URL):他是微信回调 你的服务器的地址。记住这个服务器地址是你的。不是微信的。而且这个地址有些硬性条件

      (1)该url必须开通外网映射,不管你是在公司 还是在家。这个地址必须外网能够访问到。

      (2)该url端口号必须是80,至于映射到本地应用端口是XXXX都无所谓。配置外网映射 我使用的是Sunny-Ngrok(https://www.ngrok.cc/)内网穿透服务,这个是一个网站提供,里面有免费的http外网映射。其他的映射服务均失败(可能是自己太菜)。。格式,外网映射地址+应用验证接口

5、令牌(Token):验证使用的一个自定义字符串

6、消息加解密密钥:这个参数是发送/接收消时加密用的。但如果设置是明文方式,那么这个参数没用到。我就没用到

7、消息加密/解密方式:明文、兼容、安全

以上参数,构成了微信开发的基础参数。但想要真正开发,还有一些准备要做。

一、验证:

不能可直接在生产环境开发,大牛这么做的都很少。所以需要一个测试环境。那么就是开发者工具中的【公众号测试账号】中,就可以创建,目前其他几项我就是看看没有仔细研究,后期补发。点击进入:

用手机微信直接授权登录即可:

简单说明一下,测试账号信息表中的内容是根据登录的微信生成的。。我试了好几次都不会变。应该是账号绑定的。注意,,这时测试账号的账号和密码,,前者的账号  密码是生产环境。还有 这个登录的微信必须是该公众号管理员授权绑定的微信账号才行。

在公众号左侧菜单 人员设置中添加人员(创建者忽略),然后开发者工具中的Web开发者工具绑定一个开发者的微信号即可。
 

* 然后说说接口配置信息,第一次测试账号配置是空的。url 也就是你的服务器地址,必须是80端口或443(也就是http和https默认端口)外网能够访问到的地址+你的验证应用接口地址  和第4 配置套路一模一样比如  http://xxxx.cn/wx/yanzhengApi,验证的java demo为:

@ResponseBody
	@RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.GET)
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 微信加密签名
		String signature = request.getParameter("signature");
		System.out.println("微信加密签名=====" + signature);
		// 随机字符串
		String echostr = request.getParameter("echostr");
		System.out.println("随机字符串=====" + echostr);
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		System.out.println("时间戳=====" + echostr);
		// 随机数
		String nonce = request.getParameter("nonce");
		System.out.println("随机数=====" + echostr);
		String[] str = { TOKEN, timestamp, nonce };
		Arrays.sort(str); // 字典序排序
		String bigStr = str[0] + str[1] + str[2];
		System.out.println("=====================" + bigStr);

		MessageDigestUtils digestutil = new MessageDigestUtils();
		String sha1 = MessageDigestUtils.sha1(bigStr);
		// 确认请求来至微信
		if (sha1.equals(signature)) {
			System.out.println("=====验证成功============");
			response.getWriter().print(echostr);
		}

	}

这个demo 方法上面肯定还有一个controller 的mapping,自己写吧。

* 下面的token 就是上述第5点的token

单机提交,如果没有问题,会提示配置成功(这里需要确定你的借口在接收到请求后的响应时间,太长微信都不认, 多试几次就可以了),否则就是配置失败。失败的原因,其实很简单。就是你的url配置的问题。一般token不会有问题。上述图片中是我配置很久才成功的截图。可以修改。提交验证是,会请求上述demo。大哥断点就知道怎么回事了。而且微信的api文档对这块说的还是比较清楚的。就是没有明说url配置需要80或443 端口(PS:其实api文档也说明了。但是,是在另一个页面说明的。。【开始开发】-【接入指南】最下方才说明,这里配置url啥都没说。)

完成以上工作久具备了 订阅号开发的最基本的配置。

* JS接口安全域名 我没有用到。这里不做介绍

使用你的登录测试账号的微信扫描一下  【测试号二维码】就会使当前微信关注这个订阅号了。点击关注。进入后,发现啥玩意都没有。咋办。新建菜单,这个自定义菜单可以使用微信提供的web页面创建 也可以使用java写,java 的demo如下

工具类:

package com.tiancaibao.service.weixin;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tiancaibao.weixin.pojo.token.WeixinToken; 

/** 
 * 获取微信access_token工具类 

 */  
public class WeiXinAccessTokenUtil  
{  
    private static final Logger DEBUG_LOGGER = Logger.getLogger(WeiXinAccessTokenUtil.class);  
      
    /** 
     * 从微信上
     * 获取微信access_token 
     * 
     */  
    public static WeixinToken getWeiXinAccessToken(String appid,String secret)  
    {  
        if(StringUtils.isEmpty(appid)|| StringUtils.isEmpty(secret))  
        {  
            DEBUG_LOGGER.error("appid or secret is null");  
            return null;  
        }  
        WeixinToken token = new WeixinToken();  
        try  
        {  
          String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;  
              HttpClient httpClient = new HttpClient();  
            GetMethod getMethod = new GetMethod(url);  
            int execute = httpClient.executeMethod(getMethod);  
            System.out.println("execute:"+execute);  
            String getResponse = getMethod.getResponseBodyAsString();  
            System.out.println("========return的json========"+getResponse);
            JSONObject json = (JSONObject) JSON.parseObject(getResponse);  
               token.setAccessToken(json.getString("access_token"));
               token.setExpiresIn(new Integer(json.getString("expires_in"))); 
               Date createtime=new Date();;
			token.setCreatetime(createtime);
        }  
        catch (IOException e)  
        {  
            DEBUG_LOGGER.error("getAccessToken failed,desc:::"+e);  
            e.printStackTrace();  
        }  
    
        return token; 
    }  


}  

access_token实体:

package com.tiancaibao.weixin.pojo.token;

import java.io.Serializable;
import java.util.Date;

public class WeixinToken implements Serializable {
    private Integer id;

    private String accessToken;

    private Integer expiresIn;

    private Date createtime;

    protected String fields;

    private static final long serialVersionUID = 1L;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAccessToken() {
        return accessToken;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken == null ? null : accessToken.trim();
    }

    public Integer getExpiresIn() {
        return expiresIn;
    }

    public void setExpiresIn(Integer expiresIn) {
        this.expiresIn = expiresIn;
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public void setFields(String fields) {
        this.fields = fields;
    }

    public String getFields() {
        return fields;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", accessToken=").append(accessToken);
        sb.append(", expiresIn=").append(expiresIn);
        sb.append(", createtime=").append(createtime);
        sb.append(", fields=").append(fields);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

请求创建工具:

package com.tiancaibao.weixin.menu;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tiancaibao.service.weixin.MyX509TrustManager; 



/**
* 

* 开发人员: liming  </br>

 */
public class WeixinUtil {
    
    private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);
    

    // 菜单创建(POST) 限100(次/天)
    public static String menu_create_url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
/***
 * 自定义菜单创建接口:
http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
自定义菜单查询接口:
http请求方式:GET https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN
自定义菜单删除接口:
http请求方式:GET https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
 * 
 */
    /**
     * 创建菜单
     * 
     * @param menu 菜单实例
     * @param accessToken 有效的access_token
     * @return 0表示成功,其他值表示失败
     */
    public static int createMenu(Menu menu, String accessToken) {
        int result = 0;
        // 拼装创建菜单的url
        String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
        // 将菜单对象转换成json字符串
        String jsonMenu = JSONObject.toJSONString(menu);
        // 调用接口创建菜单
        JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
        if (null != jsonObject) {
            if (0 != jsonObject.getInteger("errcode")) {
                result = jsonObject.getInteger("errcode");
                log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
            }
        }

        return result;
    }
    

    
    
    /**
     * 描述:  发起https请求并获取结果
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式(GET、POST)
     * @param outputStr 提交的数据
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
     */
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyX509TrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSONObject.parseObject(buffer.toString());
        } catch (ConnectException ce) {
            log.error("Weixin server connection timed out.");
        } catch (Exception e) {
            log.error("https request error:{}", e);
        }
        return jsonObject;
    }
    /**
     * 发送图片消息
     * @param accesstoken
     * {
    "touser":"OPENID",
    "msgtype":"image",
    "image":
    {
      "media_id":"MEDIA_ID"
    }
}
     * @param openid
     */
    public static int SendCustomerMessage(String accesstoken ){
    	      String url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+accesstoken;
    	      ImageMsg image =new ImageMsg();
    	      Image ima= new Image();
    	      ima.setMedia_id("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM");
    	      image.setImage(ima);
    	      image.setTouser("ovlNE1A7Zlufu0wfMYiweE6igo-c");
    	      image.setMsgtype("image");// 图片类型消息

    	      
    	      String jsonMenu = JSONObject.toJSONString(image);
    	      System.out.println(jsonMenu);
    	        // 调用接口创建菜单
  	        JSONObject jsonObject = httpRequest(url, "POST", jsonMenu);
    	      int  result = 0;
				if (null != jsonObject) {
    	            if (0 != jsonObject.getInteger("errcode")) {
    	                result = jsonObject.getInteger("errcode");
    	                log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInteger("errcode"), jsonObject.getString("errmsg"));
    	            }
    	        }

    	        return result;
      	
    }
    
 public static void main(String[] args) {
	}
}

自定义菜单创建main:

package com.tiancaibao.weixin.menu;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tiancaibao.service.weixin.WeiXinAccessTokenUtil;
import com.tiancaibao.weixin.pojo.token.WeixinToken;


/**
* 类名: MenuManager </br>
* 
* 描述:菜单管理器类 </br>

 */
public class MenuManager {
    private static Logger log = LoggerFactory.getLogger(MenuManager.class);

    public static void main(String[] args) {
      // 第三方用户唯一凭证  测试
     String appId = "wxxxxxxx";
        // 第三方用户唯一凭证密钥
        String appSecret = "xxxxxxxxxxxx";
    	    
        WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken(appId, appSecret);
        
       if (null != weiXinAccessToken) {
        	String asstoken=weiXinAccessToken.getAccessToken();
        			// 调用接口创建菜单
            int result = WeixinUtil.createMenu(getMenu(), asstoken);

            // 判断菜单创建结果
            if (0 == result)
                log.info("菜单创建成功!");
            else
                log.info("菜单创建失败,错误码:" + result);
       }
    }

    /**
     * 组装菜单数据
     * 
     * @return
     */
    private static Menu getMenu() {


        //新菜单自定义

        CommonButton mainBtn1New = new CommonButton();
        mainBtn1New.setName("呀!活动");
        mainBtn1New.setType("view");
        mainBtn1New.setKey("http://weixin.xxxx");

        CommonButton btn2_1 = new CommonButton();
        btn2_1.setName("历史文章");
        btn2_1.setType("view");
        btn2_1.setUrl("xxxx");

        CommonButton btn2_2 = new CommonButton();
        btn2_2.setName("积分商城");
        btn2_2.setType("view");
        btn2_2.setUrl("http://xxxx");

        CommonButton btn2_3 = new CommonButton();
        btn2_3.setName("客服热线");
        btn2_3.setType("click");
        btn2_3.setKey("我们的服务热线xx,工作时间 9:00-20:00,欢迎有问题拨打热线哦~");

        CommonButton btn3_1 = new CommonButton();
        btn3_1.setName("我的资产");
        btn3_1.setType("view");
        btn3_1.setKey("http://xxxx");

        CommonButton btn3_2 = new CommonButton();
        btn3_2.setName("登录注册");
        btn3_2.setType("view");
        btn3_2.setKey("http://xxx");

        CommonButton btn3_3 = new CommonButton();
        btn3_3.setName("我要出借");
        btn3_3.setType("view");
        btn3_3.setKey("http://xxx");

        CommonButton btn3_4 = new CommonButton();
        btn3_4.setName("下载APP");
        btn3_4.setType("view");
        btn3_4.setKey("https://xxx");
        
        /**
         * 微信:  mainBtn1,mainBtn2,mainBtn3底部的三个一级菜单。 执行前观察appSecret参数是否需要重置。记得的话就不需要。。不急的。估计悬了。。要重置,
         * 但重置后会不会对全有的菜单有影响呢?~~
         */
        
//        ComplexButton mainBtn1 = new ComplexButton();
//        mainBtn1.setName("呀!活动");
//        //一级下有4个子菜单
//        mainBtn1.setSub_button(new CommonButton[] {btn8,btn9});

        
        ComplexButton mainBtn2 = new ComplexButton();
        mainBtn2.setName("呀!姿势");
        mainBtn2.setSub_button(new CommonButton[] { btn2_1,btn2_2, btn2_3 });

        
        ComplexButton mainBtn3 = new ComplexButton();
        mainBtn3.setName("呀!我的");
        mainBtn3.setSub_button(new CommonButton[] { btn3_1,btn3_2,btn3_3, btn3_4 });

        
        /**
         * 封装整个菜单
         */
        Menu menu = new Menu();
        menu.setButton(new Button[] { mainBtn1New, mainBtn2, mainBtn3 });

        return menu;
    }
}

CommonButton:

package com.tiancaibao.weixin.menu;

/**
* 类名: CommonButton </br>
* 包名: com.souvc.weixin.menu
* 描述: 子菜单项 :没有子菜单的菜单项,有可能是二级菜单项,也有可能是不含二级菜单的一级菜单。 </br>

 */
public class CommonButton extends Button {
    
    private String type;
    private String key;
    private String  url;

    public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}

complexButton:

package com.tiancaibao.weixin.menu;

public class ComplexButton extends Button {
    private Button[] sub_button;

    public Button[] getSub_button() {
        return sub_button;
    }

    public void setSub_button(Button[] sub_button) {
        this.sub_button = sub_button;
    }
}

Button:

package com.tiancaibao.weixin.menu;


/**
* 类名: Button </br>
* 包名: com.souvc.weixin.menu
* 描述: 菜单项的基类  </br>
 */
public class Button {
    
    private String name;//所有一级菜单、二级菜单都共有一个相同的属性,那就是name

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Menu:

package com.tiancaibao.weixin.menu;

/**
* 类名: Menu </br>
* 包名: com.souvc.weixin.menu
* 描述: 整个菜单对象的封装 </br>

 */
public class Menu {
    private Button[] button;

    public Button[] getButton() {
        return button;
    }

    public void setButton(Button[] button) {
        this.button = button;
    }
}

以上就是 自定菜单的创建源码及过程。一级菜单和二级菜单的编辑 使用了java 的多态特性。api文档中也给出了具体的demo 可以参考。至于相关的事件和特性也请参看api文档,写的很详细了,不做赘述。

附加,接收微信回调处理方法:

/*
	 * 特别注意,req.getInputStream()只能获取一次,并且只能读取一次。如果想要多次读取,需要另外想办法。为了简单起见,
	 */
	@ResponseBody
	@RequestMapping(value = "/WechatCallbackApi", method = RequestMethod.POST)
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 设置编码
		req.setCharacterEncoding("utf-8");
		resp.setContentType("html/text;charset=utf-8");
		resp.setCharacterEncoding("utf-8");
		/*
		 * 该部分我们获取用户发送的信息,并且解析成<K,V>的形式进行显示
		 */
		// 解析用户发送过来的信息
		InputStream is = req.getInputStream();// 拿取请求流
		// 将解析结果存储在HashMap中
		Map<String, String> map = new HashMap<String, String>();
		// 解析xml,将获取到的返回结果xml进行解析成我们习惯的文字信息
		SAXReader reader = new SAXReader();//
		Document document = null;
		try {
			document = reader.read(is);// 读取流中的内容
		} catch (DocumentException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子节点
		List<Element> elementList = root.elements();
		// 遍历所有子节点,将所有的节点存放到map中,读取的时候方便
		for (Element e : elementList)
			map.put(e.getName(), e.getText());

		Set<String> keySet = map.keySet();
		// 输出解析后用户发过来的信息
		System.out.println("===解析用户发送过来的信息开始");
		String FromUserName = "";// 用户的openid
		String event = "";// 事件类型
		boolean ismessage = false;
		String messsgeContent = "";
		String shopid = "";
		String EventKey = "";
		for (String key : keySet) {
			System.out.println(key + ":" + map.get(key));
			if ("FromUserName".equals(key)) {
				FromUserName = map.get(key);
			}
			if ("Event".equals(key)) {
				event = map.get(key);
			}
			// 关键词报文开头
			if ("MsgId".equals(key)) {
				ismessage = true;
			}
			if ("Content".equals(key)) {
				messsgeContent = map.get(key);
			}
			if ("EventKey".equals(key)) {
				EventKey = map.get(key);
			}
		}

		System.out.println("==========是否发送message==============" + ismessage);
		System.out.println(":解析用户发送过来的信息结束");

		/*
		 * 该部分我们尝试按照文档的要求格式给用户回复文本信息、图文消息。重点:按照文档要求构造需要的参数。特别注意:参数区分大小写。
		 */
		// 发送普通文本消息,请查看文档关于“回复文本消息”的xml格式

		// 第一步:按照回复文本信息构造需要的参数
		TextMsg textMsg = new TextMsg();
		textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
		textMsg.setFromUserName(map.get("ToUserName"));
		textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
		textMsg.setMsgType("text");// 文本类型消息
		Date subscribedate = new Date();
		// 自定义菜单为 CLICK,关注为subscribe
		if (event.equals("CLICK")) {
			textMsg.setContent("我们的服务热线xxxx,工作时间 9:00-20:00,欢迎有问题拨打热线哦~\ue415");
		} else if (event.equals("subscribe")) {
			// 查询是否有关注记录
			Weixinshopsubscriberecord selectInfoByOpenId = wexinSubscibeservice.selectInfoByOpenId(FromUserName);
			System.out.println("=============查询是否有关注记录==========" + selectInfoByOpenId);
			if (EventKey != "" || EventKey != null || !"".equals(EventKey)) {
				System.out.println("===========================EventKey===============" + EventKey.toString());
				String[] Str = EventKey.split("_");
				// 此判断是为了防止二维码参数为空的情况
				if (Str.length > 1) {
					shopid = Str[1];
				}
			}
			// 未关注
			if (selectInfoByOpenId == null) {
				// 初次关注
				String FirstSubscribe = "终于等到你还好我没放弃,右下角快去开启你的财富之旅吧!" ;
				if(!"".equals(shopid)){

					FirstSubscribe+="   来源编号:"+ shopid;

				}
				
				
				textMsg.setContent(FirstSubscribe);
				Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord();
				weixinshop.setOpenid(FromUserName);
				weixinshop.setShopid(shopid);
				weixinshop.setState("1");
				weixinshop.setSubscribedate(subscribedate);
				weixinshop.setSubscribetime(subscribedate);
				// 保存openid
				wexinSubscibeservice.SubscribeSave(weixinshop);

			} else {
				// 取消后再次关注
				selectInfoByOpenId.setState("2");
				selectInfoByOpenId.setSubscribedate(subscribedate);
				selectInfoByOpenId.setSubscribetime(subscribedate);
				selectInfoByOpenId.setOpenid(FromUserName);
				selectInfoByOpenId.setShopid(shopid);
				wexinSubscibeservice.UpdateSubscribe(selectInfoByOpenId);// 更改记录
				
				String SecondSubscribe = "欢迎回到财富之路,等你启程!" ;
				if(!"".equals(shopid)){
					SecondSubscribe+="  来源编号:"+ shopid;
				}
				
				
				
				
				textMsg.setContent(SecondSubscribe);

			}
		} else if (event.equals("unsubscribe")) {
			Weixinshopsubscriberecord weixinshop = new Weixinshopsubscriberecord();
			weixinshop.setState("0");// 取消关注为0
			weixinshop.setSubscribedate(subscribedate);
			weixinshop.setSubscribetime(subscribedate);
			weixinshop.setOpenid(FromUserName);
			weixinshop.setShopid(shopid);
			wexinSubscibeservice.UpdateSubscribe(weixinshop);

		}
		// 是否发送客服消息
		Boolean issend = false;

		/**
		 * 回复图片消息
		 */
		ImageMsg imagemsg = new ImageMsg();
		imagemsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
		imagemsg.setFromUserName(map.get("ToUserName"));
		imagemsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
		imagemsg.setMsgType("image");// 文本类型消息
		Image Image = new Image();
		// Image.setMediaId("FsM7Uo7Nk1YDdSZr8zYu7p079vyXhsvdbW3ArYpwqcM");//图片ID,不固定

		Image.setMediaId("6GTGDx7tGKMgnHv2Qzd9-orxsSaNBr4TdLN_n2zdw14");// 图片ID,不固定

		imagemsg.setImage(Image);
		// 消息内容
		if (ismessage) {
			if (messsgeContent.indexOf("建军节快乐") != -1) {
				textMsg.setContent("活动已结束,欢迎下次来参加哦\ue409");
			}else if(messsgeContent.indexOf("中秋") != -1){
			   textMsg.setContent("http://4xxx/index.jsp?aid=fe66eb90a5ea40e3a956ecaf2926f1c9&activityid=110312&wuid=457767&keyversion=0&isFromApiFilter=1");
		     }else if (messsgeContent.indexOf("客服 联系 电话") != -1) {
				textMsg.setContent("我们的客服热线:xxx,快去拨打吧,美丽的客服妹子在等你~");
			} else if (messsgeContent.indexOf("你好") != -1 || messsgeContent.indexOf("在么") != -1
					|| messsgeContent.indexOf("在") != -1 || messsgeContent.indexOf("在?") != -1
					|| messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("您好?") != -1
					|| messsgeContent.indexOf("你好?") != -1 || messsgeContent.indexOf("你好啊?") != -1
					|| messsgeContent.indexOf("hi") != -1 || messsgeContent.indexOf("hello") != -1) {
				textMsg.setContent("Hi~~~想我了吗?有任何问题,请电话骚扰我们的客服哦,客服电话:xxx \ue032");
			} else if (messsgeContent.indexOf("好买酒") != -1 || messsgeContent.indexOf("好卖酒") != -1
					|| messsgeContent.indexOf("酒") != -1) {
				// textMsg.setContent("呀呀,你是“好买酒”过来的吧?路途遥远,辛苦啦\ue056
				// \n即日起,扫描上方二维码实名注册xxx,即可享受5000元体验金\ue106+80元现金红包\ue106+20%加息券\ue106“三重好礼”大礼包,机不可失,失不再来,快去完成注册吧\ue056");

				XStream xStream = new XStream();
				xStream.alias("xml", imagemsg.getClass());
				String imagemsgXml = xStream.toXML(imagemsg);
				System.out.println("回复图片的xml====" + imagemsgXml);
				PrintWriter printWriter = resp.getWriter();
				printWriter.print(imagemsgXml);
				issend = true;
			} else {
				textMsg.setContent(
						"憋~着~急~哈~\ue415你的消息,小编我已收到,容我慢慢回复哈~\ue056有问题最好还是找我们的客服妹子哈,xxx,人家可比我这个整天只知道码字送积分的小编专业滴多哈~~~\ue409");
			}
		}

		XStream xStream = new XStream();
		xStream.alias("xml", textMsg.getClass());
		String textMsg2Xml = xStream.toXML(textMsg);
		System.out.println("返回给微信服务器,让其发送用户消息的报文====" + textMsg2Xml);

		// 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
		// 除了这个,已关注再扫描的事件
		if (!event.equals("SCAN")) {
			PrintWriter printWriter = resp.getWriter();
			printWriter.print(textMsg2Xml);
			System.out.println("======文本发送了============");

		}

		if (issend) {
			/**
			 * 发送客服文本消息
			 */
			// 第一步 获取accesstoken
			String accesstoken = "";
			Date date1 = new Date();
			Date date2 = new Date();
			Weixincommoninfo selectaccesstoken = weixincommoInfoservice.selectInfo();
			// 查看是否有accesstoken
			if (selectaccesstoken == null) {

				selectaccesstoken = new Weixincommoninfo();
				WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken();
				accesstoken = weiXinAccessToken.getAccessToken();
				selectaccesstoken.setSavefiled("accesstoken");
				selectaccesstoken.setSaveinfo(accesstoken);
				selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn());
				selectaccesstoken.setCreatetime(date1);
				date2.setHours(date1.getHours() + 1);// 此处将accesstoken的有效期,设置为1小时
				selectaccesstoken.setEffectivetime(date2);
				weixincommoInfoservice.Saveinfo(selectaccesstoken);

			} else {
				Date date = new Date();
				// 判断当前时间是否在accesstoken 的有效期内,
				Date effectivetime = selectaccesstoken.getEffectivetime();
				if (effectivetime.getTime() > date.getTime()) {
					accesstoken = selectaccesstoken.getSaveinfo();
					System.out.println("数据库中的accesstoken能用");
				} else {
					WeixinToken weiXinAccessToken = WeiXinAccessTokenUtil.getWeiXinAccessToken();
					selectaccesstoken = new Weixincommoninfo();
					accesstoken = weiXinAccessToken.getAccessToken();
					selectaccesstoken.setSavefiled("accesstoken");
					selectaccesstoken.setSaveinfo(accesstoken);
					selectaccesstoken.setExpiresIn(weiXinAccessToken.getExpiresIn());
					selectaccesstoken.setCreatetime(date1);
					date2.setHours(date1.getHours() + 1);
					selectaccesstoken.setEffectivetime(date2);
					weixincommoInfoservice.upadateInfo(selectaccesstoken);
					System.out.println("数据库中的accesstoken不呢能用,重新获取更新");
				}
			}

			// 第二步发送消息
			System.out.println("发送客服消息=======================");
			String mescont = "呀呀,你是“好买酒”过来的吧?路途遥远,辛苦啦\ue056 \n即日起,扫描下方二维码实名注册xxx,即可享受5000元体验金\ue106+80元现金红包\ue106+20%加息券\ue106“三重好礼”大礼包,机不可失,失不再来,快去完成注册吧\ue056";
			WeixinUtil.SendCustomerTextMessage(accesstoken, FromUserName, mescont);
		}

	}

猜你喜欢

转载自my.oschina.net/u/2543341/blog/2885275