微信

微信

【微信公众平台改版后】Java模拟登录微信平台,主动推送消息给用户

企业开发atool 发表了文章 • 2 个评论 • 1267 次浏览 • 2016-04-22 13:08 • 来自相关话题

一、简要说明

在博文《Java模拟登录微信公众平台,主动推送图文消息给用户》中提到使用Java语言登录微信公众平台,然后发送图文消息给用户,基本可以符合使用要求,但是在今年10月23日,微信公众平台的界面有所变化,所以,上一篇博文的代码不再适用,很多朋友留言,不能使用了怎么办,这篇文章针对新版本做了处理,并且加入了新的功能,代码上要感谢trprebel这位朋友。

再备注:如果遇到获取粉丝返回-1的问题,有需要的给这个网友发邮件。 yyn_0210@sina.com

二、代码功能和要求

*.new Weixin()对象,先登录再取粉丝数和者发消息;
*.发消息需要设置post参数中的content;
*.内容中的超链接可以直接发送不用使用标签;
*.经过我(trprebel)修改之后,此份代码可在2013年11月之后使用;
*.我只做了获取粉丝列表和发送消息,其他部分未做;
*.理论上可以获取到粉丝的地址,签名等一切你登陆可以得到的信息;
*.另外可能需要你在本机先登陆过至少一次微信公众平台获取SSL证书;
*.此份代码作者较多,函数前面都有作者名,我只修改了登陆,获取粉丝列表和发送消息;
*.其他代码可能已经不能用了但我并没有删除,方便大家扩展,我做的也比较粗糙,没整理;
*.另外,腾讯3天之内又加了一条限制,粉丝24小时之内没有主动说话,微信公众平台不能主动与其说话,官方平台登陆也不行;

使用到的库:commons-codec-1.3.jar、commons-httpclient-3.1.jar、commons-lang.jar、commons-logging-1.0.4.jar、fastjson-1.1.15.jar、gson-2.2.4.jar、httpclient-4.1.3.jar、httpcore-4.1.4.jar、jsoup-1.5.2.jar

环境:JDK1.6

三、代码下载

使用的库请自己下载,源代码如下附件,如果使用有任何的问题,请直接回复博文即可...

四、核心代码和说明

Weixin.java模拟请求的链接及结构
public final static String HOST = "http://mp.weixin.qq.com";
public final static String LOGIN_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String INDEX_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SENDMSG_URL = "https://mp.weixin.qq.com/cgi-bin/singlesend";
public final static String FANS_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String LOGOUT_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DOWNLOAD_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String VERIFY_CODE = "http://mp.weixin.qq.com/cgi-bin/verifycode?";
public final static String POST_MSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String VIEW_HEAD_IMG = "http://mp.weixin.qq.com/cgi-bin/viewheadimg";
public final static String GET_IMG_DATA = "http://mp.weixin.qq.com/cgi-bin/getimgdata";
public final static String GET_REGIONS = "http://mp.weixin.qq.com/cgi-bin/getregions";
public final static String GET_MESSAGE = "http://mp.weixin.qq.com/cgi-bin/getmessage";
public final static String OPER_ADVANCED_FUNC = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String MASSSEND_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String FILE_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPERATE_APPMSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String FMS_TRANSPORT = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
// public final static String CONTACT_MANAGE_PAGE =
// "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String CONTACT_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPER_SELF_MENU = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String REPLY_RULE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SINGLE_MSG_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String USER_INFO_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DEV_APPLY = "http://mp.weixin.qq.com/cgi-bin/devapply";
public final static String UPLOAD_MATERIAL = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
/**
* 登录,登录失败会重复请求登录
*/
public void login() {}
/**
* 发送登录信息,记录cookie,登录状态,token等信息
*/
private boolean _login() {}
/**
* 从登录成功的信息中分离出token信息
*/
private String getToken(String s) {}
/**
* 获取首页
* @throws HttpException
* @throws IOException
*/
public void index() throws HttpException, IOException {}
/**
* 登出操作
* @throws HttpException
* @throws IOException
*/
public void logout() throws HttpException, IOException {}
/**
* 获取验证码
* @throws HttpException
* @throws IOException
*/
public InputStream code() throws HttpException, IOException {}
/**
* 获取粉丝列表,返回粉丝数量,出错则返回-1
*/
public int getFans() {}
/**
* 从返回文本中提取粉丝数量
*/
private int parseFansCount(String text) {}
/**
* 解析粉丝列表,将粉丝列表存入List<fan>
*/
private int parseFans(String text) {}
/**
* <strong>群发消息</strong>
* 返回码说明
* 0:发送成功
* 64004:今天的群发数量已到,无法群发
* -20000:请求被禁止,请仔细检查token是否合法
* 可通过msgSendCode取得发送状态码
*/
public boolean msgSend(MsgForm form, MsgType type) {}
/**
* 向粉丝发送消息,默认发送第二个粉丝,想不受限制的群发可以循环向粉丝列表中的粉丝发送消息
*/
public boolean sendMsg(int i) {}
public void updateImg(ImgFileForm form) {}
/**
* 页面跳转
*/
public void redirect(String url) {}
//使用样例说明
public static void main(String[] args) {
String LOGIN_USER = "knight.ding@gmail.com"; // 此为上一任作者的用户名和密码,截止到我最后用发现还能用
String LOGIN_PWD = "AAbb1122";
Weixin wx = new Weixin(LOGIN_USER, LOGIN_PWD);
wx.login();
wx.getCookiestr();
// ImgFileForm form = new ImgFileForm();
// form.setUploadfile(new File("D:Dataimage4.jpg"));
// wx.updateImg(form);
System.out.println("粉丝数:" + wx.getFans());
wx.sendMsg(1);// 像好友列表中的第几个好友发消息,从0开始
}
Enjoy~~~如果能帮助到你,请回复博文或者分享给他人,谢谢~ 查看全部
一、简要说明

在博文《Java模拟登录微信公众平台,主动推送图文消息给用户》中提到使用Java语言登录微信公众平台,然后发送图文消息给用户,基本可以符合使用要求,但是在今年10月23日,微信公众平台的界面有所变化,所以,上一篇博文的代码不再适用,很多朋友留言,不能使用了怎么办,这篇文章针对新版本做了处理,并且加入了新的功能,代码上要感谢trprebel这位朋友。

再备注:如果遇到获取粉丝返回-1的问题,有需要的给这个网友发邮件。 yyn_0210@sina.com

二、代码功能和要求

*.new Weixin()对象,先登录再取粉丝数和者发消息;
*.发消息需要设置post参数中的content;
*.内容中的超链接可以直接发送不用使用标签;
*.经过我(trprebel)修改之后,此份代码可在2013年11月之后使用;
*.我只做了获取粉丝列表和发送消息,其他部分未做;
*.理论上可以获取到粉丝的地址,签名等一切你登陆可以得到的信息;
*.另外可能需要你在本机先登陆过至少一次微信公众平台获取SSL证书;
*.此份代码作者较多,函数前面都有作者名,我只修改了登陆,获取粉丝列表和发送消息;
*.其他代码可能已经不能用了但我并没有删除,方便大家扩展,我做的也比较粗糙,没整理;
*.另外,腾讯3天之内又加了一条限制,粉丝24小时之内没有主动说话,微信公众平台不能主动与其说话,官方平台登陆也不行;

使用到的库:commons-codec-1.3.jar、commons-httpclient-3.1.jar、commons-lang.jar、commons-logging-1.0.4.jar、fastjson-1.1.15.jar、gson-2.2.4.jar、httpclient-4.1.3.jar、httpcore-4.1.4.jar、jsoup-1.5.2.jar

环境:JDK1.6

三、代码下载

使用的库请自己下载,源代码如下附件,如果使用有任何的问题,请直接回复博文即可...

四、核心代码和说明

