java个人微信消息接收_java接口接收json数据

java个人微信消息接收_java接口接收json数据微信公众平台java服务器认证、接收文本消息和图片消息并实现返回,订阅服务号实现了通过微信接收信息转发至java后台解析并回复的消息的简单功能,贡献出代码希望能给大家一个参考

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

最近公司在开发微信项目,所以自己也试着申请了个人的订阅服务号,实现了通过微信接收信息转发至java后台解析并回复的消息的简单功能,在还没忘记的时候记录一下,以便日后查阅,并且贡献出代码希望能给大家一个参考。

好首先你要看下面的示例,要事先申请微信公众平台的订阅服务号(个人只能申请这个),地址https://mp.weixin.qq.com ,申请的范例我这里就不讲了,一般根据提示可以自行完成,如果这都完成不了,那只能去度娘翻翻了。

要想让用户发送给公众帐号的消息转发给java后台服务器,首先要 在开发者中心 进行 服务器配置

下图为认证启动后小效果:

 

你要先进入到 修改配置里面,如下图:

 

你要填写这几个文本框内的内容,

1.URL 不用解释了,就是微信将用户发来的消息转发到你服务器的请求的地址,我让微信把请求发送到本地服务这样方便调试。

推荐一款反向代理的工具 pagekite.net ,感兴趣的朋友可以去搜索一下。使用相当方便,就是需要python2.7.x环境支持,然后运行下载的一个脚本,输入你的邮箱,然后在输入你要设置的域名前缀,就搞定,下次运行就不用在输入,它影射的是本地80端口,所以你启动服务的时候记得改成80端口就对了,还有这个貌似对于一个邮箱只有31天和5个连接的限制,PS:邮箱这东西都是免费的,你懂的。

2.Token:这个长度符合就行 自己随意

3.EncodingAESKey:点击随机生成 就OK

 

下面介绍我的代码:

我的开发环境是eclipse+springMvc

“/chat” 是我最终项目的请求Controller URL路径

下面是homecontroller

 

@Controller
@RequestMapping("/*")
public class HomeController {

	private String Token = "123456789abcdef";

