首页 > 开发 > Java > 正文

Java微信公众号开发实例

2020-02-29 20:04:31
字体:
来源:转载
供稿:网友

Java微信公众号开发实例,微信公众号开发一般是针对企业和组织的,个人一般只能申请订阅号,并且调用的接口有限,下面错新技术频道的小编就来简单的描述下接入公众号的步骤

1、首先你需要一个邮箱在微信公众号平台进行注册;
     注册的方式有订阅号、公众号、小程序和企业号,个人我们这里只能选择订阅号

2、注册完后,我们登录到公众号平台--->开发--->基本配置,这里需要填写URL和token,URL就是我们使用服务器的接口;

3、Java Web服务器程序编译好且在服务器上部署可以运行的话,可在微信公众号进行在线接口调试:

    1)、选择合适的接口
    2)、系统会生成该接口的参数表,您可以直接在文本框内填入对应的参数值(红色星号表示该字段必填)
    3)、点击检查问题按钮,即可得到相应的调试信息

   eg:获取access_token的步骤:

   1)、接口类型:基础支持
   2)、接口列表:获取access_token接口/token
   3)、填写相应的参数:grant_type、appid、secret
   4)、点击检查问题
   5)、验证成功会返回结果和提示,结果为:200 ok,提示:Request successful即表示验证成功

   我们这里验证比较多的是消息接口调试:文本消息、图片消息、语音消息、视频消息、etc

4、接口有不理解的地方,可进入开发-->开发者工具-->开发者文档进行查询

5、接口权限:订阅号主要有基础支持、接收消息及网页服务里面的一些接口

下面我们主要讲订阅号怎么样接收消息的案例:

1、需要申请一个个人微信订阅号
2、url服务器和服务器端代码部署(可以用腾讯云or阿里云服务器)

1)、AccountsServlet.java类,验证来自微信服务器和微信服务器的消息处理