Weixin.java模拟请求的链接及结构
public final static String HOST = "http://mp.weixin.qq.com";
public final static String LOGIN_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String INDEX_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SENDMSG_URL = "https://mp.weixin.qq.com/cgi-bin/singlesend";
public final static String FANS_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String LOGOUT_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DOWNLOAD_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String VERIFY_CODE = "http://mp.weixin.qq.com/cgi-bin/verifycode?";
public final static String POST_MSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String VIEW_HEAD_IMG = "http://mp.weixin.qq.com/cgi-bin/viewheadimg";
public final static String GET_IMG_DATA = "http://mp.weixin.qq.com/cgi-bin/getimgdata";
public final static String GET_REGIONS = "http://mp.weixin.qq.com/cgi-bin/getregions";
public final static String GET_MESSAGE = "http://mp.weixin.qq.com/cgi-bin/getmessage";
public final static String OPER_ADVANCED_FUNC = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String MASSSEND_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String FILE_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPERATE_APPMSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String FMS_TRANSPORT = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
// public final static String CONTACT_MANAGE_PAGE =
// "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String CONTACT_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPER_SELF_MENU = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String REPLY_RULE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SINGLE_MSG_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String USER_INFO_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DEV_APPLY = "http://mp.weixin.qq.com/cgi-bin/devapply";
public final static String UPLOAD_MATERIAL = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
/**
* 登录,登录失败会重复请求登录
*/
public void login() {}
/**
* 发送登录信息,记录cookie,登录状态,token等信息
*/
private boolean _login() {}
/**
* 从登录成功的信息中分离出token信息
*/
private String getToken(String s) {}
/**
* 获取首页
* @throws HttpException
* @throws IOException
*/
public void index() throws HttpException, IOException {}
/**
* 登出操作
* @throws HttpException
* @throws IOException
*/
public void logout() throws HttpException, IOException {}
/**
* 获取验证码
* @throws HttpException
* @throws IOException
*/
public InputStream code() throws HttpException, IOException {}
/**
* 获取粉丝列表,返回粉丝数量,出错则返回-1
*/
public int getFans() {}
/**
* 从返回文本中提取粉丝数量
*/
private int parseFansCount(String text) {}
/**
* 解析粉丝列表,将粉丝列表存入List<fan>
*/
private int parseFans(String text) {}
/**
* <strong>群发消息</strong>
* 返回码说明
* 0:发送成功
* 64004:今天的群发数量已到,无法群发
* -20000:请求被禁止,请仔细检查token是否合法
* 可通过msgSendCode取得发送状态码
*/
public boolean msgSend(MsgForm form, MsgType type) {}
/**
* 向粉丝发送消息,默认发送第二个粉丝,想不受限制的群发可以循环向粉丝列表中的粉丝发送消息
*/
public boolean sendMsg(int i) {}
public void updateImg(ImgFileForm form) {}
/**
* 页面跳转
*/
public void redirect(String url) {}
//使用样例说明
public static void main(String[] args) {
String LOGIN_USER = "knight.ding@gmail.com"; // 此为上一任作者的用户名和密码,截止到我最后用发现还能用
String LOGIN_PWD = "AAbb1122";
Weixin wx = new Weixin(LOGIN_USER, LOGIN_PWD);
wx.login();
wx.getCookiestr();
// ImgFileForm form = new ImgFileForm();
// form.setUploadfile(new File("D:Dataimage4.jpg"));
// wx.updateImg(form);
System.out.println("粉丝数:" + wx.getFans());
wx.sendMsg(1);// 像好友列表中的第几个好友发消息,从0开始
}
Enjoy~~~如果能帮助到你,请回复博文或者分享给他人,谢谢~

使用Java给微信公众号创建自定义的菜单

编程语言atool 发表了文章 • 0 个评论 • 1214 次浏览 • 2016-04-22 12:53 • 来自相关话题

最近一段时间,微信公众平台做了很多的改进啊~

微信目前将公众帐号分成服务号和订阅号两种,之前的微信公众号默认为订阅号,不过有一次机会可以自由选择,两者之间各有优劣:

服务号每月只能推送一条消息,不过消息是显示在消息列表中,并有消息提示;订阅号每天有一条消息推送,不过消息不显示在消息列表,没有消息提示。

除此之外,目前微信公众号可以自定义菜单,下面将介绍如果使用Java作一个微信公众号的菜单,参考API可到官网查看:http://mp.weixin.qq.com/wiki/index.php?title=%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95%E6%8E%A5%E5%8F%A3
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.json.JSONObject;