	@RequestMapping(value = "chat", method = { RequestMethod.GET, RequestMethod.POST })
	@ResponseBody
	public void liaotian(Model model, HttpServletRequest request, HttpServletResponse response) {
		System.out.println("进入chat");
		boolean isGet = request.getMethod().toLowerCase().equals("get");
		if (isGet) {
			String signature = request.getParameter("signature");
			String timestamp = request.getParameter("timestamp");
			String nonce = request.getParameter("nonce");
			String echostr = request.getParameter("echostr");
			System.out.println(signature);
			System.out.println(timestamp);
			System.out.println(nonce);
			System.out.println(echostr);
			access(request, response);
		} else {
			// 进入POST聊天处理
			System.out.println("enter post");
			try {
				// 接收消息并返回消息
				acceptMessage(request, response);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 验证URL真实性
	 * 
	 * @author morning
	 * @date 2015年2月17日 上午10:53:07
	 * @param request
	 * @param response
	 * @return String
	 */
	private String access(HttpServletRequest request, HttpServletResponse response) {
		// 验证URL真实性
		System.out.println("进入验证access");
		String signature = request.getParameter("signature");// 微信加密签名
		String timestamp = request.getParameter("timestamp");// 时间戳
		String nonce = request.getParameter("nonce");// 随机数
		String echostr = request.getParameter("echostr");// 随机字符串
		List<String> params = new ArrayList<String>();
		params.add(Token);
		params.add(timestamp);
		params.add(nonce);
		// 1. 将token、timestamp、nonce三个参数进行字典序排序
		Collections.sort(params, new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				return o1.compareTo(o2);
			}
		});
		// 2. 将三个参数字符串拼接成一个字符串进行sha1加密
		String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));
		if (temp.equals(signature)) {
			try {
				response.getWriter().write(echostr);
				System.out.println("成功返回 echostr:" + echostr);
				return echostr;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		System.out.println("失败 认证");
		return null;
	}

	private void acceptMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 处理接收消息
		ServletInputStream in = request.getInputStream();
		// 将POST流转换为XStream对象
		XStream xs = SerializeXmlUtil.createXstream();
		xs.processAnnotations(InputMessage.class);
		xs.processAnnotations(OutputMessage.class);
		// 将指定节点下的xml节点数据映射为对象
		xs.alias("xml", InputMessage.class);
		// 将流转换为字符串
		StringBuilder xmlMsg = new StringBuilder();
		byte[] b = new byte[4096];
		for (int n; (n = in.read(b)) != -1;) {
			xmlMsg.append(new String(b, 0, n, "UTF-8"));
		}
		// 将xml内容转换为InputMessage对象
		InputMessage inputMsg = (InputMessage) xs.fromXML(xmlMsg.toString());

		String servername = inputMsg.getToUserName();// 服务端
		String custermname = inputMsg.getFromUserName();// 客户端
		long createTime = inputMsg.getCreateTime();// 接收时间
		Long returnTime = Calendar.getInstance().getTimeInMillis() / 1000;// 返回时间

		// 取得消息类型
		String msgType = inputMsg.getMsgType();
		// 根据消息类型获取对应的消息内容
		if (msgType.equals(MsgType.Text.toString())) {
			// 文本消息
			System.out.println("开发者微信号:" + inputMsg.getToUserName());
			System.out.println("发送方帐号:" + inputMsg.getFromUserName());
			System.out.println("消息创建时间:" + inputMsg.getCreateTime() + new Date(createTime * 1000l));
			System.out.println("消息内容:" + inputMsg.getContent());
			System.out.println("消息Id:" + inputMsg.getMsgId());

			StringBuffer str = new StringBuffer();
			str.append("<xml>");
			str.append("<ToUserName><![CDATA[" + custermname + "]]></ToUserName>");
			str.append("<FromUserName><![CDATA[" + servername + "]]></FromUserName>");
			str.append("<CreateTime>" + returnTime + "</CreateTime>");
			str.append("<MsgType><![CDATA[" + msgType + "]]></MsgType>");
			str.append("<Content><![CDATA[你说的是:" + inputMsg.getContent() + ",吗?]]></Content>");
			str.append("</xml>");
			System.out.println(str.toString());
			response.getWriter().write(str.toString());
		}
		// 获取并返回多图片消息
		if (msgType.equals(MsgType.Image.toString())) {
			System.out.println("获取多媒体信息");
			System.out.println("多媒体文件id:" + inputMsg.getMediaId());
			System.out.println("图片链接:" + inputMsg.getPicUrl());
			System.out.println("消息id,64位整型:" + inputMsg.getMsgId());

			OutputMessage outputMsg = new OutputMessage();
			outputMsg.setFromUserName(servername);
			outputMsg.setToUserName(custermname);
			outputMsg.setCreateTime(returnTime);
			outputMsg.setMsgType(msgType);
			ImageMessage images = new ImageMessage();
			images.setMediaId(inputMsg.getMediaId());
			outputMsg.setImage(images);
			System.out.println("xml转换:/n" + xs.toXML(outputMsg));
			response.getWriter().write(xs.toXML(outputMsg));

		}
	}

}

加密SHA1,此代码是来自网上

 

 

/*
 * 微信公众平台(JAVA) SDK
 *
 * Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved.
 * http://www.ansitech.com/weixin/sdk/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mor.util;

import java.security.MessageDigest;

/**
 * <p>
 * Title: SHA1算法
 * </p>
 * 
 */
public final class SHA1 {

	private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	/**
	 * Takes the raw bytes from the digest and formats them correct.
	 * 
	 * @param bytes
	 *            the raw bytes from the digest.
	 * @return the formatted bytes.
	 */
	private static String getFormattedText(byte[] bytes) {
		int len = bytes.length;
		StringBuilder buf = new StringBuilder(len * 2);
		// 把密文转换成十六进制的字符串形式
		for (int j = 0; j < len; j++) {
			buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
			buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
		}
		return buf.toString();
	}

