微信公众号开发学习

微信公众号开发学习

1、Readme说明:微信公众号平台开发最好用PHP,但Java也是可以实现的,下面代码用Java语言演示了HttpURLConnection的使用,成为公众号开发者,接收微信公众号信息,响应文本消息,发布菜单,获取用户基本信息等操作。

下面会给出供参考的程序源代码。

 

2、XStream简单介绍:

1XStream可以将Java对象和xml文档之间相互转换,而且可以修改某个特定的属性和节点名称,而且也支持json的转换。

2Javaxml,用toXML()方法。

XmlJava,用fromXML()方法。

(3)在没有任何设置默认情况下,Javaxml的映射,是Java成员名对应xml的元素名,Java类的全名对应xml根元素的名字。而实际中,往往是xmljava类都有了,需要相互转换,必须进行别名映射。

(4)别名配置包括三种情况:

①类别名,用aliasString nameClass type

②类成员别名,用aliasFieldString aliasClass definedInString fieldName

③类成员作为属性别名,用aliasAttributeClass definedInString attributeNameString alias),单独命名没有意义,还要通过useAttributeForClass definedInString fieldName)应用到某个类上。


3、下面是包及类的关系图:

微信公众号开发学习_第1张图片


4、源代码:

(1)action包

****action

********MainAction.java

********TestAction.java

①MainAction.java

package com.remoa.action;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.remoa.common.util.ConfigureUtil;
import com.remoa.common.util.MessageUtil;
import com.remoa.common.util.SignUtil;
import com.remoa.domain.message.TextResponse;
import com.remoa.domain.message.WeixinRequest;

/**
 * 处理事务逻辑的主类(验证登录,接收消息及回复消息等)
 * @author Remoa
 *
 */
@WebServlet("/MainAction")
public class MainAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
    private static final String charset = ConfigureUtil.getValue("charset");   
    
    public MainAction() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("MainAction.doGet():start!");
		response.setCharacterEncoding(charset);
		request.setCharacterEncoding(charset);
		//获取必要的参数,验证服务器地址的有效性
		String token = request.getParameter("token");//密码
		String signature = request.getParameter("signature");//微信加密签名
		String timestamp = request.getParameter("timestamp");//时间戳
		String nonce = request.getParameter("nonce");//随机数
		String echostr = request.getParameter("echostr");//随机字符串
		System.out.println(signature + " " + echostr);
		//调用登录工具类进行验证
		boolean sign = SignUtil.validSign(signature, token, timestamp, nonce);
		ServletOutputStream outputStream = response.getOutputStream();
		//验证成功则返回随机字符串内容,否则验证失败
		if(sign){	
			outputStream.write(echostr.getBytes());
			outputStream.flush();
		}else{
			outputStream.write("验证失败".getBytes());
			outputStream.flush();
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("MainAction.doPost():start!");
		request.setCharacterEncoding(charset);
		response.setCharacterEncoding(charset);
		ServletInputStream inputStream = request.getInputStream();//获取微信请求消息
		WeixinRequest xinReq = MessageUtil.fromXmlToWeixinReq(inputStream);//将xml字符串转换为WeixinRequest对象
		TextResponse textResponse = new TextResponse();
		textResponse.setToUserName(xinReq.getFromUserName());//实现响应的开发者微信号
		textResponse.setFromUserName(xinReq.getToUserName());//响应传达的接收方账号
		textResponse.setCreateTime(System.currentTimeMillis());//返回系统当前时间
		textResponse.setMsgType("text");//响应文本消息
		textResponse.setContent("小编已收到您的消息");//回复的消息内容
		String respStr = MessageUtil.toXmlFromResp(textResponse);
		response.getOutputStream().write(respStr.getBytes());
	}	
}

②TestAction.java

package com.remoa.action;

import java.io.IOException;
import java.util.Scanner;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 此类用于测试连接成功后接收消息是否成功
 * @author Remoa
 *
 */
@WebServlet("/TestAction")
public class TestAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public TestAction() {
        super();
    }
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletInputStream inputStream = request.getInputStream();
		Scanner scanner = new Scanner(inputStream, "UTF-8");
		while(scanner.hasNextLine()){
			System.out.println(scanner.nextLine());
		}
		scanner.close();
	}
}