public class MenuUtil {
/**
* 获得ACCESS_TOKEN
* @Title: getAccess_token
* @Description: 获得ACCESS_TOKEN
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
private static String getAccess_token(){

String APPID="";
String APPSECRET="";

String url = "https://api.weixin.qq.com/cgi- ... 3B%2B APPID + "&secret=" +APPSECRET;
String accessToken = null;
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();

http.setRequestMethod("GET"); //必须是get方式请求
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");

JSONObject demoJson = new JSONObject(message);
accessToken = demoJson.getString("access_token");

System.out.println(message);
} catch (Exception e) {
e.printStackTrace();
}
return accessToken;
}

/**
* 创建Menu
* @Title: createMenu
* @Description: 创建Menu
* @param @return
* @param @throws IOException 设定文件
* @return int 返回类型
* @throws
*/
public static String createMenu() {
String menu = "{\"button\":[{\"type\":\"click\",\"name\":\"MENU01\",\"key\":\"1\"},{\"type\":\"click\",\"name\":\"天气查询\",\"key\":\"西安\"},{\"name\":\"日常工作\",\"sub_button\":[{\"type\":\"click\",\"name\":\"待办工单\",\"key\":\"01_WAITING\"},{\"type\":\"click\",\"name\":\"已办工单\",\"key\":\"02_FINISH\"},{\"type\":\"click\",\"name\":\"我的工单\",\"key\":\"03_MYJOB\"},{\"type\":\"click\",\"name\":\"公告消息箱\",\"key\":\"04_MESSAGEBOX\"},{\"type\":\"click\",\"name\":\"签到\",\"key\":\"05_SIGN\"}]}]}";

//此处改为自己想要的结构体,替换即可
String access_token= getAccess_token();

String action = "https://api.weixin.qq.com/cgi- ... en%3B
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("POST");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.write(menu.getBytes("UTF-8"));//传入参数
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "返回信息"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "createMenu 失败";
}

/**
* 删除当前Menu
* @Title: deleteMenu
* @Description: 删除当前Menu
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String deleteMenu()
{
String access_token= getAccess_token();
String action = "https://api.weixin.qq.com/cgi-bin/menu/delete? access_token="+access_token;
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("GET");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "deleteMenu返回信息:"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "deleteMenu 失败";
}

public static void main(String[] args) {
System.out.println(createMenu());
}
}代码来源于:http://www.oschina.net/code/snippet_945711_24355 ,后续会做PHP版,并加入到自己的微信公众号上面,我的微信公众号二维码见右侧。Enjoy~ 查看全部
最近一段时间,微信公众平台做了很多的改进啊~

微信目前将公众帐号分成服务号和订阅号两种,之前的微信公众号默认为订阅号,不过有一次机会可以自由选择,两者之间各有优劣:

服务号每月只能推送一条消息,不过消息是显示在消息列表中,并有消息提示;订阅号每天有一条消息推送,不过消息不显示在消息列表,没有消息提示。

除此之外,目前微信公众号可以自定义菜单,下面将介绍如果使用Java作一个微信公众号的菜单,参考API可到官网查看:http://mp.weixin.qq.com/wiki/index.php?title=%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95%E6%8E%A5%E5%8F%A3
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.json.JSONObject;

public class MenuUtil {
/**
* 获得ACCESS_TOKEN
* @Title: getAccess_token
* @Description: 获得ACCESS_TOKEN
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
private static String getAccess_token(){

String APPID="";
String APPSECRET="";

String url = "https://api.weixin.qq.com/cgi- ... 3B%2B APPID + "&secret=" +APPSECRET;
String accessToken = null;
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();

http.setRequestMethod("GET"); //必须是get方式请求
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");

JSONObject demoJson = new JSONObject(message);
accessToken = demoJson.getString("access_token");

System.out.println(message);
} catch (Exception e) {
e.printStackTrace();
}
return accessToken;
}

/**
* 创建Menu
* @Title: createMenu
* @Description: 创建Menu
* @param @return
* @param @throws IOException 设定文件
* @return int 返回类型
* @throws
*/
public static String createMenu() {
String menu = "{\"button\":[{\"type\":\"click\",\"name\":\"MENU01\",\"key\":\"1\"},{\"type\":\"click\",\"name\":\"天气查询\",\"key\":\"西安\"},{\"name\":\"日常工作\",\"sub_button\":[{\"type\":\"click\",\"name\":\"待办工单\",\"key\":\"01_WAITING\"},{\"type\":\"click\",\"name\":\"已办工单\",\"key\":\"02_FINISH\"},{\"type\":\"click\",\"name\":\"我的工单\",\"key\":\"03_MYJOB\"},{\"type\":\"click\",\"name\":\"公告消息箱\",\"key\":\"04_MESSAGEBOX\"},{\"type\":\"click\",\"name\":\"签到\",\"key\":\"05_SIGN\"}]}]}";

//此处改为自己想要的结构体,替换即可
String access_token= getAccess_token();

String action = "https://api.weixin.qq.com/cgi- ... en%3B
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("POST");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.write(menu.getBytes("UTF-8"));//传入参数
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "返回信息"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "createMenu 失败";
}

/**
* 删除当前Menu
* @Title: deleteMenu
* @Description: 删除当前Menu
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String deleteMenu()
{
String access_token= getAccess_token();
String action = "https://api.weixin.qq.com/cgi-bin/menu/delete? access_token="+access_token;
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("GET");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "deleteMenu返回信息:"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "deleteMenu 失败";
}

public static void main(String[] args) {
System.out.println(createMenu());
}
}
代码来源于:http://www.oschina.net/code/snippet_945711_24355 ,后续会做PHP版,并加入到自己的微信公众号上面,我的微信公众号二维码见右侧。Enjoy~

Java模拟登录微信公众平台,主动推送图文消息给用户

服务端atool 发表了文章 • 0 个评论 • 1186 次浏览 • 2016-04-22 11:37 • 来自相关话题

@2013-11-25,对博文进行说明,由于2013年10月底,微信公众平台界面完全改版,所以本博文的所有代码几乎全部不能使用,不过有网友对本博的代码进行修改并授权于我共享给大家,因此大家可以去看博文《【微信公众平台改版后】Java模拟登录微信平台,主动推送消息给用户》,本博文的思路,大家也可以看看进行参考。

很早之前,在博客中发表了关于使用java开发微信公众号接口的程序代码,详细见《微信公众号消息接口开发——Java Servlet开发》,例外利用java做了小黄鸡,小i机器人的微信聊天开发,所以之前很多人问我有关于java开发微信接口的东西~

除此之外,更重要的是:很多人还问我关于微信主动推送消息给用户的问题,我所给出的所有答案都是:微信官方没有给出主动推送的api,所有采用程序记录用户微信id,然后模拟微信接口的请求数据,去请求微信接口中设置的url,这些方法都是不可行的~

不过,要实现主动推送不是不可能的,最简单的一个思路就是使用java模拟登录微信公众平台,然后推送消息消息给用户,不过这种方式有推送限制。

由于问的人比较多,决定把代码放出来,代码还未整理,里面有解析数据可以用正则表达式替换也没做,有需要的可以自己在此基础上修改。如果你觉得有用,并帮助了你,感谢你对我的赞助和支持。
public boolean msgSend(MsgForm form, MsgType type) {
try {
if (!this.isLogin) {
this._login();
}
if (this.isLogin) {
form.setToken(this.token);
PostMethod post = new PostMethod(POST_MSG);
post.setRequestHeader(USER_AGENT_H, USER_AGENT);
post.setRequestHeader(REFERER_H, INDEX_URL);
post.setRequestHeader("Cookie", this.cookiestr);
NameValuePair[] params = null;
Part[] parts = null;
switch (type) {
case TEXT:

parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
case IMAGE_TEXT:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
default:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
}
RequestEntity entity = new MultipartRequestEntity(parts,
post.getParams());
post.setRequestEntity(entity);
int status;
status = client.executeMethod(post);
if (status == HttpStatus.SC_OK) {
String text = post.getResponseBodyAsString();
try {
MsgJson ret = JSON.parseObject(text, MsgJson.class);
this.msgSendCode = ret.getRet();
switch (this.msgSendCode) {
case 0:
this.msgSendMsg = "发送成功";
return true;
case -2:
this.msgSendMsg = "参数错误,请仔细检查";
return false;
case 64004:
this.msgSendMsg = "今天的群发数量已到,无法群发";
return false;
case -20000:
this.msgSendMsg = "请求被禁止,请仔细检查token是否合法";
return false;
default:
this.msgSendMsg = "未知错误!";
return false;
}
} catch (Exception e) {
String info = "【群发信息失败】【解析json错误】" + e.getMessage()
+ "
【文本:】
" + text;
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
}
}
} catch (Exception e) {
String info = "【群发信息失败】" + e.getMessage();
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
return false;
} 查看全部
@2013-11-25,对博文进行说明,由于2013年10月底,微信公众平台界面完全改版,所以本博文的所有代码几乎全部不能使用,不过有网友对本博的代码进行修改并授权于我共享给大家,因此大家可以去看博文《【微信公众平台改版后】Java模拟登录微信平台,主动推送消息给用户》,本博文的思路,大家也可以看看进行参考。

很早之前,在博客中发表了关于使用java开发微信公众号接口的程序代码,详细见《微信公众号消息接口开发——Java Servlet开发》,例外利用java做了小黄鸡,小i机器人的微信聊天开发,所以之前很多人问我有关于java开发微信接口的东西~

除此之外,更重要的是:很多人还问我关于微信主动推送消息给用户的问题,我所给出的所有答案都是:微信官方没有给出主动推送的api,所有采用程序记录用户微信id,然后模拟微信接口的请求数据,去请求微信接口中设置的url,这些方法都是不可行的~

不过,要实现主动推送不是不可能的,最简单的一个思路就是使用java模拟登录微信公众平台,然后推送消息消息给用户,不过这种方式有推送限制。

由于问的人比较多,决定把代码放出来,代码还未整理,里面有解析数据可以用正则表达式替换也没做,有需要的可以自己在此基础上修改。如果你觉得有用,并帮助了你,感谢你对我的赞助和支持。
public boolean msgSend(MsgForm form, MsgType type) {
try {
if (!this.isLogin) {
this._login();
}
if (this.isLogin) {
form.setToken(this.token);
PostMethod post = new PostMethod(POST_MSG);
post.setRequestHeader(USER_AGENT_H, USER_AGENT);
post.setRequestHeader(REFERER_H, INDEX_URL);
post.setRequestHeader("Cookie", this.cookiestr);
NameValuePair[] params = null;
Part[] parts = null;
switch (type) {
case TEXT:

parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
case IMAGE_TEXT:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
default:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
}
RequestEntity entity = new MultipartRequestEntity(parts,
post.getParams());
post.setRequestEntity(entity);
int status;
status = client.executeMethod(post);
if (status == HttpStatus.SC_OK) {
String text = post.getResponseBodyAsString();
try {
MsgJson ret = JSON.parseObject(text, MsgJson.class);
this.msgSendCode = ret.getRet();
switch (this.msgSendCode) {
case 0:
this.msgSendMsg = "发送成功";
return true;
case -2:
this.msgSendMsg = "参数错误,请仔细检查";
return false;
case 64004:
this.msgSendMsg = "今天的群发数量已到,无法群发";
return false;
case -20000:
this.msgSendMsg = "请求被禁止,请仔细检查token是否合法";
return false;
default:
this.msgSendMsg = "未知错误!";
return false;
}
} catch (Exception e) {
String info = "【群发信息失败】【解析json错误】" + e.getMessage()
+ "
【文本:】
" + text;
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
}
}
} catch (Exception e) {
String info = "【群发信息失败】" + e.getMessage();
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
return false;
}

微信公众号消息接口开发——Java Servlet开发

编程语言atool 发表了文章 • 0 个评论 • 1100 次浏览 • 2016-04-22 11:02 • 来自相关话题

张小龙搞出来的微信真的很牛逼啊,短短两三年就2亿用户量,这个数据似乎在警告QQ部门,IM软件上,你们QQ的老大位置并不稳固,仍需努力。当然QQ和微信不是一个平台上的产品,并不存在很大的竞争问题。

微信公众号消息接口API只有相当于只有一个简单调用链接,但是却完全改变了最初微信公众号的概念。不过说实话,这个接口真的设计的不怎么的...验证过程个字符处理啊,加密啊,拼接啊毫无用处,在申请页面填写的token也毫无用处,这些都是题外话了。不管这个接口腾讯设计得好不好,我们需要关心的是我们利用这个接口能够做什么,怎么做?

废话少说,言归正传,微信官网给我们提供了PHP的例子,所以做PHP的同学只需要画瓢即可,对于Java平台,网上还没有人说起,欲知Java平台怎么开发微信公众号接口,请看下文:

下面列出使用Java Servlet开发的一个简单的微信公众号接口调用的例子,如果有疑问,可以参见我本博的微信公众号:红色石头。

另外,我想大家一定很想知道《模拟登录微信公众平台,主动推送图文消息给用户》的有关信息。点开即可看到了~~~




 
package com.wzwcxl.pubwx.hustac.pubwx;

import java.io.IOException;
import java.io.InputStream;

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

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.wzwcxl.pubwx.hustac.util.StringUtil;

/**
* 微信公众号接口调用Java版
* @author Xewee.Zhiwei.Wang
* @version 2012-12-17 上午9:16:02
* @Contract wzwahl36@QQ.com or http://wzwahl36.net/
*/
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
// response.getWriter().write(request.getParameter("echostr"));
doPost(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------post---------------");
try {
InputStream is = request.getInputStream();
// 取HTTP请求流长度
int size = request.getContentLength();
// 用于缓存每次读取的数据
byte[] buffer = new byte[size];
// 用于存放结果的数组
byte[] xmldataByte = new byte[size];
int count = 0;
int rbyte = 0;
// 循环读取
while (count < size) {
// 每次实际读取长度存于rbyte中
rbyte = is.read(buffer);
for(int i=0;i<rbyte;i++) {
xmldataByte[count + i] = buffer[i];
}
count += rbyte;
}
is.close();
String requestStr = new String(xmldataByte, "UTF-8");
Document doc = DocumentHelper.parseText(requestStr);
Element rootElt = doc.getRootElement();
String content = rootElt.elementText("Content");
String toUserName = rootElt.elementText("ToUserName");
String fromUserName = rootElt.elementText("FromUserName");
//得到所有的有用数据
System.out.println(content+ ":" + toUserName + ":" + fromUserName);
//文本消息
if (! StringUtil.isBlank(content) && "text".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//图文消息
else if (! StringUtil.isBlank(content) && "news".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[news]]></MsgType>";
responseStr += "<Content><![CDATA[]]></Content>";

responseStr += "<ArticleCount>2</ArticleCount>";

responseStr += "<Articles>";
responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "</Articles>";
responseStr += "<FuncFlag>1</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//不能识别
else {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}

} catch (Exception e) {
e.printStackTrace();
}
}
}需要注意是一点是:在验证链接时,将get方法写为以下:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
response.getWriter().write(request.getParameter("echostr"));
// doPost(request, response);
}
验证通过之后,将get方法和post方法写成一样的。
另外注意servlet的编码问题,我这个servlet里面没有写编码是因为我设置了编码过滤器:
package com.wzwcxl.pubwx.hustac.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
* Servlet Filter implementation class EncodingFilter
*/
public class EncodingFilter implements Filter {

/**
* Default constructor.
*/
public EncodingFilter() {
// TODO Auto-generated constructor stub
}

/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}