	public static String encode(String str) {
		if (str == null) {
			return null;
		}
		try {
			MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
			messageDigest.update(str.getBytes());
			return getFormattedText(messageDigest.digest());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

输入信息实体类 InputMessage 

 

 

<pre name="code" class="java">/*
 * 微信公众平台(JAVA) SDK
 *
 * Copyright (c) 2014, Ansitech Network Technology Co.,Ltd All rights reserved.
 * http://www.ansitech.com/weixin/sdk/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mor.maven.demo.mavenweb.model;

import java.io.Serializable;

import com.thoughtworks.xstream.annotations.XStreamAlias;

/**
 * POST的XML数据包转换为消息接受对象
 * 
 * <p>
 * 由于POST的是XML数据包,所以不确定为哪种接受消息,<br/>
 * 所以直接将所有字段都进行转换,最后根据<tt>MsgType</tt>字段来判断取何种数据
 * </p>
 * 
 */
@XStreamAlias("xml")
public class InputMessage implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@XStreamAlias("ToUserName")
	private String ToUserName;
	@XStreamAlias("FromUserName")
	private String FromUserName;
	@XStreamAlias("CreateTime")
	private Long CreateTime;
	@XStreamAlias("MsgType")
	private String MsgType = "text";
	@XStreamAlias("MsgId")
	private Long MsgId;
	// 文本消息
	@XStreamAlias("Content")
	private String Content;
	// 图片消息
	@XStreamAlias("PicUrl")
	private String PicUrl;
	// 位置消息
	@XStreamAlias("LocationX")
	private String LocationX;
	@XStreamAlias("LocationY")
	private String LocationY;
	@XStreamAlias("Scale")
	private Long Scale;
	@XStreamAlias("Label")
	private String Label;
	// 链接消息
	@XStreamAlias("Title")
	private String Title;
	@XStreamAlias("Description")
	private String Description;
	@XStreamAlias("Url")
	private String URL;
	// 语音信息
	@XStreamAlias("MediaId")
	private String MediaId;
	@XStreamAlias("Format")
	private String Format;
	@XStreamAlias("Recognition")
	private String Recognition;
	// 事件
	@XStreamAlias("Event")
	private String Event;
	@XStreamAlias("EventKey")
	private String EventKey;
	@XStreamAlias("Ticket")
	private String Ticket;

	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 Long getMsgId() {
		return MsgId;
	}

	public void setMsgId(Long msgId) {
		MsgId = msgId;
	}

	public String getContent() {
		return Content;
	}

	public void setContent(String content) {
		Content = content;
	}

	public String getPicUrl() {
		return PicUrl;
	}

	public void setPicUrl(String picUrl) {
		PicUrl = picUrl;
	}

	public String getLocationX() {
		return LocationX;
	}

	public void setLocationX(String locationX) {
		LocationX = locationX;
	}

	public String getLocationY() {
		return LocationY;
	}

	public void setLocationY(String locationY) {
		LocationY = locationY;
	}

	public Long getScale() {
		return Scale;
	}

	public void setScale(Long scale) {
		Scale = scale;
	}

	public String getLabel() {
		return Label;
	}

	public void setLabel(String label) {
		Label = label;
	}

	public String getTitle() {
		return Title;
	}

	public void setTitle(String title) {
		Title = title;
	}

	public String getDescription() {
		return Description;
	}

	public void setDescription(String description) {
		Description = description;
	}

	public String getURL() {
		return URL;
	}

	public void setURL(String uRL) {
		URL = uRL;
	}

	public String getEvent() {
		return Event;
	}

	public void setEvent(String event) {
		Event = event;
	}

	public String getEventKey() {
		return EventKey;
	}

	public void setEventKey(String eventKey) {
		EventKey = eventKey;
	}

	public String getMediaId() {
		return MediaId;
	}

	public void setMediaId(String mediaId) {
		MediaId = mediaId;
	}

	public String getFormat() {
		return Format;
	}

	public void setFormat(String format) {
		Format = format;
	}

	public String getRecognition() {
		return Recognition;
	}

	public void setRecognition(String recognition) {
		Recognition = recognition;
	}

	public String getTicket() {
		return Ticket;
	}

	public void setTicket(String ticket) {
		Ticket = ticket;
	}
}

 

 

 

为了加入 CDATA 验证创建的@interface类

 

 

 

 

package com.mor.maven.demo.mavenweb.model;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD })
public @interface XStreamCDATA {

}

