java的web 工程,接收消息,发送图片信息
企业微信api
企业号开发者接口文档
企业微信接口调试工具
微信企业号错误代码查询工具
原理:有移动端输入信息到企业号,企业号中的信息有微信服务器加密之后发送给自己的服务,自己的服务接收到信息、解密、获取信息、处理信息,加密、返回信息给微信服务器,后显示到企业号中;
但是因为这种需要在5s内相应,否则视为相应失败;
所以我们是有api文档建议的类似于异步发送,自己的服务接收处理信息后,直接返回200,给微信服务器标示为处理成功,之后在调用主动发送消息,发送给特定的用户;
整个项目war-好多信息懒得改
代码案例
其中get请求处理url验证,post请求处理移动端主动发送的信息及回复;
发送图片,调用主动发送的信息
其中加密解密都有参考可看,主动发送的实例都在test文件夹中,util文件夹是各种工具类;
(可参考前几篇相关文章)
package servlet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import net.sf.json.JSONObject;
import util.AesException;
import util.MediaUploadUtil;
import util.WXBizMsgCrypt;
import util.WxworkNewsType;
import util.WxworkUtil;
/**
* @version 本servlet,针对微信企业号,其中get处理url校验,post处理接收信息处理
* @author pwu
* @time 20180201
*/
public class ResponseNews extends HttpServlet {
// 设置企业号后台参数
static String sToken = "QDG6eK";
static String sEncodingAESKey = "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C";
static String sCorpID = "ww248ac59c619621da";
static String sAgentId = "1000002";
static String corpsecret = "uXWrHT-Kxjttu1nDga-fdKqs6SCi01cq-nVb4bfXsSE";
/**
*
*/
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
// System.out.println("request-url:" +
// request.getRequestURL().toString());
System.out.println("ResponseNews----get--" + sFormat.format(new Date()));
// System.out.println("请求格式:" + request.getContentType());
request.setCharacterEncoding("utf-8");
// String getContextPath = request.getContextPath();
// String basePath = request.getScheme() + "://" +
// request.getServerName() + ":" + request.getServerPort()
// + getContextPath + "/";
// System.out.println("basePath:" + basePath);
/*
* String getRemoteAddress=request.getRemoteAddr(); String
* getServletPath =request.getServletPath(); String
* getServletContext_getRealPath =request.getServletPath();
*/
// String getRequestURL = request.getRequestURL().toString();
// System.out.println("getRequestURL:" + getRequestURL);
/*
* String getRequestURI =request.getRequestURI(); String getRemoteUser
* =request.getRemoteUser();
*/
String getQueryString = request.getQueryString();
if (request.getQueryString() == null || ("").equals(request.getQueryString())) {
out.println("request no querystring");
} else {
System.out.println("getQueryString:" + getQueryString);
// System.out.println("请求参数getQueryString:" + getQueryString);
// System.out.println("需要解密的字段,获取其中echostr信息:"+teMap.get("echostr"));
// System.out.println("request.getParameter--" +
// request.getParameter("echostr"));
String sVerifyMsgSig = request.getParameter("msg_signature");
String sVerifyTimeStamp = request.getParameter("timestamp");
String sVerifyNonce = request.getParameter("nonce");
String sVerifyEchoStr = request.getParameter("echostr");
String sEchoStr = null; // 需要返回的明文
WXBizMsgCrypt wxcpt = null;
if (sEncodingAESKey.length() != 43) {
System.out.println("sEncodingAESKey 长度异常");
}
try {
wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr);
System.out.println("解密结果verifyurl echostr: " + sEchoStr);
// 验证URL成功,将sEchoStr返回
} catch (Exception e) {
// 验证URL失败,错误原因请查看异常
e.printStackTrace();
}
/*
* response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
* response.setHeader("content-type", "text/html;charset=UTF-8");
* response.setContentType("text/htmll;charset=utf-8");
*/
String numbers = sEchoStr;
out.println(numbers);
}
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to
* post.
*
* @param request
* the request send by the client to the server
* @param response
* the response send by the server to the client
* @throws ServletException
* if an error occurred
* @throws IOException
* if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
long time1 = System.currentTimeMillis();
// 获取accestoken后,发送post请求,目前发送txt格式,发送的参数为json格式
JSONObject jsparam = new JSONObject();
JSONObject jsparam2 = new JSONObject();
WXBizMsgCrypt wxcpt = null;
String sReqMsgSig = null;//
String sReqTimeStamp = null;// 时间戳
String sReqNonce = null;// 随机数
// 解密消息参数
String ToUserName = null;// 发送信息用户名
String MsgId = null;// 此次消息的msgid
String Content = null;// 请求消息
try {
wxcpt = new WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID);
} catch (AesException e1) {
e1.printStackTrace();
}
System.out.println("处理Post()请求------");
System.out.println("*************************request信息如下:**************");
response.setContentType("text/html;charset=UTF-8");
/*
* String getContextPath = request.getContextPath(); String basePath =
* request.getScheme()+"://"+request.getServerName()+":"+request.
* getServerPort()+getContextPath+"/"; String getServletPath =
* request.getServletPath(); String getRemoteUser =
* request.getRemoteUser(); String getRequestUri =
* request.getRequestURI();
*/
String getRequestUrl = request.getRequestURL().toString();
String getQueryString = request.getQueryString();
// 获取请求体
BufferedReader bReader = request.getReader();
String str, sReqData = "";
while ((str = bReader.readLine()) != null) {
sReqData += str;
}
// System.out.println("getContextPath:"+getContextPath);
// System.out.println("basePath:"+basePath);
System.out.println("getRequestUrl:" + getRequestUrl);
// System.out.println("getRequestUri:"+getRequestUri);
// System.out.println("getQueryString:" + getQueryString);
System.out.println("请求body的加密信息:" + sReqData);
// 对url中的参数进行校验和处理
if (getQueryString == null && ("").equals(getQueryString)) {
System.out.println("请求url的参数为空");
}
// System.out.println("获取url参数后,需要解密");
sReqMsgSig = request.getParameter("msg_signature");
sReqTimeStamp = request.getParameter("timestamp");
sReqNonce = request.getParameter("nonce");
String sMsg = "";
try {
sMsg = wxcpt.DecryptMsg(sReqMsgSig, sReqTimeStamp, sReqNonce, sReqData);
System.out.println("解密结果after decrypt msg: " + sMsg);
// TODO: 解析出明文xml标签的内容进行处理
// For example:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(sMsg);
InputSource is = new InputSource(sr);
Document document = db.parse(is);
Element root = document.getDocumentElement();
NodeList nodelist1 = root.getElementsByTagName("Content");
Content = nodelist1.item(0).getTextContent();
ToUserName = root.getElementsByTagName("AgentID").item(0).getTextContent();
MsgId = root.getElementsByTagName("MsgId").item(0).getTextContent();
System.out.println("解析企业号发送信息Content:" + Content);
} catch (AesException e) {
System.out.println("获取request参数及body后,解析异常");
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("*************************response信息入下:****************");
response.setContentType("text/htmll;charset=utf-8");
/*
* 处理返回的加密信息 其中xml中的Nonce是随机数,TimeStamp是时间戳 sReqTimeStamp,
* sReqNonce取自请求request参数
*
*/
PrintWriter out = response.getWriter();
// String sRespData =
// "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this
// is a
// test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>";
// String sRespData =
// "<xml><ToUserName><![CDATA[PengWu]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this
// is a
// test]]></Content><MsgId>1234567890123456</MsgId><AgentID>1000002</AgentID></xml>";
String sRespData = "";
if (("text1").equals(Content)) {
sRespData = "<xml><ToUserName><![CDATA[" + ToUserName
+ "]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>"
+ System.currentTimeMillis() + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA["
+ "response news -- test,type:text" + "]]></Content><MsgId>" + MsgId + "</MsgId><AgentID>"
+ sAgentId + "</AgentID></xml>";
} else if (("text2").equals(Content)) {
sRespData = "200";
/**使用异步发送
* 1.获取access_token,在发送文本信息,调用工具
*/
String access_token = WxworkUtil.GetForAT(sCorpID, corpsecret).get("access_token");
JSONObject jObject = WxworkNewsType.textType("文本信息,异步发送", ToUserName, "", sAgentId);
String result = WxworkUtil.sendData(access_token, jObject).get("errmsg");
System.out.println("返回发送结果errmsg:"+result);
}
else if (("image").equals(Content)) {
/*
* String access_token = WxworkUtil.GetForAT(sCorpID,
* corpsecret).get("access_token");
* System.out.println("accest_token:"+access_token); String mediaid
* = MediaUploadUtil.uploadMedia(access_token, "image",
* "http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg");
* String media_id = WxworkUtil.readRuslt(mediaid).get("media_id");
* System.out.println("media_id:"+media_id); sRespData =
* "<xml><ToUserName><![CDATA["+ ToUserName
* +"]]></ToUserName><FromUserName><![CDATA["+ sCorpID
* +"]]></FromUserName><CreateTime>"+ System.currentTimeMillis()
* +"</CreateTime><MsgType><![CDATA["+ "image"
* +"]]></MsgType><PicUrl><![CDATA["+
* "http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg"
* +"]]></PicUrl><MediaId><![CDATA[" + media_id +
* "]]></MediaId><MsgId>"+ MsgId +"</MsgId><AgentID>"+ sAgentId
* +"</AgentID></xml>";
*/
sRespData = "200";
/**
* 在这里调用主动发送信息,发送除了文本信息之外的数据
*/
String access_token = WxworkUtil.GetForAT(sCorpID, corpsecret).get("access_token");
String result = MediaUploadUtil.uploadMedia(access_token, "image",
"http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg");
System.out.println("result---media_id:" + result);
jsparam.put("media_id", WxworkUtil.readRuslt(result).get("media_id"));
jsparam2.put("image", jsparam);
jsparam2.put("msgtype", "image");
jsparam2.put("agentid", 1000002);
jsparam2.put("touser", "PengWu");
jsparam2.put("safe", "0");
String sendruslt = WxworkUtil.sendData(access_token, jsparam2).get("errmsg");
System.out.println("post请求返回结果:" + sendruslt);
} else if (("link").equals(Content)) {
sRespData = "<xml><ToUserName><![CDATA[" + sCorpID + "]]></ToUserName><FromUserName><![CDATA[" + ToUserName
+ "]]></FromUserName><CreateTime>" + System.currentTimeMillis() + "</CreateTime><MsgType><![CDATA["
+ "link" + "]]></MsgType><Title><![CDATA[" + "this is a title!--test link"
+ "]]></Title><Description><![CDATA[" + "this is a description!--test link"
+ "]]></Description><PicUrl><![CDATA["
+ "http://pic.sc.chinaz.com/files/pic/pic9/201801/zzpic9711.jpg" + "]]></PicUrl><MsgId>" + MsgId
+ "</MsgId><AgentID>" + sAgentId + "</AgentID></xml>";
} else {
sRespData = "<xml><ToUserName><![CDATA[" + ToUserName + "]]></ToUserName><FromUserName><![CDATA[" + sCorpID
+ "]]></FromUserName><CreateTime>" + System.currentTimeMillis() + "</CreateTime><MsgType><![CDATA["
+ "text" + "]]></MsgType><Content><![CDATA[" + Content + "]]></Content><MsgId>" + MsgId
+ "</MsgId><AgentID>" + sAgentId + "</AgentID></xml>";
}
// String sRespData = ToXmlString("response news -- test ",ToUserName);
try {
String sEncryptMsg = wxcpt.EncryptMsg(sRespData, sReqTimeStamp, sReqNonce);
System.out.println("相应消息加密结果--after encrypt sEncrytMsg: " + sEncryptMsg);
out.println(sEncryptMsg);
long time2 = System.currentTimeMillis() - time1;
System.out.println("限制为5000,服务端处理信息的时间-->" + time2);
// 加密成功
// TODO:
// HttpUtils.SetResponse(sEncryptMsg);
} catch (Exception e) {
e.printStackTrace();
// 加密失败
}
}
// 对于txt格式的xml生成
private String ToXmlString(String content, String ToUserName) {
Random random = new Random();
// "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this
// is a
// test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>";
String lString = "<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[{3}]]></MsgType><Content><![CDATA[{4}]]></Content><MsgId>{5}</MsgId><AgentID>{6}</AgentID></xml>";
lString = String.format(lString, ToUserName, sCorpID, System.currentTimeMillis(), "text", content,
random.nextInt(214748364) + 1, sAgentId);
// String s =
// "<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[{3}]]></MsgType><Content><![CDATA[{4}]]></Content></xml>";
// s = String.format(s,"wzwl005", sCorpID, System.currentTimeMillis(),
// "text", content);
return lString;
}
}
效果图:
将其中个个常用的方法的抽离类(不知道对不对,还没测完):
package util;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
/**
* @version 整理常用到的消息类型,抽离成固定方法,需要时直接调用;
* @author pwu
*
*/
public class WxworkNewsType {
static JSONObject jb = new JSONObject();
static JSONObject jb1 = new JSONObject();
static JSONObject jb2 = new JSONObject();
/**@description 文本信息格式,主动发送
* @param
* 例子:
* {
"touser" : "UserID1|UserID2|UserID3",
"toparty" : "PartyID1|PartyID2",
"totag" : "TagID1 | TagID2",
"msgtype" : "text",
"agentid" : 1,
"text" : {
"content" : "你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看<a href=\"http://work.weixin.qq.com\">邮件中心视频实况</a>,聪明避开排队。"
},
"safe":0
}
*/
public static JSONObject textType(String content,String touser,String toparty,String agentid){
jb1.put("content", content);
jb.put("text", jb1);
jb.put("msgtype" , "text");
jb.put("safe" , 0);
jb.put("agentid", agentid);
if (touser != null ) {
jb.put("touser", touser);
}else {
System.out.println("文本消息参数不规范,将会发送给所有人!");
jb.put("touser", "@all");
}
if (toparty != null) {
jb.put("toparty", toparty);
}
return jb;
}
/**
* @description 图文信息格式,主动发送
* @param
{
"touser" : "UserID1|UserID2|UserID3",
"toparty" : "PartyID1 | PartyID2",
"totag" : "TagID1 | TagID2",
"msgtype" : "news",
"agentid" : 1,
"news" : {
"articles" : [
{
"title" : "中秋节礼品领取",
"description" : "今年中秋节公司有豪礼相送",
"url" : "URL",
"picurl" : "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png",
"btntxt":"更多"
}
]
}
}
*/
public static JSONObject newsType(String touser,String toparty,String agentid,String title,
String description,String url,String picurl,String btntxt){
jb2.put("btntxt", btntxt);
jb2.put("picurl", picurl);
jb2.put("url", url);
jb2.put("description", description);
jb2.put("title", title);
JSONArray articles = new JSONArray();
articles.add(jb1);
jb1.put("articles", articles);
jb.put("news", jb1);
jb.put("msgtype" , "news");
jb.put("agentid", agentid);
if (touser != null ) {
jb.put("touser", touser);
}else {
System.out.println("文本消息参数不规范,将会发送给所有人!");
jb.put("touser", "@all");
}
if (toparty != null) {
jb.put("toparty", toparty);
}
return jb;
}
/**
* @description 图片信息格式,主动发送
* @param
* {
"touser" : "UserID1|UserID2|UserID3",
"toparty" : "PartyID1|PartyID2",
"totag" : "TagID1 | TagID2",
"msgtype" : "image",
"agentid" : 1,
"image" : {
"media_id" : "MEDIA_ID"
},
"safe":0
}
*/
public static JSONObject imageType(String media_id,String touser,String toparty,String agentid){
jb1.put("media_id", media_id);
jb.put("image", jb1);
jb.put("msgtype" , "image");
jb.put("safe" , 0);
jb.put("agentid", agentid);
if (touser != null ) {
jb.put("touser", touser);
}else {
System.out.println("文本消息参数不规范,将会发送给所有人!");
jb.put("touser", "@all");
}
if (toparty != null) {
jb.put("toparty", toparty);
}
return jb;
}
}