/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
System.out.println("EncodingFilter: UTF-8");

chain.doFilter(request, response);
}

/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}附加:很多人问到代码中的StringUtil类中的isBlank方法是什么?然后要我发给他,其实StringUtil只有isBlank方法,这个方法就是用来判断字符串是不是空,所谓字符串为空,就是等于null或者trim之后为"",每次问到这个我都不知道怎么回答,所以在这里附加说明一下~

Enjoy~有空点点广告,感谢~~~ 查看全部
张小龙搞出来的微信真的很牛逼啊,短短两三年就2亿用户量,这个数据似乎在警告QQ部门,IM软件上,你们QQ的老大位置并不稳固,仍需努力。当然QQ和微信不是一个平台上的产品,并不存在很大的竞争问题。

微信公众号消息接口API只有相当于只有一个简单调用链接,但是却完全改变了最初微信公众号的概念。不过说实话,这个接口真的设计的不怎么的...验证过程个字符处理啊,加密啊,拼接啊毫无用处,在申请页面填写的token也毫无用处,这些都是题外话了。不管这个接口腾讯设计得好不好,我们需要关心的是我们利用这个接口能够做什么,怎么做?

废话少说,言归正传,微信官网给我们提供了PHP的例子,所以做PHP的同学只需要画瓢即可,对于Java平台,网上还没有人说起,欲知Java平台怎么开发微信公众号接口,请看下文:

下面列出使用Java Servlet开发的一个简单的微信公众号接口调用的例子,如果有疑问,可以参见我本博的微信公众号:红色石头。

另外,我想大家一定很想知道《模拟登录微信公众平台,主动推送图文消息给用户》的有关信息。点开即可看到了~~~
redstones_wx_430.jpg

 
package com.wzwcxl.pubwx.hustac.pubwx;

import java.io.IOException;
import java.io.InputStream;

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

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.wzwcxl.pubwx.hustac.util.StringUtil;

/**
* 微信公众号接口调用Java版
* @author Xewee.Zhiwei.Wang
* @version 2012-12-17 上午9:16:02
* @Contract wzwahl36@QQ.com or http://wzwahl36.net/
*/
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
// response.getWriter().write(request.getParameter("echostr"));
doPost(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------post---------------");
try {
InputStream is = request.getInputStream();
// 取HTTP请求流长度
int size = request.getContentLength();
// 用于缓存每次读取的数据
byte[] buffer = new byte[size];
// 用于存放结果的数组
byte[] xmldataByte = new byte[size];
int count = 0;
int rbyte = 0;
// 循环读取
while (count < size) {
// 每次实际读取长度存于rbyte中
rbyte = is.read(buffer);
for(int i=0;i<rbyte;i++) {
xmldataByte[count + i] = buffer[i];
}
count += rbyte;
}
is.close();
String requestStr = new String(xmldataByte, "UTF-8");
Document doc = DocumentHelper.parseText(requestStr);
Element rootElt = doc.getRootElement();
String content = rootElt.elementText("Content");
String toUserName = rootElt.elementText("ToUserName");
String fromUserName = rootElt.elementText("FromUserName");
//得到所有的有用数据
System.out.println(content+ ":" + toUserName + ":" + fromUserName);
//文本消息
if (! StringUtil.isBlank(content) && "text".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//图文消息
else if (! StringUtil.isBlank(content) && "news".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[news]]></MsgType>";
responseStr += "<Content><![CDATA[]]></Content>";

responseStr += "<ArticleCount>2</ArticleCount>";

responseStr += "<Articles>";
responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "</Articles>";
responseStr += "<FuncFlag>1</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//不能识别
else {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}

} catch (Exception e) {
e.printStackTrace();
}
}
}
需要注意是一点是:在验证链接时,将get方法写为以下:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
response.getWriter().write(request.getParameter("echostr"));
// doPost(request, response);
}
验证通过之后,将get方法和post方法写成一样的。
另外注意servlet的编码问题,我这个servlet里面没有写编码是因为我设置了编码过滤器:
package com.wzwcxl.pubwx.hustac.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
* Servlet Filter implementation class EncodingFilter
*/
public class EncodingFilter implements Filter {

/**
* Default constructor.
*/
public EncodingFilter() {
// TODO Auto-generated constructor stub
}

/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}

/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
System.out.println("EncodingFilter: UTF-8");

chain.doFilter(request, response);
}

/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
附加:很多人问到代码中的StringUtil类中的isBlank方法是什么?然后要我发给他,其实StringUtil只有isBlank方法,这个方法就是用来判断字符串是不是空,所谓字符串为空,就是等于null或者trim之后为"",每次问到这个我都不知道怎么回答,所以在这里附加说明一下~

Enjoy~有空点点广告,感谢~~~

【微信公众平台改版后】Java模拟登录微信平台,主动推送消息给用户

企业开发atool 发表了文章 • 2 个评论 • 1267 次浏览 • 2016-04-22 13:08 • 来自相关话题

一、简要说明

在博文《Java模拟登录微信公众平台,主动推送图文消息给用户》中提到使用Java语言登录微信公众平台,然后发送图文消息给用户,基本可以符合使用要求,但是在今年10月23日,微信公众平台的界面有所变化,所以,上一篇博文的代码不再适用,很多朋友留言,不能使用了怎么办,这篇文章针对新版本做了处理,并且加入了新的功能,代码上要感谢trprebel这位朋友。

再备注:如果遇到获取粉丝返回-1的问题,有需要的给这个网友发邮件。 yyn_0210@sina.com

二、代码功能和要求

*.new Weixin()对象,先登录再取粉丝数和者发消息;
*.发消息需要设置post参数中的content;
*.内容中的超链接可以直接发送不用使用标签;
*.经过我(trprebel)修改之后,此份代码可在2013年11月之后使用;
*.我只做了获取粉丝列表和发送消息,其他部分未做;
*.理论上可以获取到粉丝的地址,签名等一切你登陆可以得到的信息;
*.另外可能需要你在本机先登陆过至少一次微信公众平台获取SSL证书;
*.此份代码作者较多,函数前面都有作者名,我只修改了登陆,获取粉丝列表和发送消息;
*.其他代码可能已经不能用了但我并没有删除,方便大家扩展,我做的也比较粗糙,没整理;
*.另外,腾讯3天之内又加了一条限制,粉丝24小时之内没有主动说话,微信公众平台不能主动与其说话,官方平台登陆也不行;