(2)common包

****common

********util

************ConfigureUtil.java

************HttpUtil.java

************MessageUtil.java

************SignUtil.java

ConfigureUtil.java

package com.remoa.common.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 获取配置信息工具类
 * @author Remoa
 *
 */
public class ConfigureUtil {
	private static Properties pro;
	static{
		InputStream is = ConfigureUtil.class.getClassLoader().getResourceAsStream("conf.properties");//通过类加载器返回作为输入流读取配置文件
		pro = new Properties();
		try {
			pro.load(is);//从输入流中读取属性列表
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("发生了I/O异常错误");
		}
	}
	
	/**
	 * 从配置文件中获得属性值
	 * @param key 键
	 * @return value 返回键对应的值
	 */
	public static String getValue(String key){
		return pro.getProperty(key);
	}
	
	/**
	 * 仅用于测试该配置信息工具类是否能获取到配置文件中的值
	 * @param args
	 */
	public static void main(String[] args){
		String value = ConfigureUtil.getValue("charset");
		System.out.println(value);
	}
}

HttpUtil.java

package com.remoa.common.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

import sun.net.www.protocol.http.HttpURLConnection;

/**
 * Http连接工具类
 * @author Remoa
 *
 */
public class HttpUtil {
	
	/**
	 * 发送http请求
	 * @param url 请求地址
	 * @param method 请求方法
	 * @param param 请求参数
	 * @param charset 字符集
	 * @return 返回请求结果
	 */
	public static String sendHttpReq(String url, String method, String param, String charset){
		HttpURLConnection httpURLConnection = null;//生成请求连接到Http服务器
		BufferedOutputStream bufferedOutputStream = null;// 缓冲输出流
		BufferedReader bufferedReader = null;//读取字符输入流
		URL urlObj;
		try {
			urlObj = new URL(url);
			httpURLConnection = (HttpURLConnection)urlObj.openConnection();//连接url所引用的远程对象
		} catch (MalformedURLException e) {
			e.printStackTrace();
			System.out.println("出现了使用未知协议错误");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("出现了I/O异常错误");
		}
		httpURLConnection.setDoInput(true);//读取指定url服务器的资源
		if(param != null){
			httpURLConnection.setDoOutput(true);//写入数据到指定url服务器
		}
		httpURLConnection.setUseCaches(false);//不允许连接使用缓存
		httpURLConnection.setReadTimeout(1000 * 60);//设置读超时,此处设置为1分钟,单位为毫秒
		httpURLConnection.setConnectTimeout(1000 * 60);//设置建立连接超时,此处设置为1分钟,单位为毫秒
		try {
			httpURLConnection.setRequestMethod(method);
		} catch (ProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("无法重置方法或者请求的方法对 HTTP 无效");
		}//设置请求方法
		try {
			if(param != null){
				bufferedOutputStream = new BufferedOutputStream(httpURLConnection.getOutputStream());
				bufferedOutputStream.write(param.getBytes());
				bufferedOutputStream.flush();
				bufferedOutputStream.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("缓冲输出流出现了I/O异常错误");
		}
		try {
			bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), charset));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("读取字符输入流出现了I/O异常错误");
		}
		StringBuilder stringBuilder = new StringBuilder();//提供了与StringBuffer兼容的api,当字符缓冲区被单个线程所使用时,优先使用此类,因为其比StringBuffer要快
		String line = null;
		//读取一个文本行操作
		try {
			if((line = bufferedReader.readLine()) != null){
				stringBuilder.append(line).append("\n");
			}
			bufferedReader.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("读取字符输入流出现了I/O异常错误");
		}
		httpURLConnection.disconnect();//指示近期服务器不太可能有其他请求
		return stringBuilder.toString();
	}
	
	/**
	 * 实现关闭流、关闭连接的功能
	 * @param reader 关闭字符读取流
	 * @param inputStream 关闭输入流
	 * @param outputStream 关闭输出流
	 * @param httpURLConnection 关闭http服务器连接
	 */
	public static void closeAll(Reader reader, InputStream inputStream, OutputStream outputStream, HttpURLConnection httpURLConnection) {
		//关闭字符流
		if(reader != null){
			try {
				reader.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("发生I/O错误");
			}
		}
		if(inputStream != null){
			try {
				inputStream.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("发生I/O错误");
			}
		}
		if(outputStream != null){
			try {
				outputStream.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println("发生I/O错误");
			}
		}
		if(httpURLConnection != null){
			httpURLConnection.disconnect();
		}
	}
	
	/**
	 * 实现上传素材的功能
	 * @param url 请求地址
	 * @param filePath 文件路径
	 * @param charset 字符编码方式
	 * @return String 表单地址
	 */
	public static String upload(String url, String filePath, String charset) {
		HttpURLConnection httpURLConnection = null;//生成请求连接到Http服务器
		BufferedOutputStream bufferedOutputStream = null;// 缓冲输出流
		BufferedReader bufferedReader = null;//读取字符输入流
		BufferedInputStream fileInput = null;
		URL urlObj;
		try {
			urlObj = new URL(url);
			httpURLConnection = (HttpURLConnection)urlObj.openConnection();//连接url所引用的远程对象
		} catch (MalformedURLException e) {
			e.printStackTrace();
			System.out.println("出现了使用未知协议错误");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("出现了I/O异常错误");
		}
		httpURLConnection.setDoInput(true);//允许读取指定url服务器的资源
		httpURLConnection.setDoOutput(true);//允许写入数据到指定url服务器
		httpURLConnection.setUseCaches(false);//不允许连接使用缓存
		httpURLConnection.setReadTimeout(1000 * 60);//设置读超时,此处设置为1分钟,单位为毫秒
		httpURLConnection.setConnectTimeout(1000 * 60);//设置建立连接超时,此处设置为1分钟,单位为毫秒
		try {
			httpURLConnection.setRequestMethod("POST");//设置请求方法
		} catch (ProtocolException e) {
			e.printStackTrace();
			System.out.println("无法重置方法或者请求的方法对 HTTP 无效");
		}
		String boundary = String.valueOf(System.currentTimeMillis());
		httpURLConnection.addRequestProperty("Content-Type", "multipart/form-data:boundary=" + boundary);//设置请求头
		StringBuilder headstr = new StringBuilder("----");
		headstr.append(boundary).append("\r\n").append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(filePath).append("\"").append("\r\n").append("Content-Type: application/octet-stream\r\n\r\n");//设置附件表单信息
		try {
			bufferedOutputStream = new BufferedOutputStream(httpURLConnection.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("创建输出流时发生 I/O 错误");
		}
		try {
			bufferedOutputStream.write(headstr.toString().getBytes());//写入表单信息
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("写入时发生I/O错误");
		}
		try {
			bufferedOutputStream.flush();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("刷新缓冲输出流时发生I/O错误");
		}
		//写入附件
		try {
			fileInput = new BufferedInputStream(new FileInputStream(filePath));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("没有找到文件");
		}
		byte[] bytebuf = new byte[1024];
		int len = 0;
		try {
			while((len = fileInput.read(bytebuf)) != -1){
				bufferedOutputStream.write(bytebuf, 0, len);
				bufferedOutputStream.write(("\r\n--" + boundary + "--\r\n").getBytes(charset));
				bufferedOutputStream.flush();
				bufferedOutputStream.close();
				fileInput.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("发生I/O异常");
		}
		try {
			bufferedOutputStream.write(("\r\n--" + boundary + "--\r\n").getBytes(charset));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			System.out.println("不支持该字符编码");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("发生I/O异常");
		}
		try {
			bufferedOutputStream.flush();
			bufferedOutputStream.close();
			fileInput.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("发生I/O异常");
		}
		StringBuilder stringBuilder = null;
		try {
			bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), charset));
			String line = null;
			stringBuilder = new StringBuilder();//提供了与StringBuffer兼容的api,当字符缓冲区被单个线程所使用时,优先使用此类,因为其比StringBuffer要快
			while((line = bufferedReader.readLine()) != null){
				stringBuilder.append(line).append("\n");
			}
			bufferedReader.close();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			System.out.println("不支持该字符编码");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("发生I/O异常");
		}
		httpURLConnection.disconnect();
		return stringBuilder.toString();
	}		
}

