java微信公众平台接收发送文本消息

1.我用的是测试号,如果没有测试号的小伙伴可以去注册

http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

2.注册完成后可以按照网上的将信息配置成功

3.进入基本配置


这里需要填写的有服务器的url  Token俩个地方

URL

是一个公网地址,只能接收80端口的(http默认端口)

http://公网地址/项目名称/请求路径

Token

4.验证Token

在校验的时候需要用到,随便输入一个字符串就可以了,在自己的服务器浏览器上访问下面这个controller 可以验证token

WeixinController类中

@RequestMapping(value="/wechat")
		public @ResponseBody String getNews(HttpServletRequest request,HttpServletResponse response) throws Exception{
		
		
		2018-05-08 14:57:02,775 INFO [com.bos.controller.WeiXinController:44]
		//[signature: e71f4f0c8b5c626089d0fc939ce2a2db66897319]
		 * [timestamp: 1525762622]
		 * [nonce: 559220466]
		 * [echostr: 970164183845924479]
		微信验证成功
	       
	        //微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp,nonce参数
	        String signature = request.getParameter("signature");
	        //时间戳
	        String timestamp = request.getParameter("timestamp");
	        //随机数
	        String nonce = request.getParameter("nonce");
	        //随机字符串
	        String echostr = request.getParameter("echostr");
	        System.out.println(signature+"-----"+timestamp+"-----"+""+nonce);
	        String method=request.getMethod();
	        if("GET".equals(method)){
	        	
	        if (SignUtil.checkSignature(signature, timestamp, nonce)) {
	            logger.info("[signature: "+signature + "]<-->[timestamp: "+ timestamp+"]<-->[nonce: "+nonce+"]<-->[echostr: "+echostr+"]");
	            response.getOutputStream().println(echostr);
	            System.out.println("微信验证成功");
	            Map<String, Object> map=WeiXinController.getAccessToken();
	            System.out.println(map.get("access_token"));
	            return echostr;
	        }
	        return "";
	        }if("POST".equals(method)){
	        	System.out.println("请求方式"+method);
	        	
	        }
		return "";
	   }

package com.bos.util;


import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;


public class SignUtil {
	private static String token = "Chenggaowei";


    /**
     * 校验签名
     * @param signature 签名
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @return 布尔值
     */
    public static boolean checkSignature(String signature,String timestamp,String nonce){
        String checktext = null;
        if (null != signature) {
            //对ToKen,timestamp,nonce 按字典排序
            String[] paramArr = new String[]{token,timestamp,nonce};
            Arrays.sort(paramArr);
            //将排序后的结果拼成一个字符串
            String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);


            try {
                MessageDigest md = MessageDigest.getInstance("SHA-1");
                //对接后的字符串进行sha1加密
                byte[] digest = md.digest(content.toString().getBytes());
                checktext = byteToStr(digest);
            } catch (NoSuchAlgorithmException e){
                e.printStackTrace();
            }
        }
        //将加密后的字符串与signature进行对比
        return checktext !=null ? checktext.equals(signature.toUpperCase()) : false;
    }


    /**
     * 将字节数组转化我16进制字符串
     * @param byteArrays 字符数组
     * @return 字符串
     */
    private static String byteToStr(byte[] byteArrays){
        String str = "";
        for (int i = 0; i < byteArrays.length; i++) {
            str += byteToHexStr(byteArrays[i]);
        }
        return str;
    }


    /**
     *  将字节转化为十六进制字符串
     * @param myByte 字节
     * @return 字符串
     */
    private static String byteToHexStr(byte myByte) {
        char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        char[] tampArr = new char[2];
        tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
        tampArr[1] = Digit[myByte & 0X0F];
        String str = new String(tampArr);
        return str;
    }


以上俩个类可以将token验证成功,接下来从第5点开始就可以做接收文本消息和模板消息

5,接收消息发送文本消息,(WeixinController)有必要说一下就是我上面那个方法是我用来验证token的,我验证成功后我就把这个方法的代码改成了这个,直接是我下面这个方法,因为经过测试,方法不能有返回值

@RequestMapping(value="/wechat")
public  void getAccessToken(PrintWriter out,HttpServletRequest request,HttpServletResponse response) throws Exception{
		  
					       //第五步:后面加上用来回复消息
				           WechatService wechatService=new WechatService();
				           respMessage= wechatService.weixinPost(request);
				           System.out.println("回复的消息为:"+respMessage);
					   out.print(respMessage); // 将回应发送给微信服务器 
				}	
		}

6.WeChatService,我目前做的是客户发的是什么消息,那么返回给客户的就是什么数据

然后服务器与测试号之间是通过xml来进行传输数据的

package com.wei.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

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

import org.dom4j.DocumentException;
import org.springframework.web.socket.TextMessage;

import com.wei.pojo.TextMeaasge;

/*
 * 
 * 只是消息的自动回复
 * 
 * */