使用到的库:commons-codec-1.3.jar、commons-httpclient-3.1.jar、commons-lang.jar、commons-logging-1.0.4.jar、fastjson-1.1.15.jar、gson-2.2.4.jar、httpclient-4.1.3.jar、httpcore-4.1.4.jar、jsoup-1.5.2.jar

环境:JDK1.6

三、代码下载

使用的库请自己下载,源代码如下附件,如果使用有任何的问题,请直接回复博文即可...

四、核心代码和说明

Weixin.java模拟请求的链接及结构
public final static String HOST = "http://mp.weixin.qq.com";
public final static String LOGIN_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String INDEX_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SENDMSG_URL = "https://mp.weixin.qq.com/cgi-bin/singlesend";
public final static String FANS_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String LOGOUT_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DOWNLOAD_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String VERIFY_CODE = "http://mp.weixin.qq.com/cgi-bin/verifycode?";
public final static String POST_MSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String VIEW_HEAD_IMG = "http://mp.weixin.qq.com/cgi-bin/viewheadimg";
public final static String GET_IMG_DATA = "http://mp.weixin.qq.com/cgi-bin/getimgdata";
public final static String GET_REGIONS = "http://mp.weixin.qq.com/cgi-bin/getregions";
public final static String GET_MESSAGE = "http://mp.weixin.qq.com/cgi-bin/getmessage";
public final static String OPER_ADVANCED_FUNC = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String MASSSEND_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String FILE_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPERATE_APPMSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String FMS_TRANSPORT = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
// public final static String CONTACT_MANAGE_PAGE =
// "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String CONTACT_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPER_SELF_MENU = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String REPLY_RULE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SINGLE_MSG_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String USER_INFO_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DEV_APPLY = "http://mp.weixin.qq.com/cgi-bin/devapply";
public final static String UPLOAD_MATERIAL = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
/**
* 登录,登录失败会重复请求登录
*/
public void login() {}
/**
* 发送登录信息,记录cookie,登录状态,token等信息
*/
private boolean _login() {}
/**
* 从登录成功的信息中分离出token信息
*/
private String getToken(String s) {}
/**
* 获取首页
* @throws HttpException
* @throws IOException
*/
public void index() throws HttpException, IOException {}
/**
* 登出操作
* @throws HttpException
* @throws IOException
*/
public void logout() throws HttpException, IOException {}
/**
* 获取验证码
* @throws HttpException
* @throws IOException
*/
public InputStream code() throws HttpException, IOException {}
/**
* 获取粉丝列表,返回粉丝数量,出错则返回-1
*/
public int getFans() {}
/**
* 从返回文本中提取粉丝数量
*/
private int parseFansCount(String text) {}
/**
* 解析粉丝列表,将粉丝列表存入List<fan>
*/
private int parseFans(String text) {}
/**
* <strong>群发消息</strong>
* 返回码说明
* 0:发送成功
* 64004:今天的群发数量已到,无法群发
* -20000:请求被禁止,请仔细检查token是否合法
* 可通过msgSendCode取得发送状态码
*/
public boolean msgSend(MsgForm form, MsgType type) {}
/**
* 向粉丝发送消息,默认发送第二个粉丝,想不受限制的群发可以循环向粉丝列表中的粉丝发送消息
*/
public boolean sendMsg(int i) {}
public void updateImg(ImgFileForm form) {}
/**
* 页面跳转
*/
public void redirect(String url) {}
//使用样例说明
public static void main(String[] args) {
String LOGIN_USER = "knight.ding@gmail.com"; // 此为上一任作者的用户名和密码,截止到我最后用发现还能用
String LOGIN_PWD = "AAbb1122";
Weixin wx = new Weixin(LOGIN_USER, LOGIN_PWD);
wx.login();
wx.getCookiestr();
// ImgFileForm form = new ImgFileForm();
// form.setUploadfile(new File("D:Dataimage4.jpg"));
// wx.updateImg(form);
System.out.println("粉丝数:" + wx.getFans());
wx.sendMsg(1);// 像好友列表中的第几个好友发消息,从0开始
}
Enjoy~~~如果能帮助到你,请回复博文或者分享给他人,谢谢~ 查看全部
一、简要说明

在博文《Java模拟登录微信公众平台,主动推送图文消息给用户》中提到使用Java语言登录微信公众平台,然后发送图文消息给用户,基本可以符合使用要求,但是在今年10月23日,微信公众平台的界面有所变化,所以,上一篇博文的代码不再适用,很多朋友留言,不能使用了怎么办,这篇文章针对新版本做了处理,并且加入了新的功能,代码上要感谢trprebel这位朋友。

再备注:如果遇到获取粉丝返回-1的问题,有需要的给这个网友发邮件。 yyn_0210@sina.com

二、代码功能和要求

*.new Weixin()对象,先登录再取粉丝数和者发消息;
*.发消息需要设置post参数中的content;
*.内容中的超链接可以直接发送不用使用标签;
*.经过我(trprebel)修改之后,此份代码可在2013年11月之后使用;
*.我只做了获取粉丝列表和发送消息,其他部分未做;
*.理论上可以获取到粉丝的地址,签名等一切你登陆可以得到的信息;
*.另外可能需要你在本机先登陆过至少一次微信公众平台获取SSL证书;
*.此份代码作者较多,函数前面都有作者名,我只修改了登陆,获取粉丝列表和发送消息;
*.其他代码可能已经不能用了但我并没有删除,方便大家扩展,我做的也比较粗糙,没整理;
*.另外,腾讯3天之内又加了一条限制,粉丝24小时之内没有主动说话,微信公众平台不能主动与其说话,官方平台登陆也不行;

使用到的库:commons-codec-1.3.jar、commons-httpclient-3.1.jar、commons-lang.jar、commons-logging-1.0.4.jar、fastjson-1.1.15.jar、gson-2.2.4.jar、httpclient-4.1.3.jar、httpcore-4.1.4.jar、jsoup-1.5.2.jar

环境:JDK1.6

三、代码下载

使用的库请自己下载,源代码如下附件,如果使用有任何的问题,请直接回复博文即可...

四、核心代码和说明

Weixin.java模拟请求的链接及结构
public final static String HOST = "http://mp.weixin.qq.com";
public final static String LOGIN_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String INDEX_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SENDMSG_URL = "https://mp.weixin.qq.com/cgi-bin/singlesend";
public final static String FANS_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String LOGOUT_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DOWNLOAD_URL = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String VERIFY_CODE = "http://mp.weixin.qq.com/cgi-bin/verifycode?";
public final static String POST_MSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String VIEW_HEAD_IMG = "http://mp.weixin.qq.com/cgi-bin/viewheadimg";
public final static String GET_IMG_DATA = "http://mp.weixin.qq.com/cgi-bin/getimgdata";
public final static String GET_REGIONS = "http://mp.weixin.qq.com/cgi-bin/getregions";
public final static String GET_MESSAGE = "http://mp.weixin.qq.com/cgi-bin/getmessage";
public final static String OPER_ADVANCED_FUNC = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String MASSSEND_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String FILE_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPERATE_APPMSG = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
public final static String FMS_TRANSPORT = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
// public final static String CONTACT_MANAGE_PAGE =
// "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String CONTACT_MANAGE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String OPER_SELF_MENU = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String REPLY_RULE_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String SINGLE_MSG_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String USER_INFO_PAGE = "http://mp.weixin.qq.com/cgi-bi ... 3B%3B
public final static String DEV_APPLY = "http://mp.weixin.qq.com/cgi-bin/devapply";
public final static String UPLOAD_MATERIAL = "https://mp.weixin.qq.com/cgi-b ... 3B%3B
/**
* 登录,登录失败会重复请求登录
*/
public void login() {}
/**
* 发送登录信息,记录cookie,登录状态,token等信息
*/
private boolean _login() {}
/**
* 从登录成功的信息中分离出token信息
*/
private String getToken(String s) {}
/**
* 获取首页
* @throws HttpException
* @throws IOException
*/
public void index() throws HttpException, IOException {}
/**
* 登出操作
* @throws HttpException
* @throws IOException
*/
public void logout() throws HttpException, IOException {}
/**
* 获取验证码
* @throws HttpException
* @throws IOException
*/
public InputStream code() throws HttpException, IOException {}
/**
* 获取粉丝列表,返回粉丝数量,出错则返回-1
*/
public int getFans() {}
/**
* 从返回文本中提取粉丝数量
*/
private int parseFansCount(String text) {}
/**
* 解析粉丝列表,将粉丝列表存入List<fan>
*/
private int parseFans(String text) {}
/**
* <strong>群发消息</strong>
* 返回码说明
* 0:发送成功
* 64004:今天的群发数量已到,无法群发
* -20000:请求被禁止,请仔细检查token是否合法
* 可通过msgSendCode取得发送状态码
*/
public boolean msgSend(MsgForm form, MsgType type) {}
/**
* 向粉丝发送消息,默认发送第二个粉丝,想不受限制的群发可以循环向粉丝列表中的粉丝发送消息
*/
public boolean sendMsg(int i) {}
public void updateImg(ImgFileForm form) {}
/**
* 页面跳转
*/
public void redirect(String url) {}
//使用样例说明
public static void main(String[] args) {
String LOGIN_USER = "knight.ding@gmail.com"; // 此为上一任作者的用户名和密码,截止到我最后用发现还能用
String LOGIN_PWD = "AAbb1122";
Weixin wx = new Weixin(LOGIN_USER, LOGIN_PWD);
wx.login();
wx.getCookiestr();
// ImgFileForm form = new ImgFileForm();
// form.setUploadfile(new File("D:Dataimage4.jpg"));
// wx.updateImg(form);
System.out.println("粉丝数:" + wx.getFans());
wx.sendMsg(1);// 像好友列表中的第几个好友发消息,从0开始
}
Enjoy~~~如果能帮助到你,请回复博文或者分享给他人,谢谢~