③MessageUtil.java

package com.remoa.common.util;

import java.io.InputStream;
import java.util.Scanner;

import com.remoa.domain.message.TextResponse;
import com.remoa.domain.message.WeixinRequest;
import com.thoughtworks.xstream.XStream;
/**
 * 消息处理工具类,包括接收消息及发送消息的处理
 * @author Remoa
 *
 */
public class MessageUtil {
	public static final String charset = ConfigureUtil.getValue("charset");
	/**
	 * 将微信请求接收到的xml字符串转换为Java处理微信消息请求的类WeixinRequest对象
	 * @param in ServletInputStream输入流
	 * @return fromXML 返回WeixinRequest对象
	 */
	public static WeixinRequest fromXmlToWeixinReq(InputStream in){
		Scanner scan = new Scanner(in, charset);//从指定流中构造一个新的扫描器
		StringBuffer str = new StringBuffer();
		while(scan.hasNextLine()){
			str.append(scan.nextLine()).append("\r\n");
		}
		scan.close();
		System.out.println(str.toString());
		XStream xStream = new XStream();
		xStream.alias("xml", WeixinRequest.class);
		WeixinRequest fromXML = (WeixinRequest)xStream.fromXML(str.toString());
		System.out.println(fromXML);
		return fromXML;
	}
	
