精华内容
下载资源
问答
  • 微信公众平台开发入门

    万人学习 2015-01-06 11:21:27
    通过本课程的学习,学员能够入门微信公众平台开发,能够胜任企业级的订阅号、服务号、企业号的应用开发工作。 通过本课程的学习,学员能够对微信公众平台有一个清晰的、系统性的认识。例如,公众号是什么,它有什么...
  • 微信公众平台

    2014-06-19 15:16:55
    微信公众平台入门到精通》Vol.1 2 《微信公众平台入门到精通》Vol.2 10 《微信公众平台入门到精通》Vol.3 19 《微信公众平台入门到精通》Vol.4 32 《微信公众平台入门到精通》Vol.5 40 《微信公众平台入门到精通》...
  • 微信公众平台 java示例 接收消息并回复

    万次阅读 多人点赞 2015-02-17 11:24:34
    微信公众平台 java 服务器认证、接收文本消息和图片消息并实现返回,订阅服务号实现了通过微信接收信息转发至java后台解析并回复的消息的简单功能,贡献出代码希望能给大家一个参考

    最近公司在开发微信项目,所以自己也试着申请了个人的订阅服务号,实现了通过微信接收信息转发至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://mp.weixin.qq.com https://mp.weixin.qq.com ...

    以下内容,仅限于根据自己开发以及阅读微信文档总结,错误之处敬请指出,共同进步!

    一、微信公众平台、微信公众平台.小程序、微信.开放平台登录地址

    项目 微信公众平台 微信公众平台.小程序 微信。开放平台
    登录地址 https://mp.weixin.qq.com https://mp.weixin.qq.com https://open.weixin.qq.com
    登录账号 sensor@**** 1960314645**** 2851513591****
    简称 公众号平台 小程序平台 开放平台
    微信认证 每年年审,费用 300元/年 无认证费用 需要一次性认证,认证费300元

    这三个平台必须使用不同的账号申请,因为账号是邮箱地址,所以,必须使用3个不同的邮箱地址作为账号,如果某个邮箱地址已经是微信公众平台的账号,则这个邮箱地址就不能用于另外的两个平台。
    事实上,微信公众平台为了和微信公众平台.小程序区分开来,也可以称作微信公众平台.公众号。以下简称:公众号平台、小程序平台、开放平台

    二、登录成功后界面

    1. 公众号平台 (微信公众平台.公众号)
      在这里插入图片描述
    2. 小程序平台 (微信公众平台.小程序)
      在这里插入图片描述
    3. 开放平台(微信.开放平台)
      在这里插入图片描述

    三、三者之间的关系

    如果需要搞清楚三者之间的关系,就涉及到unionid。关于unionid,在【微信官方文档.公众号】是这样描述的:开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的
    开放文档
    综上结合自己的理解:
    1、公众号平台负责管理公众号;
    2、小程序平台负责管理小程序;
    3、每个平台对于某个用户都会产生一个OpenID,在单独的平台上这个OpenID是唯一的,但是如果某个用户既要使用公众号,又有小程序,那么在公众号和小程序平台上OpenID是分别不一样的。
    4、此时就需要开放平台,凡是在开放平台登记的应用,对于这个开放平台都将使用一个统一的unionID。这样就可以在不同的平台上唯一确定某个用户了。

    这么理解,公众号平台和小程序平台是相互独立的平台,可以各自开发各自的应用,如果是一个独立的应用,那么只需要使用OpenID就可以区别用户,例如如果只是使用公众号,不使用小程序,那么直接使用公众号的OpenID就可以了,繁殖对于小程序来说也是一样的。同一个用户在公众号平台和在小程序平台上的OpenID是不一样的,但是实际应用是经常会需要公众号和小程序同时使用,这样就需要使用开放平台来统一OpenID,最终出现了unionid。这个是唯一的,不变的!

    四、小程序开发中关于使用Session_Key可以解开得到unionid问题

    按照官方文档的说明,前端是可以通过 wx.login 获取到 code 登录凭证,然后在后台通过 auth.code2Session 换取openid,session_key,unionid,需要说明的是,unionid是用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回。那么满足什么样的条件会直接返回unionid呢?答案是注册认证微信开放平台,注意一定要认证,也就是说要交300元通过认证,这样后台就会直接返回unionid。否则,按照官方说的如果没有返回unionid,也可以通过session_key在后台进行解密,解密需要的相关参数需要前端通过wx.getUserInfo调用获取到userInfo,rawData,signature,encryptedData,iv,cloudID参数。后台通过加密算法解密,最终可以得到unionid。 我测试的时候,如果没有通过开放平台认证,密文数据中始终没有返回unionid,不知道不认证的情况下满足什么样的条件才会返回。

    展开全文
  • 本例中列出了微信公众平台开发的所有流程的代码,包括接收xml数据、解析xml数据、调用图灵机器人api接口获取智能回复内容、封装结果xml数据等,简单明了,不明之处可查看个人博客中的讲解。
  • 1.微信开放平台是app用的,对应一个微信商户平台。 2.微信公众平台是微信内h5用的,对应另外一个微信商户平台。 微信开放平台的商户平台和微信公众平台的商户平台不能通用。...

    1.微信开放平台是app用的,对应一个微信商户平台。

    2.微信公众平台是微信内h5用的,对应另外一个微信商户平台。

    微信开放平台的商户平台和微信公众平台的商户平台不能通用。

    展开全文
  • 微信公众平台开发 微信公众平台开发...微信公众平台开发 微信公众平台开发模式 企业微信公众平台 微信一键关注 方倍工作室  以下功能全部被屏蔽,用不了了。老老实实的用二维码吧。其他折腾都是白费力气    一

    微信公众平台开发 微信公众平台开发模式 企业微信公众平台 微信一键关注  
    整理:方倍工作室 
    原文: http://www.cnblogs.com/txw1958/p/weixin41-follow-method.html

    微信公众平台开发 微信公众平台开发模式 企业微信公众平台 微信一键关注 方倍工作室 

    以下功能全部被屏蔽,用不了了。老老实实的用二维码吧。其他折腾都是白费力气 

     

    一、使用HTTP协议

    特别推荐 <a href="http://weixin.qq.com/r/dnXk68HE5P_bh9CInyBS">豆立方</a>,点击关注。

     

    二、使用weixin协议

    <a href="weixin://profile/gh_b629c48b653e">点击关注方倍工作室</a>

    或者

    <a href="weixin://addfriend/pondbaystudio">点击关注方倍工作室</a>

     

     

    三、使用JavaScript代码

    var addWxContact = function(wxid, cb)
    {
        if (typeof WeixinJSBridge == 'undefined') return false;
            WeixinJSBridge.invoke('addContact', {
                webtype: '1',
                username: wxid
            }, function(d) {
                // 返回d.err_msg取值,d还有一个属性是err_desc
                // add_contact:cancel 用户取消
                // add_contact:fail 关注失败
                // add_contact:ok 关注成功
                // add_contact:added 已经关注
                WeixinJSBridge.log(d.err_msg);
                cb && cb(d.err_msg);
            });
    };

     

    四、部分账号专用

    https://open.weixin.qq.com/subscribe?appid=wxb629c48b653e

     

    五、订阅同时绑定,DNS专用

     解码后为

    https://login.weixin.qq.com/l/E0LsxoTaRxC_HM

     

    六、扫描二维码(推荐)

     

    七、体验

    关注方倍工作室的微信,回复9,再点击微信图标,体验一键关注

                       

     

    展开全文
  • 微信公众平台提供了一个简单的php示例代码,在做进一步开发之前,我们有必要将其详细了解一下。 二、获取代码 微信官网:http://mp.weixin.qq.com/mpres/htmledition/res/wx_sample.zip 三、分析代码 ...
  • 微信公众平台、微信开放平台的关系背景简介微信公众平台能干什么?微信开放平台(open平台)能干什么? 背景 做微信相关开发的时候,要登录很多账号,而且不同的功能要在这两个账号之间切换来切换去,很烦;所以今天...
  • 微信公众平台开发

    热门讨论 2014-05-14 10:53:28
    微信公众平台开发最佳实践 第1章简要介绍了微信及其两大平台:微信公众平台与微信开放平台,重点介绍了微信公众平台后台的各项功能。 第2章介绍了申请服务器资源的方法,包括申请新浪云及购买虚拟空间两种方式。...
  • 微信公众平台深度开发Java版 v2.0”系列课程共有6季,使用JAVA语言,系统讲解微信公众平台订阅号、服务号官方列出的全部功能接口,包括:自定义菜单、个性化菜单(按需定制菜单)、群发消息、客服消息(有限次消息...
  • 前面几篇文章一直都在说微信公众平台的开发准备工作,那么从这篇开始我们就将正式的进入JAVA微信公众平台开发的整个流程,那么这篇我们开始聊聊如何将我们的服务端和微信公众平台对接! (一)接入流程解析 ...
  • 微信公众平台测试工具

    千次下载 热门讨论 2015-04-09 15:58:41
    方便微信公众平台开发者在本地调试自己的微信公众平台应用。软件采用Java开发,需要Java运行环境。软件开源,https://github.com/subirun/WechatTestTool
  • 微信公众平台开发(二) 微信公众平台示例代码分析一、摘要微信公众平台提供了一个简单的php示例代码,在做进一步开发之前,我们有必要将其详细了解一下。二、获取代码微信官网:...
  • 微信开放平台与微信公众平台简介

    千次阅读 2016-09-18 19:06:54
    微信开放平台地址:微信开放平台微信公众平台地址:微信公众平台一、微信开放平台常用功能app: 分享与收藏 微信登录 微信支付 智能接口(具体参看文档) 网站: 微信登录 智能接口(具体参看文档) 公众账号: 消息...
  • 微信公众平台C#版SDK

    千次下载 热门讨论 2014-02-09 01:02:41
    详细介绍:微信公众平台C#版SDK,封装了微信公众平台的所有消息推送以及接受API的调用方法,方便公众平台.NET开发者轻松进行微信公众平台的开发。 作者网站:微信公众账号导航 http://www.qq8384.com 详细帮助:...
  • 微信公众平台、微信开放平台、商户平台的区别: 一.微信开放平台 主要面对移动应用/网站应用开发者,为其提供微信登录、分享、支付等相关权限和服务。 微信开放平台还提供了数据统计功能,用于开发者统计接入应用...
  • 微信公众平台二次开发的环境有3部分:微信公众账号、百度云平台、ide开发工具 当然我们也可以自己搭建服务器来代替百度平台,只要在服务器url那里改成自己对应的服务器url就行,我们后面会说到。 微信公众账号...
  • 微信公众平台开发之消息管理是子恒老师《微信公众平台开发》视频教程的第4部。详细讲解了用php开发微信,对微信公众平台中的消息管理开发。内容包含微信关键字回复,多图文消息回复开发,接收图片消息,视频,小视频...
  • 微信公众平台消息接口c#版

    千次下载 热门讨论 2012-12-13 09:12:53
    微信只有php版,自己改写的微信公众平台消息接口c#版
  • 微信公众平台开发有关与架构设计、安全、微信UI的相关知识。提供全套的开发工具,从“初级”开始讲解,教授如何注册、使用开发账号。特别的,还有专门的课程,手把手教同学们如何搭建环境。
  • 微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,并实现和特定群体的文字、图片、语音的全方位沟通、互动。 二、通讯机制 三、注册微信平台公众帐号...
  • Senparc.Weixin.MP SDK 微信公众平台开发教程(三):微信公众平台开发验证  要对接微信公众平台的"开发模式",即对接到自己的网站程序,必须在注册成功之后(见Senparc.Weixin.MP SDK 微信公众平台开发教程...
  • 微信公众平台(下面简称“公众平台”)注册步骤和导航还是比较流畅的,因此这个教程对于上网经验丰富的朋友来说,有点多余。不过为了保持教程系列的完整性,这里还是认认真真把流程梳理一遍。 第一步:
  • 学习开源 Senparc.Weixin.MP SDK 微信公众平台开发教程(一):微信公众平台注册

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,043
精华内容 8,017
关键字:

微信公众平台