package cn.jon.wechat.servlet;  import java.io.IOException; import java.io.PrintWriter;  import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  import cn.jon.wechat.service.AccountsService; import cn.jon.wechat.utils.SignUtil;  public class AccountsServlet extends HttpServlet {   public AccountsServlet() {  super();  }    public void destroy() {  super.destroy();  // Put your code here  }  /**  * 确认请求来自于微信服务器  */   public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  System.out.println("接口测试开始!!!");  //微信加密签名  String signature = request.getParameter("signature");  //时间戳  String timestamp = request.getParameter("timestamp");  //随机数  String nonce = request.getParameter("nonce");  //随机字符串  String echostr = request.getParameter("echostr");   PrintWriter out = response.getWriter();  //通过校验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败  if(SignUtil.checkSignature(signature,timestamp,nonce)){  out.print(echostr);  }  out.close();  out = null; // response.encodeRedirectURL("success.jsp");    }  /**  * 处理微信服务器发来的消息  */  public void doPost(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {  //消息的接受、处理、响应  request.setCharacterEncoding("utf-8");  response.setCharacterEncoding("utf-8");  //调用核心业务类型接受消息、处理消息  String respMessage = AccountsService.processRequest(request);   //响应消息  PrintWriter out = response.getWriter();  out.print(respMessage);  out.close();    }   public void init() throws ServletException {  // Put your code here  }  } 

2)、SignUtil.java类,请求校验工具类,token需要和微信中填写的token一致

package cn.jon.wechat.utils;  import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap;  /**  * 请求校验工具类  * @author jon  */ public class SignUtil {  //与微信配置中的的Token一致  private static String token = "";   public static boolean checkSignature(String signature, String timestamp,  String nonce) {  String[] arra = new String[]{token,timestamp,nonce};  //将signature,timestamp,nonce组成数组进行字典排序  Arrays.sort(arra);  StringBuilder sb = new StringBuilder();  for(int i=0;i>>4)&0X0F];  tmpArr[1] = Digit[dByte&0X0F];  String s = new String(tmpArr);  return s;  }   public static void main(String[] args) {  /*byte dByte = 'A';  System.out.println(byteToHexStr(dByte));*/  Map map = new ConcurrentHashMap();  map.put("4", "zhangsan");  map.put("100", "lisi");  Set set = map.keySet();  Iterator iter = set.iterator();  while(iter.hasNext()){ // String keyV = (String) iter.next();  String key =(String)iter.next();  System.out.println(map.get(key)); // System.out.println(map.get(iter.next()));  }  /*for(int i=0;i();i++){>,>,string>;i++){>

3)、AccountsService.java服务类,主要是消息的请求和响应处理,并且当用户关注你的公众号的时候,可以设置默认推送消息

package cn.jon.wechat.service;  import java.util.Date; import java.util.Map;  import javax.servlet.http.HttpServletRequest;  import cn.jon.wechat.message.req.ImageMessage; import cn.jon.wechat.message.req.LinkMessage; import cn.jon.wechat.message.req.LocationMessage; import cn.jon.wechat.message.req.VideoMessage; import cn.jon.wechat.message.req.VoiceMessage; import cn.jon.wechat.message.resp.TextMessage; import cn.jon.wechat.utils.MessageUtil;  /**  * 解耦,使控制层与业务逻辑层分离开来,主要处理请求,响应  * @author jon  */ public class AccountsService {   public static String processRequest(HttpServletRequest request) {  String respMessage = null;  //默认返回的文本消息内容  String respContent = "请求处理异常,请稍后尝试!";  try {  //xml请求解析  Map requestMap = MessageUtil.pareXml(request);   //发送方账号(open_id)  String fromUserName = requestMap.get("FromUserName");  //公众账号  String toUserName = requestMap.get("ToUserName");  //消息类型  String msgType = requestMap.get("MsgType");   //默认回复此文本消息  TextMessage defaultTextMessage = new TextMessage();  defaultTextMessage.setToUserName(fromUserName);  defaultTextMessage.setFromUserName(toUserName);  defaultTextMessage.setCreateTime(new Date().getTime());  defaultTextMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT);  defaultTextMessage.setFuncFlag(0);  // 由于href属性值必须用双引号引起,这与字符串本身的双引号冲突,所以要转义  defaultTextMessage.setContent("欢迎访问jon的博客!"); // defaultTextMessage.setContent(getMainMenu());  // 将文本消息对象转换成xml字符串  respMessage = MessageUtil.textMessageToXml(defaultTextMessage);    //文本消息  if(msgType.equals(MessageUtil.MESSSAGE_TYPE_TEXT)){  //respContent = "Hi,您发送的是文本消息!";  //回复文本消息  TextMessage textMessage = new TextMessage(); // textMessage.setToUserName(toUserName); // textMessage.setFromUserName(fromUserName);  //这里需要注意,否则无法回复消息给用户了  textMessage.setToUserName(fromUserName);  textMessage.setFromUserName(toUserName);  textMessage.setCreateTime(new Date().getTime());  textMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT);  textMessage.setFuncFlag(0);  respContent = "Hi,你发的消息是:"+requestMap.get("Content");  textMessage.setContent(respContent);  respMessage = MessageUtil.textMessageToXml(textMessage);  }  //图片消息  else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_IMAGE)){    ImageMessage imageMessage=new ImageMessage();  imageMessage.setToUserName(fromUserName);  imageMessage.setFromUserName(toUserName);  imageMessage.setCreateTime(new Date().getTime());  imageMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_IMAGE);  //respContent=requestMap.get("PicUrl");  imageMessage.setPicUrl("http://img24.pplive.cn//2013//07//24//12103112092_230X306.jpg");  respMessage = MessageUtil.imageMessageToXml(imageMessage);  }  //地理位置  else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LOCATION)){  LocationMessage locationMessage=new LocationMessage();  locationMessage.setToUserName(fromUserName);  locationMessage.setFromUserName(toUserName);  locationMessage.setCreateTime(new Date().getTime());  locationMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LOCATION);  locationMessage.setLocation_X(requestMap.get("Location_X"));  locationMessage.setLocation_Y(requestMap.get("Location_Y"));  locationMessage.setScale(requestMap.get("Scale"));  locationMessage.setLabel(requestMap.get("Label"));  respMessage = MessageUtil.locationMessageToXml(locationMessage);    }   //视频消息  else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VIDEO)){  VideoMessage videoMessage=new VideoMessage();  videoMessage.setToUserName(fromUserName);  videoMessage.setFromUserName(toUserName);  videoMessage.setCreateTime(new Date().getTime());  videoMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VIDEO);  videoMessage.setMediaId(requestMap.get("MediaId"));  videoMessage.setThumbMediaId(requestMap.get("ThumbMediaId"));  respMessage = MessageUtil.videoMessageToXml(videoMessage);    }  //链接消息  else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LINK)){  LinkMessage linkMessage=new LinkMessage();  linkMessage.setToUserName(fromUserName);  linkMessage.setFromUserName(toUserName);  linkMessage.setCreateTime(new Date().getTime());  linkMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LINK);  linkMessage.setTitle(requestMap.get("Title"));  linkMessage.setDescription(requestMap.get("Description"));  linkMessage.setUrl(requestMap.get("Url"));  respMessage = MessageUtil.linkMessageToXml(linkMessage);  }  //语音消息  else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VOICE)){  VoiceMessage voiceMessage=new VoiceMessage();  voiceMessage.setToUserName(fromUserName);  voiceMessage.setFromUserName(toUserName);  voiceMessage.setCreateTime(new Date().getTime());  voiceMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VOICE);  voiceMessage.setMediaId(requestMap.get("MediaId"));  voiceMessage.setFormat(requestMap.get("Format"));  respMessage = MessageUtil.voiceMessageToXml(voiceMessage);  }  //事件推送  else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_EVENT)){  //事件类型  String eventType = requestMap.get("Event");  //订阅  if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){   respContent = "谢谢关注!";  }  //取消订阅  else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){   //   System.out.println("取消订阅");    }  else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){   //自定义菜单消息处理   System.out.println("自定义菜单消息处理");  }  }   } catch (Exception e) {  // TODO Auto-generated catch block  e.printStackTrace();  }  return respMessage;  }   public static String getMainMenu()  {  StringBuffer buffer =new StringBuffer();  buffer.append("您好,我是jon,请回复数字选择服务:").append("/n");  buffer.append("1、我的博客").append("/n");  buffer.append("2、 歌曲点播").append("/n");  buffer.append("3、 经典游戏").append("/n");  buffer.append("4 、聊天打牌").append("/n/n");  buffer.append("回复"+"0"+"显示帮助菜单");  return buffer.toString();   } } ,string>

4)、MessageUtil.java帮助类,包括常量的定义和xml消息转换和处理

package cn.jon.wechat.utils;  import java.io.InputStream; import java.io.Writer; import java.util.HashMap; import java.util.List; import java.util.Map;  import javax.servlet.http.HttpServletRequest;  import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;  import cn.jon.wechat.message.req.ImageMessage; import cn.jon.wechat.message.req.LinkMessage; import cn.jon.wechat.message.req.LocationMessage; import cn.jon.wechat.message.req.VideoMessage; import cn.jon.wechat.message.req.VoiceMessage; import cn.jon.wechat.message.resp.Article; import cn.jon.wechat.message.resp.MusicMessage; import cn.jon.wechat.message.resp.NewsMessage; import cn.jon.wechat.message.resp.TextMessage;  import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XppDriver;  /**  * 各种消息的处理类  * @author jon  */  public class MessageUtil {  /**  * 文本类型  */  public static final String MESSSAGE_TYPE_TEXT = "text";  /**  * 音乐类型  */  public static final String MESSSAGE_TYPE_MUSIC = "music";  /**  * 图文类型  */  public static final String MESSSAGE_TYPE_NEWS = "news";   /**  * 视频类型  */  public static final String MESSSAGE_TYPE_VIDEO = "video";  /**  * 图片类型  */  public static final String MESSSAGE_TYPE_IMAGE = "image";  /**  * 链接类型  */  public static final String MESSSAGE_TYPE_LINK = "link";  /**  * 地理位置类型  */  public static final String MESSSAGE_TYPE_LOCATION = "location";  /**  * 音频类型  */  public static final String MESSSAGE_TYPE_VOICE = "voice";  /**  * 推送类型  */  public static final String MESSSAGE_TYPE_EVENT = "event";  /**  * 事件类型:subscribe(订阅)  */  public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";  /**  * 事件类型:unsubscribe(取消订阅)  */  public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";  /**  * 事件类型:click(自定义菜单点击事件)  */  public static final String EVENT_TYPE_CLICK= "CLICK";   /**  * 解析微信发来的请求 XML  */  @SuppressWarnings("unchecked")  public static Map pareXml(HttpServletRequest request) throws Exception {   //将解析的结果存储在HashMap中  Map reqMap = new HashMap();   //从request中取得输入流  InputStream inputStream = request.getInputStream();  //读取输入流  SAXReader reader = new SAXReader();  Document document = reader.read(inputStream);  //得到xml根元素  Element root = document.getRootElement();  //得到根元素的所有子节点  List elementList = root.elements();  //遍历所有的子节点取得信息类容  for(Element elem:elementList){  reqMap.put(elem.getName(),elem.getText());  }  //释放资源  inputStream.close();  inputStream = null;   return reqMap;  }  /**  * 响应消息转换成xml返回  * 文本对象转换成xml  */  public static String textMessageToXml(TextMessage textMessage) {  xstream.alias("xml", textMessage.getClass());  return xstream.toXML(textMessage);  }  /**  * 语音对象的转换成xml  *  */  public static String voiceMessageToXml(VoiceMessage voiceMessage) {  xstream.alias("xml", voiceMessage.getClass());  return xstream.toXML(voiceMessage);  }   /**  * 视频对象的转换成xml  *  */  public static String videoMessageToXml(VideoMessage videoMessage) {  xstream.alias("xml", videoMessage.getClass());  return xstream.toXML(videoMessage);  }   /**  * 音乐对象的转换成xml  *  */  public static String musicMessageToXml(MusicMessage musicMessage) {  xstream.alias("xml", musicMessage.getClass());  return xstream.toXML(musicMessage);  }  /**  * 图文对象转换成xml  *  */  public static String newsMessageToXml(NewsMessage newsMessage) {  xstream.alias("xml", newsMessage.getClass());  xstream.alias("item", new Article().getClass());  return xstream.toXML(newsMessage);  }   /**  * 图片对象转换成xml  *  */   public static String imageMessageToXml(ImageMessage imageMessage)  {  xstream.alias("xml",imageMessage.getClass());  return xstream.toXML(imageMessage);   }   /**  * 链接对象转换成xml  *  */   public static String linkMessageToXml(LinkMessage linkMessage)  {  xstream.alias("xml",linkMessage.getClass());  return xstream.toXML(linkMessage);   }   /**  * 地理位置对象转换成xml  *  */   public static String locationMessageToXml(LocationMessage locationMessage)  {  xstream.alias("xml",locationMessage.getClass());  return xstream.toXML(locationMessage);   }   /**  * 拓展xstream,使得支持CDATA块  *  */  private static XStream xstream = new XStream(new XppDriver(){  public HierarchicalStreamWriter createWriter(Writer out){  return new PrettyPrintWriter(out){  //对所有的xml节点的转换都增加CDATA标记  boolean cdata = true;    @SuppressWarnings("unchecked")  public void startNode(String name,Class clazz){   super.startNode(name,clazz);  }    protected void writeText(QuickWriter writer,String text){   if(cdata){   writer.write("");   }else{   writer.write(text);   }  }  };  }  });  } ,>,string>,string>

5)、BaseMessage.java消息基类(包括:开发者微信号、用户账户、创建时间、消息类型、消息ID变量),文本、视频、图片消息都会继承此基类,在此基础上扩展自己的变量,可根据开发者文档中的各种消息属性进行定义

package cn.jon.wechat.message.req; /**  * 消息基类 (普通用户-公众号)  * @author jon  */ public class BaseMessage {   //开发者微信号  private String ToUserName;  //发送方账号(一个openId)  private String FromUserName;  //消息创建时间(整型)  private long CreateTime;  //消息类型(text/image/location/link...)  private String MsgType;  //消息id 64位整型  private String MsgId;   public BaseMessage() {  super();  // TODO Auto-generated constructor stub  }   public BaseMessage(String toUserName, String fromUserName, long createTime,  String msgType, String msgId) {  super();  ToUserName = toUserName;  FromUserName = fromUserName;  CreateTime = createTime;  MsgType = msgType;  MsgId = msgId;  }   public String getToUserName() {  return ToUserName;  }   public void setToUserName(String toUserName) {  ToUserName = toUserName;  }   public String getFromUserName() {  return FromUserName;  }   public void setFromUserName(String fromUserName) {  FromUserName = fromUserName;  }  public long getCreateTime() {  return CreateTime;  }   public void setCreateTime(long createTime) {  CreateTime = createTime;  }  public String getMsgType() {  return MsgType;  }   public void setMsgType(String msgType) {  MsgType = msgType;  }  public String getMsgId() {  return MsgId;  }   public void setMsgId(String msgId) {  MsgId = msgId;  } } 

6)、TextMessage.java文本消息,继承自5中基类,扩展内容属性

package cn.jon.wechat.message.req; /**  * 文本消息  * @author jon  */ public class TextMessage extends BaseMessage{  //消息内容  private String content;   public String getContent() {  return content;  }   public void setContent(String content) {  this.content = content;  }  } 

7)、ImageMessage.java图片消息 

package cn.jon.wechat.message.req; /**  * 图片消息  * @author jon  */ public class ImageMessage extends BaseMessage{  //图片链接  private String PicUrl;   public String getPicUrl() {  return PicUrl;  }   public void setPicUrl(String picUrl) {  PicUrl = picUrl;  } } 

8)、VideoMessage.java视频消息

package cn.jon.wechat.message.req;  public class VideoMessage extends BaseMessage {   private String mediaId;  private String thumbMediaId;  public String getMediaId() {  return mediaId;  }  public void setMediaId(String mediaId) {  this.mediaId = mediaId;  }  public String getThumbMediaId() {  return thumbMediaId;  }  public void setThumbMediaId(String thumbMediaId) {  this.thumbMediaId = thumbMediaId;  }  } 

其他消息类可根据开发者文档自行进行完成,另外,开发者也可以申请公众平台测试账号,对开发的相关内容进行测试。

以上就是Java微信公众号开发实例的全部内容,希望对大家的学习有所帮助,也希望大家多多支持错新技术频道。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表