	/**
	 * 将文本消息响应结果转换为xml字符串
	 * @param textResponse 文本消息响应对象
	 * @return toxml 返回xml字符串
	 */
	public static String toXmlFromResp(TextResponse textResponse){
		XStream xStream = new XStream();
		xStream.alias("xml", TextResponse.class);
		String toXml = xStream.toXML(textResponse);
		System.out.println(toXml.toString());
		return toXml;
	}
}

④SignUtil.java

package com.remoa.common.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
 * 登录工具类
 * @author Remoa
 *
 */
public class SignUtil {
	//开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数:
	/**
	 * 判断登录的有效性
	 * @param signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
	 * @param token 密码
	 * @param timestamp 时间戳
	 * @param nonce 随机数
	 * @return boolean 返回判断值true或false
	 */
	public static boolean validSign(String signature, String token, String timestamp, String nonce){
		String[] paramArr = new String[]{token, timestamp, nonce};
		Arrays.sort(paramArr);//Arrays类用来操作数组(比如排序和搜索)的各种方法。sort对数组按数字升序进行排序。
		StringBuilder sb = new StringBuilder(paramArr[0]);
		sb.append(paramArr[1]).append(paramArr[2]);
		String ciphertext = null;
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");//为应用程序提供信息摘要算法的功能
			byte[] digest = md.digest(sb.toString().getBytes());
			ciphertext = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false;
	}
	
	private static String byteToStr(byte[] byteArray) {
		String rst = "";
		for (int i = 0; i < byteArray.length; i++) {
			rst += byteToHex(byteArray[i]);
		}
		return rst;
	}
	
	private static String byteToHex(byte b) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
		char[] tempArr = new char[2];
		tempArr[0] = Digit[(b >>> 4) & 0X0F];
		tempArr[1] = Digit[b & 0X0F];
		String s = new String(tempArr);
		return s;
	}
}

(3)domain包

****domain

********AccessToken

************AccessToken.java

********menu

************Menu.java

************MyButton.java

********message

************BaseMessageResponse.java

************ErrorMessage.java

************ImageResponseMessage.java

************TextResponse.java

************WeixinRequest.java

********user

************UserInfo.java

①AccessToken.java

package com.remoa.domain.AccessToken;
/**
 * 接口调用凭据获取类
 * @author Remoa
 *
 */
public class AccessToken {
	private String access_token;//获取到的凭证
	private long expires_in;//凭证有效时间(单位:秒)
	public String getAccess_token() {
		return access_token;
	}
	public void setAccess_token(String access_token) {
		this.access_token = access_token;
	}
	public long getExpires_in() {
		return expires_in;
	}
	public void setExpires_in(long expires_in) {
		this.expires_in = expires_in;
	}
}

②Menu.java

package com.remoa.domain.menu;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
/**
 * 菜单实体类
 * @author Remoa
 *
 */