public class WechatService {
	/**
     * 处理微信发来的请求
     * 
     * @param request
     * @return
	 * @throws DocumentException 
	 * @throws IOException 
     */
    public String weixinPost(HttpServletRequest request) throws IOException, DocumentException {
    	//response.setCharacterEncoding("UTF-8");
    	Map<String, String> map = MessageUtil.xmlToMap(request);
        // 发送方帐号(一个OpenID)
        String fromUserName = map.get("FromUserName");
        // 开发者微信号
        String toUserName = map.get("ToUserName");
        // 消息类型
        String msgType = map.get("MsgType");
        // 默认回复一个"success"
        String responseMessage = "success";
        //用户输入的消息
        String message=map.get("Content");
        // 对文本消息进行处理
        if (MessageUtil.RESP_MESSAGE_TYPE_TEXT.equals(msgType)) {// 文本消息
            TextMeaasge textMessage=new TextMeaasge();
            textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
            textMessage.setToUserName(fromUserName);//注意这里的toUserName 是刚才接收xml中的FromUserName
            textMessage.setFromUserName(toUserName);
            textMessage.setCreateTime(System.currentTimeMillis());
            String str = new String(message);
            System.out.println("str-------"+str);
            textMessage.setContent(str);
            responseMessage = MessageUtil.textMessageToXML(textMessage);
            
        }else if(MessageUtil.REQ_MESSAGE_TYPE_VOICE.equals(msgType)){
        	//对语音消息进行处理
        	   responseMessage="你发送了一个消息";
        }
        return responseMessage;
        }

}

7.MessageUtil类中,这是一个工具类

 
 
package com.wei.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;
import com.wei.pojo.TextMeaasge;
/*
 * 按照微信的接口文档编写的文本消息实体类
 * 
 * */
public class MessageUtil {
	/** 
     * 返回消息类型:文本 
     */  
    public static final String RESP_MESSAGE_TYPE_TEXT = "text";  
  
    /** 
     * 返回消息类型:音乐 
     */  
    public static final String RESP_MESSAGE_TYPE_MUSIC = "music";  
  
    /** 
     * 返回消息类型:图文 
     */  
    public static final String RESP_MESSAGE_TYPE_NEWS = "news";  
  
    /** 
     * 请求消息类型:文本 
     */  
    public static final String REQ_MESSAGE_TYPE_TEXT = "text";  
  
    /** 
     * 请求消息类型:图片 
     */  
    public static final String REQ_MESSAGE_TYPE_IMAGE = "image";  
  
    /** 
     * 请求消息类型:链接 
     */  
    public static final String REQ_MESSAGE_TYPE_LINK = "link";  
  
    /** 
     * 请求消息类型:地理位置 
     */  
    public static final String REQ_MESSAGE_TYPE_LOCATION = "location";  
  
    /** 
     * 请求消息类型:音频 
     */  
    public static final String REQ_MESSAGE_TYPE_VOICE = "voice";  
  
    /** 
     * 请求消息类型:推送 
     */  
    public static final String REQ_MESSAGE_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转换成map集合
	 * 
	 * */
	public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException{
		Map<String, String> map=new HashMap<String,String>();
		SAXReader reader=new SAXReader();//使用dom4j解析xml
		InputStream ins=request.getInputStream();//从request中获取输入流
		Document doc=reader.read(ins);
		Element root=doc.getRootElement();   //获取根元素
		List<Element> list=root.elements();   //获取所有的节点
		for(Element e:list){
			map.put(e.getName(), e.getText());
			System.out.println(e.getName()+"----->"+e.getText());
		}
		ins.close();   //关流
		return map;
	}
	/*s
	 * 将文本消息对象转换成xml
	 * 
	 * 
	 * */
	 public static String textMessageToXML(TextMeaasge textMessage){
	        XStream xstream = new XStream();              // 使用XStream将实体类的实例转换成xml格式    
	        xstream.alias("xml", textMessage.getClass()); // 将xml的默认根节点替换成“xml”
	        return xstream.toXML(textMessage);
	         
	    }
	
}

8.TestMessage类,

注意:由于推送消息xml数据包格式是这样的,那么我们的实体类也要按照这个来,切忌不要改属性名,不要因为

          属性值一个大写觉得不规范。(被坑过)

<xml>  <ToUserName>< ![CDATA[toUser] ]></ToUserName>  <FromUserName>< ![CDATA[fromUser] ]></FromUserName>  <CreateTime>1348831860</CreateTime>  <MsgType>< ![CDATA[text] ]></MsgType>  <Content>< ![CDATA[this is a test] ]></Content> <MsgId>1234567890123456</MsgId>  </xml>

package com.wei.pojo;

public class TextMeaasge {
	private String FromUserName;
	private String ToUserName;
	private String MsgType;
	private long CreateTime;
	private String Content;
	public String getFromUserName() {
		return FromUserName;
	}
	public void setFromUserName(String fromUserName) {
		FromUserName = fromUserName;
	}
	public String getToUserName() {
		return ToUserName;
	}
	public void setToUserName(String toUserName) {
		ToUserName = toUserName;
	}
	public String getMsgType() {
		return MsgType;
	}
	public void setMsgType(String msgType) {
		MsgType = msgType;
	}
	public long getCreateTime() {
		return CreateTime;
	}
	public void setCreateTime(long createTime) {
		CreateTime = createTime;
	}
	public String getContent() {
		return Content;
	}
	public void setContent(String content) {
		Content = content;
	}


}

最后给大家看一下页面效果


猜你喜欢

转载自blog.csdn.net/tangthh123/article/details/80411551