改写的XStream工具类

 

 

package com.mor.util;

import java.io.Writer;
import java.lang.reflect.Field;

import com.mor.maven.demo.mavenweb.model.XStreamCDATA;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
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;

/**
 * xml 转换工具类
 * 
 * @author morning
 * @date 2015年2月16日 下午2:42:50
 */
public class SerializeXmlUtil {

	public static XStream createXstream() {
		return new XStream(new XppDriver() {
			@Override
			public HierarchicalStreamWriter createWriter(Writer out) {
				return new PrettyPrintWriter(out) {
					boolean cdata = false;
					Class<?> targetClass = null;

					@Override
					public void startNode(String name, @SuppressWarnings("rawtypes") Class clazz) {
						super.startNode(name, clazz);
						// 业务处理,对于用XStreamCDATA标记的Field,需要加上CDATA标签
						if (!name.equals("xml")) {
							cdata = needCDATA(targetClass, name);
						} else {
							targetClass = clazz;
						}
					}

					@Override
					protected void writeText(QuickWriter writer, String text) {
						if (cdata) {
							writer.write("<![CDATA[");
							writer.write(text);
							writer.write("]]>");
						} else {
							writer.write(text);
						}
					}
				};
			}
		});
	}

	private static boolean needCDATA(Class<?> targetClass, String fieldAlias) {
		boolean cdata = false;
		// first, scan self
		cdata = existsCDATA(targetClass, fieldAlias);
		if (cdata)
			return cdata;
		// if cdata is false, scan supperClass until java.lang.Object
		Class<?> superClass = targetClass.getSuperclass();
		while (!superClass.equals(Object.class)) {
			cdata = existsCDATA(superClass, fieldAlias);
			if (cdata)
				return cdata;
			superClass = superClass.getClass().getSuperclass();
		}
		return false;
	}

	private static boolean existsCDATA(Class<?> clazz, String fieldAlias) {
		if ("MediaId".equals(fieldAlias)) {
			return true; // 特例添加 morning99
		}
		// scan fields
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			// 1. exists XStreamCDATA
			if (field.getAnnotation(XStreamCDATA.class) != null) {
				XStreamAlias xStreamAlias = field.getAnnotation(XStreamAlias.class);
				// 2. exists XStreamAlias
				if (null != xStreamAlias) {
					if (fieldAlias.equals(xStreamAlias.value()))// matched
						return true;
				} else {// not exists XStreamAlias
					if (fieldAlias.equals(field.getName()))
						return true;
				}
			}
		}
		return false;
	}

}

输出实体类 OutputMessage 

 

 

package com.mor.maven.demo.mavenweb.model;

import com.thoughtworks.xstream.annotations.XStreamAlias;

/**
 * 
 * @author morning
 * @date 2015年2月16日 下午2:29:32
 */
@XStreamAlias("xml")
public class OutputMessage {

	@XStreamAlias("ToUserName")
	@XStreamCDATA
	private String ToUserName;

	@XStreamAlias("FromUserName")
	@XStreamCDATA
	private String FromUserName;

	@XStreamAlias("CreateTime")
	private Long CreateTime;

	@XStreamAlias("MsgType")
	@XStreamCDATA
	private String MsgType = "text";

	private ImageMessage Image;

	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 ImageMessage getImage() {
		return Image;
	}

	public void setImage(ImageMessage image) {
		Image = image;
	}

}

图片信息实体类

 

 

package com.mor.maven.demo.mavenweb.model;

import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("Image")
public class ImageMessage extends MediaIdMessage {
}