public class Menu {
	private List<MyButton> button = new ArrayList<MyButton>();

	public List<MyButton> getButton() {
		return button;
	}
	public void setButton(List<MyButton> button) {
		this.button = button;
	}
	public void addButton(MyButton button){
		this.getButton().add(button);
	}
	public static Menu getDefaultMenu(){
		Menu menu = new Menu();
		MyButton button1 = new MyButton();
		button1.setName("五绝风采");
		button1.setType("click");
		button1.setKey("Superman");
		MyButton button1_1 = new MyButton();
		button1_1.setName("黄药师");
		button1_1.setType("click");
		button1_1.setKey("Doctor Huang");
		MyButton button1_2 = new MyButton();
		button1_2.setName("欧阳锋");
		button1_2.setType("click");
		button1_2.setKey("Feng Ouyang");
		button1.addSub_button(button1_1);
		button1.addSub_button(button1_2);
		
		MyButton button2 = new MyButton();
		button2.setName("百度一下");
		button2.setType("view");
		button2.setUrl("http://www.baidu.com");
		
		menu.addButton(button1);
		menu.addButton(button2);
		return menu;
	}
	public static void main(String[] args){
		Menu menu = Menu.getDefaultMenu();
		System.out.println(JSON.toJSONString(menu, true));
	}
}

③MyButton.java

package com.remoa.domain.menu;

import java.util.ArrayList;
import java.util.List;

/**
 * 菜单上的按钮实体类定义
 * @author Remoa
 *
 */
public class MyButton {
	private List<MyButton> sub_button = new ArrayList<MyButton>();//二级菜单数组,个数应为1~5个
	private String type;//菜单的响应动作类型
	private String name;//菜单标题,不超过16个字节,子菜单不超过40个字节
	private String key;//菜单KEY值,用于消息接口推送,不超过128字节,click等点击类型必须
	private String url;//网页链接,用户点击菜单可打开链接,不超过1024字节,view类型必须
	private String media_id;//调用新增永久素材接口返回的合法media_id,media_id类型和view_limited类型必须
	public void addSub_button(MyButton button){
		this.sub_button.add(button);
	}
	public List<MyButton> getSub_button() {
		return sub_button;
	}
	public void setSub_button(List<MyButton> sub_button) {
		this.sub_button = sub_button;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getKey() {
		return key;
	}
	public void setKey(String key) {
		this.key = key;
	}
	public String getUrl() {
		return url;
	}
	public void setUrl(String url) {
		this.url = url;
	}
	public String getMedia_id() {
		return media_id;
	}
	public void setMedia_id(String media_id) {
		this.media_id = media_id;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Button [sub_button=" + sub_button + ",type=" + type + ",name=" + name + "]";
	}
}

④BaseMessageResponse.java

package com.remoa.domain.message;
/**
 * 回复各类信息其所含参数构成的基础类
 * @author Remoa
 *
 */
public class BaseMessageResponse {
	private String ToUserName;//开发者微信号
	private String FromUserName;//发送方账号,一个openID
	private long CreateTime;//消息创建时间 (整型)
	private String MsgType;//消息类型
	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;
	}
}

⑤ErrorMessage.java

package com.remoa.domain.message;
/**
 * 出现错误时信息类
 * @author Remoa
 *
 */
public class ErrorMessage {
	private long errcode;//错误码
	private String errmsg;//错误信息
	public long getErrcode() {
		return errcode;
	}
	public void setErrcode(long errcode) {
		this.errcode = errcode;
	}
	public String getErrmsg() {
		return errmsg;
	}
	public void setErrmsg(String errmsg) {
		this.errmsg = errmsg;
	}
}

⑥ImageResponseMessage.java

package com.remoa.domain.message;
/**
 * 回复图片消息
 * @author Remoa
 *
 */
public class ImageResponseMessage extends BaseMessageResponse{
	private Image image = new Image();
	public String getMediaId() {
		return image.getMediaId();
	}
	public void setMediaId(String mediaId) {
		image.setMediaId(mediaId);
	}
	public Image getImage() {
		return image;
	}
	public void setImage(Image image) {
		this.image = image;
	}
}
/**
 * 图片类
 * @author Remoa
 *
 */