使用Java给微信公众号创建自定义的菜单

编程语言atool 发表了文章 • 0 个评论 • 1214 次浏览 • 2016-04-22 12:53 • 来自相关话题

最近一段时间,微信公众平台做了很多的改进啊~

微信目前将公众帐号分成服务号和订阅号两种,之前的微信公众号默认为订阅号,不过有一次机会可以自由选择,两者之间各有优劣:

服务号每月只能推送一条消息,不过消息是显示在消息列表中,并有消息提示;订阅号每天有一条消息推送,不过消息不显示在消息列表,没有消息提示。

除此之外,目前微信公众号可以自定义菜单,下面将介绍如果使用Java作一个微信公众号的菜单,参考API可到官网查看:http://mp.weixin.qq.com/wiki/index.php?title=%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95%E6%8E%A5%E5%8F%A3
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.json.JSONObject;

public class MenuUtil {
/**
* 获得ACCESS_TOKEN
* @Title: getAccess_token
* @Description: 获得ACCESS_TOKEN
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
private static String getAccess_token(){

String APPID="";
String APPSECRET="";

String url = "https://api.weixin.qq.com/cgi- ... 3B%2B APPID + "&secret=" +APPSECRET;
String accessToken = null;
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();

http.setRequestMethod("GET"); //必须是get方式请求
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");

JSONObject demoJson = new JSONObject(message);
accessToken = demoJson.getString("access_token");

System.out.println(message);
} catch (Exception e) {
e.printStackTrace();
}
return accessToken;
}

/**
* 创建Menu
* @Title: createMenu
* @Description: 创建Menu
* @param @return
* @param @throws IOException 设定文件
* @return int 返回类型
* @throws
*/
public static String createMenu() {
String menu = "{\"button\":[{\"type\":\"click\",\"name\":\"MENU01\",\"key\":\"1\"},{\"type\":\"click\",\"name\":\"天气查询\",\"key\":\"西安\"},{\"name\":\"日常工作\",\"sub_button\":[{\"type\":\"click\",\"name\":\"待办工单\",\"key\":\"01_WAITING\"},{\"type\":\"click\",\"name\":\"已办工单\",\"key\":\"02_FINISH\"},{\"type\":\"click\",\"name\":\"我的工单\",\"key\":\"03_MYJOB\"},{\"type\":\"click\",\"name\":\"公告消息箱\",\"key\":\"04_MESSAGEBOX\"},{\"type\":\"click\",\"name\":\"签到\",\"key\":\"05_SIGN\"}]}]}";

//此处改为自己想要的结构体,替换即可
String access_token= getAccess_token();

String action = "https://api.weixin.qq.com/cgi- ... en%3B
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("POST");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.write(menu.getBytes("UTF-8"));//传入参数
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "返回信息"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "createMenu 失败";
}

/**
* 删除当前Menu
* @Title: deleteMenu
* @Description: 删除当前Menu
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String deleteMenu()
{
String access_token= getAccess_token();
String action = "https://api.weixin.qq.com/cgi-bin/menu/delete? access_token="+access_token;
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("GET");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "deleteMenu返回信息:"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "deleteMenu 失败";
}

public static void main(String[] args) {
System.out.println(createMenu());
}
}代码来源于:http://www.oschina.net/code/snippet_945711_24355 ,后续会做PHP版,并加入到自己的微信公众号上面,我的微信公众号二维码见右侧。Enjoy~ 查看全部
最近一段时间,微信公众平台做了很多的改进啊~

微信目前将公众帐号分成服务号和订阅号两种,之前的微信公众号默认为订阅号,不过有一次机会可以自由选择,两者之间各有优劣:

服务号每月只能推送一条消息,不过消息是显示在消息列表中,并有消息提示;订阅号每天有一条消息推送,不过消息不显示在消息列表,没有消息提示。

除此之外,目前微信公众号可以自定义菜单,下面将介绍如果使用Java作一个微信公众号的菜单,参考API可到官网查看:http://mp.weixin.qq.com/wiki/index.php?title=%E8%87%AA%E5%AE%9A%E4%B9%89%E8%8F%9C%E5%8D%95%E6%8E%A5%E5%8F%A3
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.json.JSONObject;

public class MenuUtil {
/**
* 获得ACCESS_TOKEN
* @Title: getAccess_token
* @Description: 获得ACCESS_TOKEN
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
private static String getAccess_token(){

String APPID="";
String APPSECRET="";

String url = "https://api.weixin.qq.com/cgi- ... 3B%2B APPID + "&secret=" +APPSECRET;
String accessToken = null;
try {
URL urlGet = new URL(url);
HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();

http.setRequestMethod("GET"); //必须是get方式请求
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");

JSONObject demoJson = new JSONObject(message);
accessToken = demoJson.getString("access_token");

System.out.println(message);
} catch (Exception e) {
e.printStackTrace();
}
return accessToken;
}

/**
* 创建Menu
* @Title: createMenu
* @Description: 创建Menu
* @param @return
* @param @throws IOException 设定文件
* @return int 返回类型
* @throws
*/
public static String createMenu() {
String menu = "{\"button\":[{\"type\":\"click\",\"name\":\"MENU01\",\"key\":\"1\"},{\"type\":\"click\",\"name\":\"天气查询\",\"key\":\"西安\"},{\"name\":\"日常工作\",\"sub_button\":[{\"type\":\"click\",\"name\":\"待办工单\",\"key\":\"01_WAITING\"},{\"type\":\"click\",\"name\":\"已办工单\",\"key\":\"02_FINISH\"},{\"type\":\"click\",\"name\":\"我的工单\",\"key\":\"03_MYJOB\"},{\"type\":\"click\",\"name\":\"公告消息箱\",\"key\":\"04_MESSAGEBOX\"},{\"type\":\"click\",\"name\":\"签到\",\"key\":\"05_SIGN\"}]}]}";

//此处改为自己想要的结构体,替换即可
String access_token= getAccess_token();

String action = "https://api.weixin.qq.com/cgi- ... en%3B
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("POST");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.write(menu.getBytes("UTF-8"));//传入参数
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "返回信息"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "createMenu 失败";
}

/**
* 删除当前Menu
* @Title: deleteMenu
* @Description: 删除当前Menu
* @param @return 设定文件
* @return String 返回类型
* @throws
*/
public static String deleteMenu()
{
String access_token= getAccess_token();
String action = "https://api.weixin.qq.com/cgi-bin/menu/delete? access_token="+access_token;
try {
URL url = new URL(action);
HttpURLConnection http = (HttpURLConnection) url.openConnection();

http.setRequestMethod("GET");
http.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
http.setDoOutput(true);
http.setDoInput(true);
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");//连接超时30秒
System.setProperty("sun.net.client.defaultReadTimeout", "30000"); //读取超时30秒

http.connect();
OutputStream os= http.getOutputStream();
os.flush();
os.close();

InputStream is =http.getInputStream();
int size =is.available();
byte[] jsonBytes =new byte[size];
is.read(jsonBytes);
String message=new String(jsonBytes,"UTF-8");
return "deleteMenu返回信息:"+message;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "deleteMenu 失败";
}

public static void main(String[] args) {
System.out.println(createMenu());
}
}
代码来源于:http://www.oschina.net/code/snippet_945711_24355 ,后续会做PHP版,并加入到自己的微信公众号上面,我的微信公众号二维码见右侧。Enjoy~

Java模拟登录微信公众平台,主动推送图文消息给用户

服务端atool 发表了文章 • 0 个评论 • 1186 次浏览 • 2016-04-22 11:37 • 来自相关话题

@2013-11-25,对博文进行说明,由于2013年10月底,微信公众平台界面完全改版,所以本博文的所有代码几乎全部不能使用,不过有网友对本博的代码进行修改并授权于我共享给大家,因此大家可以去看博文《【微信公众平台改版后】Java模拟登录微信平台,主动推送消息给用户》,本博文的思路,大家也可以看看进行参考。

很早之前,在博客中发表了关于使用java开发微信公众号接口的程序代码,详细见《微信公众号消息接口开发——Java Servlet开发》,例外利用java做了小黄鸡,小i机器人的微信聊天开发,所以之前很多人问我有关于java开发微信接口的东西~

除此之外,更重要的是:很多人还问我关于微信主动推送消息给用户的问题,我所给出的所有答案都是:微信官方没有给出主动推送的api,所有采用程序记录用户微信id,然后模拟微信接口的请求数据,去请求微信接口中设置的url,这些方法都是不可行的~

不过,要实现主动推送不是不可能的,最简单的一个思路就是使用java模拟登录微信公众平台,然后推送消息消息给用户,不过这种方式有推送限制。

由于问的人比较多,决定把代码放出来,代码还未整理,里面有解析数据可以用正则表达式替换也没做,有需要的可以自己在此基础上修改。如果你觉得有用,并帮助了你,感谢你对我的赞助和支持。
public boolean msgSend(MsgForm form, MsgType type) {
try {
if (!this.isLogin) {
this._login();
}
if (this.isLogin) {
form.setToken(this.token);
PostMethod post = new PostMethod(POST_MSG);
post.setRequestHeader(USER_AGENT_H, USER_AGENT);
post.setRequestHeader(REFERER_H, INDEX_URL);
post.setRequestHeader("Cookie", this.cookiestr);
NameValuePair[] params = null;
Part[] parts = null;
switch (type) {
case TEXT:

parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
case IMAGE_TEXT:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
default:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
}
RequestEntity entity = new MultipartRequestEntity(parts,
post.getParams());
post.setRequestEntity(entity);
int status;
status = client.executeMethod(post);
if (status == HttpStatus.SC_OK) {
String text = post.getResponseBodyAsString();
try {
MsgJson ret = JSON.parseObject(text, MsgJson.class);
this.msgSendCode = ret.getRet();
switch (this.msgSendCode) {
case 0:
this.msgSendMsg = "发送成功";
return true;
case -2:
this.msgSendMsg = "参数错误,请仔细检查";
return false;
case 64004:
this.msgSendMsg = "今天的群发数量已到,无法群发";
return false;
case -20000:
this.msgSendMsg = "请求被禁止,请仔细检查token是否合法";
return false;
default:
this.msgSendMsg = "未知错误!";
return false;
}
} catch (Exception e) {
String info = "【群发信息失败】【解析json错误】" + e.getMessage()
+ "
【文本:】
" + text;
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
}
}
} catch (Exception e) {
String info = "【群发信息失败】" + e.getMessage();
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
return false;
} 查看全部
@2013-11-25,对博文进行说明,由于2013年10月底,微信公众平台界面完全改版,所以本博文的所有代码几乎全部不能使用,不过有网友对本博的代码进行修改并授权于我共享给大家,因此大家可以去看博文《【微信公众平台改版后】Java模拟登录微信平台,主动推送消息给用户》,本博文的思路,大家也可以看看进行参考。

很早之前,在博客中发表了关于使用java开发微信公众号接口的程序代码,详细见《微信公众号消息接口开发——Java Servlet开发》,例外利用java做了小黄鸡,小i机器人的微信聊天开发,所以之前很多人问我有关于java开发微信接口的东西~

除此之外,更重要的是:很多人还问我关于微信主动推送消息给用户的问题,我所给出的所有答案都是:微信官方没有给出主动推送的api,所有采用程序记录用户微信id,然后模拟微信接口的请求数据,去请求微信接口中设置的url,这些方法都是不可行的~

不过,要实现主动推送不是不可能的,最简单的一个思路就是使用java模拟登录微信公众平台,然后推送消息消息给用户,不过这种方式有推送限制。

由于问的人比较多,决定把代码放出来,代码还未整理,里面有解析数据可以用正则表达式替换也没做,有需要的可以自己在此基础上修改。如果你觉得有用,并帮助了你,感谢你对我的赞助和支持。
public boolean msgSend(MsgForm form, MsgType type) {
try {
if (!this.isLogin) {
this._login();
}
if (this.isLogin) {
form.setToken(this.token);
PostMethod post = new PostMethod(POST_MSG);
post.setRequestHeader(USER_AGENT_H, USER_AGENT);
post.setRequestHeader(REFERER_H, INDEX_URL);
post.setRequestHeader("Cookie", this.cookiestr);
NameValuePair[] params = null;
Part[] parts = null;
switch (type) {
case TEXT:

parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
case IMAGE_TEXT:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
default:
parts = new Part[]{
new StringPart("content", form.getContent(),
"UTF-8"),
new StringPart("type", form.getType()),
new StringPart("error", form.getError()),
new StringPart("needcomment", form.getNeedcomment()),
new StringPart("groupid", form.getGroupid()),
new StringPart("sex", form.getSex()),
new StringPart("country", form.getCountry()),
new StringPart("province", form.getProvince()),
new StringPart("city", form.getCity()),
new StringPart("token", form.getToken()),
new StringPart("ajax", form.getAjax()),
new StringPart("t", "ajax-response")};
break;
}
RequestEntity entity = new MultipartRequestEntity(parts,
post.getParams());
post.setRequestEntity(entity);
int status;
status = client.executeMethod(post);
if (status == HttpStatus.SC_OK) {
String text = post.getResponseBodyAsString();
try {
MsgJson ret = JSON.parseObject(text, MsgJson.class);
this.msgSendCode = ret.getRet();
switch (this.msgSendCode) {
case 0:
this.msgSendMsg = "发送成功";
return true;
case -2:
this.msgSendMsg = "参数错误,请仔细检查";
return false;
case 64004:
this.msgSendMsg = "今天的群发数量已到,无法群发";
return false;
case -20000:
this.msgSendMsg = "请求被禁止,请仔细检查token是否合法";
return false;
default:
this.msgSendMsg = "未知错误!";
return false;
}
} catch (Exception e) {
String info = "【群发信息失败】【解析json错误】" + e.getMessage()
+ "
【文本:】
" + text;
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
}
}
} catch (Exception e) {
String info = "【群发信息失败】" + e.getMessage();
System.err.println(info);
log.debug(info);
log.info(info);
return false;
}
return false;
}

微信公众号消息接口开发——Java Servlet开发

编程语言atool 发表了文章 • 0 个评论 • 1100 次浏览 • 2016-04-22 11:02 • 来自相关话题

张小龙搞出来的微信真的很牛逼啊,短短两三年就2亿用户量,这个数据似乎在警告QQ部门,IM软件上,你们QQ的老大位置并不稳固,仍需努力。当然QQ和微信不是一个平台上的产品,并不存在很大的竞争问题。

微信公众号消息接口API只有相当于只有一个简单调用链接,但是却完全改变了最初微信公众号的概念。不过说实话,这个接口真的设计的不怎么的...验证过程个字符处理啊,加密啊,拼接啊毫无用处,在申请页面填写的token也毫无用处,这些都是题外话了。不管这个接口腾讯设计得好不好,我们需要关心的是我们利用这个接口能够做什么,怎么做?

废话少说,言归正传,微信官网给我们提供了PHP的例子,所以做PHP的同学只需要画瓢即可,对于Java平台,网上还没有人说起,欲知Java平台怎么开发微信公众号接口,请看下文:

下面列出使用Java Servlet开发的一个简单的微信公众号接口调用的例子,如果有疑问,可以参见我本博的微信公众号:红色石头。

另外,我想大家一定很想知道《模拟登录微信公众平台,主动推送图文消息给用户》的有关信息。点开即可看到了~~~




 
package com.wzwcxl.pubwx.hustac.pubwx;

import java.io.IOException;
import java.io.InputStream;

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

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.wzwcxl.pubwx.hustac.util.StringUtil;

/**
* 微信公众号接口调用Java版
* @author Xewee.Zhiwei.Wang
* @version 2012-12-17 上午9:16:02
* @Contract wzwahl36@QQ.com or http://wzwahl36.net/
*/
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
// response.getWriter().write(request.getParameter("echostr"));
doPost(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------post---------------");
try {
InputStream is = request.getInputStream();
// 取HTTP请求流长度
int size = request.getContentLength();
// 用于缓存每次读取的数据
byte[] buffer = new byte[size];
// 用于存放结果的数组
byte[] xmldataByte = new byte[size];
int count = 0;
int rbyte = 0;
// 循环读取
while (count < size) {
// 每次实际读取长度存于rbyte中
rbyte = is.read(buffer);
for(int i=0;i<rbyte;i++) {
xmldataByte[count + i] = buffer[i];
}
count += rbyte;
}
is.close();
String requestStr = new String(xmldataByte, "UTF-8");
Document doc = DocumentHelper.parseText(requestStr);
Element rootElt = doc.getRootElement();
String content = rootElt.elementText("Content");
String toUserName = rootElt.elementText("ToUserName");
String fromUserName = rootElt.elementText("FromUserName");
//得到所有的有用数据
System.out.println(content+ ":" + toUserName + ":" + fromUserName);
//文本消息
if (! StringUtil.isBlank(content) && "text".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//图文消息
else if (! StringUtil.isBlank(content) && "news".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[news]]></MsgType>";
responseStr += "<Content><![CDATA[]]></Content>";

responseStr += "<ArticleCount>2</ArticleCount>";

responseStr += "<Articles>";
responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "</Articles>";
responseStr += "<FuncFlag>1</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//不能识别
else {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}

} catch (Exception e) {
e.printStackTrace();
}
}
}需要注意是一点是:在验证链接时,将get方法写为以下:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
response.getWriter().write(request.getParameter("echostr"));
// doPost(request, response);
}
验证通过之后,将get方法和post方法写成一样的。
另外注意servlet的编码问题,我这个servlet里面没有写编码是因为我设置了编码过滤器:
package com.wzwcxl.pubwx.hustac.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
* Servlet Filter implementation class EncodingFilter
*/
public class EncodingFilter implements Filter {

/**
* Default constructor.
*/
public EncodingFilter() {
// TODO Auto-generated constructor stub
}

/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}

/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
System.out.println("EncodingFilter: UTF-8");

chain.doFilter(request, response);
}

/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}附加:很多人问到代码中的StringUtil类中的isBlank方法是什么?然后要我发给他,其实StringUtil只有isBlank方法,这个方法就是用来判断字符串是不是空,所谓字符串为空,就是等于null或者trim之后为"",每次问到这个我都不知道怎么回答,所以在这里附加说明一下~

Enjoy~有空点点广告,感谢~~~ 查看全部
张小龙搞出来的微信真的很牛逼啊,短短两三年就2亿用户量,这个数据似乎在警告QQ部门,IM软件上,你们QQ的老大位置并不稳固,仍需努力。当然QQ和微信不是一个平台上的产品,并不存在很大的竞争问题。

微信公众号消息接口API只有相当于只有一个简单调用链接,但是却完全改变了最初微信公众号的概念。不过说实话,这个接口真的设计的不怎么的...验证过程个字符处理啊,加密啊,拼接啊毫无用处,在申请页面填写的token也毫无用处,这些都是题外话了。不管这个接口腾讯设计得好不好,我们需要关心的是我们利用这个接口能够做什么,怎么做?

废话少说,言归正传,微信官网给我们提供了PHP的例子,所以做PHP的同学只需要画瓢即可,对于Java平台,网上还没有人说起,欲知Java平台怎么开发微信公众号接口,请看下文:

下面列出使用Java Servlet开发的一个简单的微信公众号接口调用的例子,如果有疑问,可以参见我本博的微信公众号:红色石头。

另外,我想大家一定很想知道《模拟登录微信公众平台,主动推送图文消息给用户》的有关信息。点开即可看到了~~~
redstones_wx_430.jpg

 
package com.wzwcxl.pubwx.hustac.pubwx;

import java.io.IOException;
import java.io.InputStream;

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

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.wzwcxl.pubwx.hustac.util.StringUtil;

/**
* 微信公众号接口调用Java版
* @author Xewee.Zhiwei.Wang
* @version 2012-12-17 上午9:16:02
* @Contract wzwahl36@QQ.com or http://wzwahl36.net/
*/
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
// response.getWriter().write(request.getParameter("echostr"));
doPost(request, response);
}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------post---------------");
try {
InputStream is = request.getInputStream();
// 取HTTP请求流长度
int size = request.getContentLength();
// 用于缓存每次读取的数据
byte[] buffer = new byte[size];
// 用于存放结果的数组
byte[] xmldataByte = new byte[size];
int count = 0;
int rbyte = 0;
// 循环读取
while (count < size) {
// 每次实际读取长度存于rbyte中
rbyte = is.read(buffer);
for(int i=0;i<rbyte;i++) {
xmldataByte[count + i] = buffer[i];
}
count += rbyte;
}
is.close();
String requestStr = new String(xmldataByte, "UTF-8");
Document doc = DocumentHelper.parseText(requestStr);
Element rootElt = doc.getRootElement();
String content = rootElt.elementText("Content");
String toUserName = rootElt.elementText("ToUserName");
String fromUserName = rootElt.elementText("FromUserName");
//得到所有的有用数据
System.out.println(content+ ":" + toUserName + ":" + fromUserName);
//文本消息
if (! StringUtil.isBlank(content) && "text".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//图文消息
else if (! StringUtil.isBlank(content) && "news".equals(content)) {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[news]]></MsgType>";
responseStr += "<Content><![CDATA[]]></Content>";

responseStr += "<ArticleCount>2</ArticleCount>";

responseStr += "<Articles>";
responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "<item>";
responseStr += "<Title><![CDATA[图文消息——红色石头]]></Title>";
responseStr += "<Discription><![CDATA[图文消息正文——红色石头]]></Discription>";
responseStr += "<PicUrl><![CDATA[http://redstones.sinaapp.com/res/images/redstones_wx_258.jpg]]></PicUrl>";
responseStr += "<Url><![CDATA[http://redstones.sinaapp.com/]]></Url>";
responseStr += "</item>";

responseStr += "</Articles>";
responseStr += "<FuncFlag>1</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}
//不能识别
else {
String responseStr = "<xml>";
responseStr += "<ToUserName><![CDATA[" + fromUserName
+ "]]></ToUserName>";
responseStr += "<FromUserName><![CDATA[" + toUserName
+ "]]></FromUserName>";
responseStr += "<CreateTime>" + System.currentTimeMillis()
+ "</CreateTime>";
responseStr += "<MsgType><![CDATA[text]]></MsgType>";
responseStr += "<Content>输入text或者news返回相应类型的消息,另外推荐你关注 '红色石头'(完全采用Java完成),反馈和建议请到http://wzwahl36.net</Content>";
responseStr += "<FuncFlag>0</FuncFlag>";
responseStr += "</xml>";
response.getWriter().write(responseStr);
}

} catch (Exception e) {
e.printStackTrace();
}
}
}
需要注意是一点是:在验证链接时,将get方法写为以下:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("----------get---------------");
response.getWriter().write(request.getParameter("echostr"));
// doPost(request, response);
}
验证通过之后,将get方法和post方法写成一样的。
另外注意servlet的编码问题,我这个servlet里面没有写编码是因为我设置了编码过滤器:
package com.wzwcxl.pubwx.hustac.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
* Servlet Filter implementation class EncodingFilter
*/
public class EncodingFilter implements Filter {

/**
* Default constructor.
*/
public EncodingFilter() {
// TODO Auto-generated constructor stub
}

/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}

/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
System.out.println("EncodingFilter: UTF-8");

chain.doFilter(request, response);
}

/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
附加:很多人问到代码中的StringUtil类中的isBlank方法是什么?然后要我发给他,其实StringUtil只有isBlank方法,这个方法就是用来判断字符串是不是空,所谓字符串为空,就是等于null或者trim之后为"",每次问到这个我都不知道怎么回答,所以在这里附加说明一下~

Enjoy~有空点点广告,感谢~~~