您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息

微信开发的消息接口

2024/4/17 12:45:05发布5次查看
这篇文章一起看看微信开发的消息接口
感觉微信开发就是要调用微信的接口,所以在没安排工作的时候看和试着调用微信接口,调用微信接口需要发送http的get和post请求,所以最好先写个httputil类,专门发送get和post请求,然而我的java网络编程学的并不好,于是百度一些代码,然后自己封装一些,可以正常使用就行了,代码如下
import java.io.bufferedreader; import java.io.datainputstream; import java.io.dataoutputstream; import java.io.file; import java.io.fileinputstream; import java.io.ioexception; import java.io.inputstream; import java.io.inputstreamreader; import java.io.outputstream; import java.io.printwriter; import java.net.httpurlconnection; import java.net.url; import java.net.urlconnection; import java.util.iterator; import java.util.map; import javax.activation.mimetypesfiletypemap; /** * * @author luolei * */ public class httputil { public static string httpget(string httpurl){ stringbuffer buffer = null; try{ url url = new url(httpurl); httpurlconnection httpurlconn = (httpurlconnection) url.openconnection(); httpurlconn.setdoinput(true); httpurlconn.setrequestmethod("get"); // 获取输入流 inputstream inputstream = httpurlconn.getinputstream(); inputstreamreader inputstreamreader = new inputstreamreader(inputstream, "utf-8"); bufferedreader bufferedreader = new bufferedreader(inputstreamreader); // 读取返回结果 buffer = new stringbuffer(); string str = null; while ((str = bufferedreader.readline()) != null) { buffer.append(str); } // 释放资源 bufferedreader.close(); inputstreamreader.close(); inputstream.close(); httpurlconn.disconnect(); }catch(exception e){ e.printstacktrace(); } return buffer.tostring(); } /** * * 发 post 请求, */ public static string httppost(string httpurl,string data){ printwriter out = null; bufferedreader in = null; string result = ""; try { url realurl = new url(httpurl); // 打开和url之间的连接 urlconnection conn = realurl.openconnection(); // 设置通用的请求属性 conn.setrequestproperty("accept", "*/*"); conn.setrequestproperty("connection", "keep-alive"); conn.setrequestproperty("user-agent", "mozilla/4.0 (compatible; msie 6.0; windows nt 5.1;sv1)"); // 发送post请求必须设置如下两行 conn.setdooutput(true); conn.setdoinput(true); // 获取urlconnection对象对应的输出流 out = new printwriter(conn.getoutputstream()); // 发送请求参数 out.print(data); // flush输出流的缓冲 out.flush(); // 定义bufferedreader输入流来读取url的响应 in = new bufferedreader( new inputstreamreader(conn.getinputstream())); string line; while ((line = in.readline()) != null) { result += line; } } catch (exception e) { system.out.println("发送 post 请求出现异常!"+e); e.printstacktrace(); } //使用finally块来关闭输出流、输入流 finally{ try{ if(out!=null){ out.close(); } if(in!=null){ in.close(); } } catch(ioexception ex){ ex.printstacktrace(); } } return result; } /** * 上传图片 * * @param urlstr * @param textmap * @param filemap * @return */ public static string formupload(string urlstr, map<string, string> textmap, map<string, string> filemap) { string res = ""; httpurlconnection conn = null; string boundary = "---------------------------123821742118716"; //boundary就是request头和上传文件内容的分隔符 try { url url = new url(urlstr); conn = (httpurlconnection) url.openconnection(); // system.out.println(conn); conn.setconnecttimeout(5000); conn.setreadtimeout(30000); conn.setdooutput(true); conn.setdoinput(true); conn.setusecaches(false); conn.setrequestmethod("post"); conn.setrequestproperty("connection", "keep-alive"); conn .setrequestproperty("user-agent", "mozilla/5.0 (windows; u; windows nt 6.1; zh-cn; rv:1.9.2.6)"); conn.setrequestproperty("content-type", "multipart/form-data; boundary=" + boundary); outputstream out = new dataoutputstream(conn.getoutputstream()); // text if (textmap != null) { stringbuffer strbuf = new stringbuffer(); iterator iter = textmap.entryset().iterator(); while (iter.hasnext()) { map.entry entry = (map.entry) iter.next(); string inputname = (string) entry.getkey(); string inputvalue = (string) entry.getvalue(); if (inputvalue == null) { continue; } strbuf.append("\r\n").append("--").append(boundary).append( "\r\n"); strbuf.append("content-disposition: form-data; name=\"" + inputname + "\"\r\n\r\n"); strbuf.append(inputvalue); } out.write(strbuf.tostring().getbytes()); } // file if (filemap != null) { iterator iter = filemap.entryset().iterator(); while (iter.hasnext()) { map.entry entry = (map.entry) iter.next(); string inputname = (string) entry.getkey(); string inputvalue = (string) entry.getvalue(); if (inputvalue == null) { continue; } file file = new file(inputvalue); string filename = file.getname(); string contenttype = new mimetypesfiletypemap() .getcontenttype(file); if (filename.endswith(".png")) { contenttype = "image/png"; } if (contenttype == null || contenttype.equals("")) { contenttype = "application/octet-stream"; } stringbuffer strbuf = new stringbuffer(); strbuf.append("\r\n").append("--").append(boundary).append( "\r\n"); strbuf.append("content-disposition: form-data; name=\"" + inputname + "\"; filename=\"" + filename + "\"\r\n"); strbuf.append("content-type:" + contenttype + "\r\n\r\n"); out.write(strbuf.tostring().getbytes()); datainputstream in = new datainputstream( new fileinputstream(file)); int bytes = 0; byte[] bufferout = new byte[1024]; while ((bytes = in.read(bufferout)) != -1) { out.write(bufferout, 0, bytes); } in.close(); } } byte[] enddata = ("\r\n--" + boundary + "--\r\n").getbytes(); out.write(enddata); out.flush(); out.close(); // 读取返回数据 stringbuffer strbuf = new stringbuffer(); bufferedreader reader = new bufferedreader(new inputstreamreader( conn.getinputstream())); string line = null; while ((line = reader.readline()) != null) { strbuf.append(line).append("\n"); } res = strbuf.tostring(); reader.close(); reader = null; } catch (exception e) { system.out.println("发送post请求出错。" + urlstr); e.printstacktrace(); } finally { if (conn != null) { conn.disconnect(); conn = null; } } return res; } }
其中的httpget 和httppost 用来发送get,和post请求,微信开发里面,消息接口一般是xml格式的,其他的接口上传和返回的数据一般是json,所以需要一个解析json的包,我用的是fastjson,当然也可以用gson
现在开始消息接口的测试,首先要了解请求过程:
微信服务器会根据填写的url发送get请求进行验证,当验证成功,还是根据url发送post请求,消息格式为xml格式
消息类型开发文档上有,主要有文本,图片,语音等消息,还有一些事件,如关注,点击,和跳转。
这些消息和事件是xml格式,所以要对xml格式的消息进行解析,我用的dom4j解析,
在之前验证接入的servlet的dopost方法解析消息,
我是按照柳峰的博客里面写的方法,写了个messageutil,里面封装了解析xml的方法,并把解析出来的结果放在map<string,string>中,具体代码如下:
public static map<string, string> parsexml(httpservletrequest request) throws exception { // 将解析结果存储在hashmap中 map<string, string> map = new hashmap<string, string>(); // 从request中取得输入流 inputstream inputstream = request.getinputstream(); // 读取输入流 saxreader reader = new saxreader(); document document = reader.read(inputstream); // 得到xml根元素 element root = document.getrootelement(); // 得到根元素的所有子节点 list<element> elementlist = root.elements(); // 遍历所有子节点 for (element e : elementlist) map.put(e.getname(), e.gettext()); // 释放资源 inputstream.close(); inputstream = null; return map; }
那么经过解析后的xml会按照 标签名 - 内容 保存在map中
然后可以从中取出消息类型msgtype
string msgtype = requestmap.get("msgtype");
然后判断消息的类型,不同的消息类型,让不同的servlet去处理,
// 文本消息 if (msgtype.equals(messageutil.req_message_type_text)) { request.getrequestdispatcher("textmessage").forward(request, response); } // 图片消息 else if (msgtype.equals(messageutil.req_message_type_image)) { request.getrequestdispatcher("imageservlet").forward(request, response); } // 地理位置消息 else if (msgtype.equals(messageutil.req_message_type_location)) { request.getrequestdispatcher("locationservlet").forward(request, response); } // 链接消息 else if (msgtype.equals(messageutil.req_message_type_link)) { request.getrequestdispatcher("linkservlet").forward(request, response); } // 音频消息 else if (msgtype.equals(messageutil.req_message_type_voice)) { request.getrequestdispatcher("vedioservlet").forward(request, response); } // 事件推送 else if (msgtype.equals(messageutil.req_message_type_event)) { // 事件类型 string eventtype = requestmap.get("event"); // 订阅 if (eventtype.equals(messageutil.event_type_subscribe)) { request.getrequestdispatcher("subservlet").forward(request, response); } // 取消订阅 else if (eventtype.equals(messageutil.event_type_unsubscribe)) { // todo 取消订阅后用户再收不到公众号发送的消息,因此不需要回复消息 } // 自定义菜单点击事件 else if (eventtype.equals(messageutil.event_type_click)) { // todo 自定义菜单权没有开放,暂不处理该类消息 request.getrequestdispatcher("clickservlet").forward(request, response); } }
不同的servlet里面处理不同的消息,可以根据需要返回不同的消息,返回消息的格式也是xml格式的,返回消息类型跟接受的消息类型基本类似,可以对这些返回的消息进行封装,每个xml标签对应字段名,内容就是字段的内容
例子:
public class basemessageresp { // 接收方帐号(收到的openid) private string tousername; // 开发者微信号 private string fromusername; // 消息创建时间 (整型) private long createtime; // 消息类型(text/music/news) private string msgtype; // 位0x0001被标志时,星标刚收到的消息 private int funcflag;
省略了set,get方法
public class textmessage extends basemessageresp { // 回复的消息内容 private string content; public string getcontent() { return content; } public void setcontent(string content) { content = content; } }
因为不同的消息有相同的字段,因此写了通用的基类。
现在离返回消息给用户还差一步,技术将这些pojo类转化为xml字符串
用的是xstream
/** * 文本消息对象转换成xml * * @param textmessage 文本消息对象 * @return xml */ public static string textmessagetoxml(textmessage textmessage) { xstream.alias("xml", textmessage.getclass()); return xstream.toxml(textmessage); }
这里只是简单的描述,具体的可以以看柳峰的博客,链接我忘记了,应该可以百度的到
最后将得到的string 返回给微信服务器就可以回复用户了。
只用这些消息接口就可以写一个简单的订阅号了,应该,一般公司的公众号好像是通过view类型的button跳到自己的网站里面去。
现在用上面的接口可以接受用户发送的各种消息,然后提前消息,可以自己进行处理,或者调用一些api,如天气,笑话,文章等api,得到结果,解析后,按照自己希望的格式返回给用户,可以实习一个生活助手之类的订阅号,但是个人申请的订阅号的权限有限,不知道能不能够胜任。
以上就是微信开发的消息接口的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录