class Image{
	private String MediaId;//图片消息媒体id,可以调用多媒体文件下载接口拉取数据。
	public String getMediaId() {
		return MediaId;
	}
	public void setMediaId(String mediaId) {
		MediaId = mediaId;
	}
}

⑦TextResponse.java

package com.remoa.domain.message;
/**
 * 回复文本消息
 * @author Remoa
 *
 */
public class TextResponse extends BaseMessageResponse{
	private String Content;//文本消息内容
	public String getContent() {
		return Content;
	}

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

⑧WeixinRequest.java

package com.remoa.domain.message;
/**
 * 处理公众号请求类
 * @author Remoa
 *
 */
public class WeixinRequest {
	private String ToUserName;//接收方帐号(收到的OpenID)
	private String FromUserName;//开发者微信号
	private long CreateTime;//消息创建时间 (整型)
	private String MsgType;//消息类型
	private String Content;//回复文本消息特有,回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)
	//用户未关注时,进行关注后的事件推送的特有参数
	private String MsgId;//回复图片消息,通过素材管理接口上传多媒体文件,得到的id。
	private String Event;//事件类型,subscribe
	private String EventKey;//事件KEY值,qrscene_为前缀,后面为二维码的参数值
	private String Ticket;//二维码的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(int createTime) {
		CreateTime = createTime;
	}

	public String getMsgType() {
		return MsgType;
	}

	public void setMsgType(String msgType) {
		MsgType = msgType;
	}

	public String getContent() {
		return Content;
	}

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

	public String getMsgId() {
		return MsgId;
	}

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

	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 getTicket() {
		return Ticket;
	}

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

	@Override
	public String toString() {
		return "WeiXinReq [ToUserName=" + ToUserName + ", FromUserName=" + FromUserName + ", CreateTime=" + CreateTime + ", MsgType=" + MsgType + ", Content=" + Content + ", MsgId=" + MsgId + ", Event=" + Event + ", EventKey=" + EventKey + ", Ticket=" + Ticket + "]";
	}
}


⑨UserInfo.java

package com.remoa.domain.user;
 /* 获取用户基本信息(UnionID机制)在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID
 * (加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。
 * 公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。
 * @author Remoa
 *
 */
public class UserInfo {
	private int subscribe;//用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
	private String openid;//用户的标识,对当前公众号唯一
	private int sex;//用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
	private String city;//用户所在城市
	private String country;//用户所在国家
	private String province;//用户所在省份
	private String language;//用户的语言,简体中文为zh_CN
	private String headimgurl;//用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
	private String subscribe_time;//用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
	private String unionid;//只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
	private String remark;//公众号运营者对粉丝的备注,公众号运营者可在微信公众平台用户管理界面对粉丝添加备注
	private String groupid;//用户所在的分组ID
	public int getSubscribe() {
		return subscribe;
	}
	public void setSubscribe(int subscribe) {
		this.subscribe = subscribe;
	}
	public String getOpenid() {
		return openid;
	}
	public void setOpenid(String openid) {
		this.openid = openid;
	}
	public int getSex() {
		return sex;
	}
	public void setSex(int sex) {
		this.sex = sex;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getCountry() {
		return country;
	}
	public void setCountry(String country) {
		this.country = country;
	}
	public String getProvince() {
		return province;
	}
	public void setProvince(String province) {
		this.province = province;
	}
	public String getLanguage() {
		return language;
	}
	public void setLanguage(String language) {
		this.language = language;
	}
	public String getHeadimgurl() {
		return headimgurl;
	}
	public void setHeadimgurl(String headimgurl) {
		this.headimgurl = headimgurl;
	}
	public String getSubscribe_time() {
		return subscribe_time;
	}
	public void setSubscribe_time(String subscribe_time) {
		this.subscribe_time = subscribe_time;
	}
	public String getUnionid() {
		return unionid;
	}
	public void setUnionid(String unionid) {
		this.unionid = unionid;
	}
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	public String getGroupid() {
		return groupid;
	}
	public void setGroupid(String groupid) {
		this.groupid = groupid;
	}
}

你可能感兴趣的:(源代码,fastjson,xstream,微信公众号开发)