多媒体id 实体类

 

 

package com.mor.maven.demo.mavenweb.model;

import com.thoughtworks.xstream.annotations.XStreamAlias;

public class MediaIdMessage {
	@XStreamAlias("MediaId")
	@XStreamCDATA
	private String MediaId;

	public String getMediaId() {
		return MediaId;
	}

	public void setMediaId(String mediaId) {
		MediaId = mediaId;
	}

}

 

 

 

 

 

基本就这些类,也不知道拷贝全没有。

不过在输出xml的时候由于要添加CDATA标签所以没有实现完美,目前自己在SerializeXmlUtil 内添加了一下判断

 

如果是子标签下的值目前只能用这种方法加CDATA,不知道各位同学有没有好的方法。

目前只是实现了服务器认证,接收文本信息并回复原文本信息加上些附加信息,接收图片信息并返回原图片信息。

后期会有扩展,先记录到此。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171572.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 汉诺塔问题java代码_汉诺塔问题编程算法

    汉诺塔问题java代码_汉诺塔问题编程算法代码:packagecom.wangyq.datastructrue.arithmetic;importjava.util.Arrays;importjava.util.Stack;/***分治算法-汉罗塔*/publicclassDivideAndConquer{publicstaticvoidmain(String[]args){//定义一个汉罗塔TowerofHanoitowerofHanoi=newT

    2022年10月12日
    3
  • 3d工具收集_3d图表走势综合版

    3d工具收集_3d图表走势综合版Poser是Metacreations公司推出的一款三维动物、人体造型和三维人体动画制作的极品软件。用过Poser2与Poser3的朋友一定能感受到Poser的人体设计和动画制作是那么的轻松自如,制作出的作品又是那么生动。而今Poser更能为你的三维人体造型增添发型、衣服、饰品等装饰。让你的设计与创意轻松展现。Mixamo:在线3D动漫角…

    2022年8月23日
    8
  • 磁力链接文件服务器,什么是磁力链接(BT、磁力链这些词语是什么意思?)

    磁力链接文件服务器,什么是磁力链接(BT、磁力链这些词语是什么意思?)“知其然知其所以然”。我们经常在下载资料的时候能看到BT、磁力链等词语,百思特网这些词语到底是什么意思呢?下载都会用,但是你了解吗?BT下载传统的下载模式是每个客户端从服务器拷贝文件,跟校园内常用的FTP一样。因为服务器宽带是一定的,所以下载的人越多下载速度会越慢。而现在使用的下载器情况正好相反,使用的人越多文件下载速度越快。这是因为现在的下载器普遍采用类似BT的下载方式。布拉姆科恩发明了BT协议…

    2022年8月10日
    11
  • nvue踩坑2

    nvue踩坑2小透明继续写一个 继上次的探索之后又遇到了一些问题 我来再说两句吧 希望能给同样遇到问题的朋友一点启发 1 关于图片圆角 因为我做的页面上面有出现用户头像 是圆形的 需要做成图片圆角 看了一些别人的博客 他们说是在 image 外层的父容器 div 的样式上加上圆角 然后用 overflow 来切掉它 让图片变圆 可是我尝试了以后发现并没有成功 然后 我把关注点从 div 上挪开 改成在 image 上加上 border radius 就成功了 写成 50 image div div image

    2025年11月9日
    2
  • django和drf_类中的方法可以序列化么

    django和drf_类中的方法可以序列化么前言上一篇文章我们讲述了序列化,这篇就带大家一起来实现以下序列化Serializer我们使用序列化类Serializer,我们来看下源码结构,这里推荐使用pycharm左边导航栏的Structu

    2022年7月29日
    6
  • dropdown list_css中display中flex

    dropdown list_css中display中flexサンプル画面–>http://ns.adobe.com/mxml/2009″    xmlns:s=”library://ns.adobe.com/flex/spark”    xmlns:mx=”library://ns.adobe.com/flex/mx”    minWidth=”800″    minHeight=”400″>      import

    2022年10月10日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号