微信开发入门

标签: 微信 开发 | 发表时间:2015-07-19 21:58 | 作者:liguanfeng
出处:http://www.iteye.com

【做微信平台开发需要以下步骤,wx.zip示例可以参考,修改配置即可】

1.申请一个公众号(订阅号或者服务号)

2.需要有自己的服务器(建议使用花生壳做内网映射)

3.配置微信服务器



 


 

 

4.编写后台代码

*微信入口

package com.wx.controller;

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.code.util.WeixinHanlder;
import com.code.util.WeixinHanlder.TextMsg;

@WebServlet("/weixin_service")
public class WxServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	
	/**
	 * 验证微信信息
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String signature,timestamp,nonce,echostr;
		signature = req.getParameter("signature");
		timestamp = req.getParameter("timestamp");
		nonce = req.getParameter("nonce");
		echostr = req.getParameter("echostr");
		try {
			if(WeixinHanlder.checkSgin(signature, timestamp, nonce)){
				ServletOutputStream out = resp.getOutputStream();
				out.print(echostr);
				out.close();
			}else{
				System.out.println("error invoke method failure ");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		ServletInputStream in = req.getInputStream();
		try {
			Object obj = WeixinHanlder.XML.getMessage(in);
			System.out.println(obj);
			if(obj instanceof WeixinHanlder.TextMsg){
				TextMsg msg = (TextMsg)obj;
				System.out.println(msg.getContent());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

* 微信加密工具类

package com.code.util;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import javax.servlet.ServletContext;

import net.sf.json.JSONObject;

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

/**
 * 微信开发工具类
 * @author LGF
 *
 */
public class WeixinHanlder {
	
	public static Integer CHANGE_TOKEN_TIME = 7000;
	public static String TOKEN = "weixin";
	public static String OPENID = "gh_d97c8ce11b95";
	public static String APPID = "wx1d80f7014b33404b";
	public static String APPSECRET = "7eb7a1f207e905c41b7c7bb56221e3df";
	public static String URL_ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx1d80f7014b33404b&secret=7eb7a1f207e905c41b7c7bb56221e3df";
	public static String URL_JS_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi";
	
	static{
		Properties props = new Properties();
		try {
			props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("weixin.properties"));
			OPENID = props.get("open_id").toString();
			APPID = props.get("app_id").toString();
			APPSECRET = props.get("app_secret").toString();
			TOKEN = props.get("token").toString();
			URL_ACCESS_TOKEN = props.get("url_access_token").toString();
			URL_JS_TICKET = props.get("url_js_ticket").toString();
			CHANGE_TOKEN_TIME = Integer.parseInt(props.get("change_token_time").toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 检查是否是微信发送的请求
	 * @param signature 签名
	 * @param timestamp 时间戳
	 * @param nonce 随机数
	 * @return
	 * @throws Exception
	 */
	public static boolean checkSgin(String signature,String timestamp,String nonce) throws Exception{
		String[] strs = new String[]{timestamp,nonce,TOKEN};
		Arrays.sort(strs);
		StringBuffer sb = new StringBuffer();
		for (String string : strs) {
			sb.append(string);
		}
		String sha1 = SecurityHanlder.sha1(sb.toString());
		if(sha1.equals(signature)){
			return true;
		}
		return false;
	}
	
	/**
	 * 获取系统默认时间
	 * @return
	 */
	public static Long getTime(){
		return System.currentTimeMillis();
	} 
	
	/**
	 * 关键字检索,默认逗号分隔
	 * @param source
	 * @param kws
	 * @return
	 */
	public static boolean keywordCheck(String source,String kws,String splitor){
		if(source!=null){
			String[] split = kws.split(splitor);
			for (Object kw : split) {
				if(source.indexOf(kw.toString())!=-1||(kw!=null&&kw.toString().indexOf(source)!=-1)){
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * 关键字检索,默认逗号分隔
	 * @param source
	 * @param kws
	 * @return
	 */
	public static boolean keywordCheck(String source,String kws){
		return keywordCheck(source,kws,",");
	}
	
	/**
	 * 读取字符串
	 * @param input
	 * @return
	 * @throws IOException
	 */
	public static String readString(InputStream input) throws IOException{
		BufferedInputStream bis = new BufferedInputStream(input);
		byte[] bs = new byte[1024];
		StringBuffer sb = new StringBuffer();
		while(bis.read(bs)!=-1){
			sb.append(new String(bs));
		}
		input.close();
		bis.close();
		return sb.toString();
	} 
	
	/**
	 * JS 签名验证
	 * @param jsapi_ticket
	 * @param url
	 * @return
	 */
    public static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String signature = "";

        String string1;
        //注意这里参数名必须全部小写,且必须有序
        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                  "&noncestr=" + nonce_str +
                  "&timestamp=" + timestamp +
                  "&url=" + url;
        System.out.println("************"+string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.toString().getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
    
        return ret;
    }

    /**
     * 转换成十六进制
     * @param hash
     * @return
     */
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    /**
     * 随机字符串
     * @return
     */
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    /**
     * 随机时间
     * @return
     */
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
	
	/**
	 * XML 文件处理,获取XML文件
	 * @author LGF
	 *
	 */
	public static class XML {
		
		public static  String XML = "xml";
		public static  String TOUSERNAME = "ToUserName";
		public static  String FROMUSERNAME = "FromUserName";
		public static  String CREATETIME = "CreateTime";
		public static  String MSGTYPE = "MsgType";
		public static  String CONTENT = "Content";
		
		public static  String VIDEO = "video";
		public static  String MEDIAID = "MediaId";
		
		public static  String TITLE = "Title";
		public static  String DESCRIPTION = "Description";
		
		public static  String MUSICURL = "MusicURL";
		public static  String HQMUSICURL = "HQMusicUrl";
		public static  String THUMBMEDIAID = "ThumbMediaId";
		
		public static  String ARTICLES = "Articles";
		public static  String ITEM = "item";
		public static  String PICURL = "PicUrl";
		public static  String URL = "URL";
		
		//消息类型
		public static  String MSGTYPE_TEXT = "text";
		public static  String MSGTYPE_IMAGE = "image";
		public static  String MSGTYPE_VIDO = "video";
		public static  String MSGTYPE_VOICE = "voice";
		
		/**
		 * 传入输入流获取Document对象
		 * @param input
		 * @return
		 * @throws Exception
		 */
		public static Document getDocuemnt(InputStream input) throws Exception{
			return  new SAXReader().read(input);
		}
		
		
		/**
		 * XML输入流获取一个对象
		 * @param <T>
		 * @param input
		 * @return
		 * @throws Exception
		 */
		@SuppressWarnings("unchecked")
		public static <T> T getMessage(InputStream input,Class<T> clazz) throws Exception{
			Document d = getDocuemnt(input);
			Element root = d.getRootElement();
			String type = root.element(MSGTYPE).getText();
			String to = root.element(TOUSERNAME).getText();
			String from = root.element(FROMUSERNAME).getText();
			String time = root.element(CREATETIME).getText();
			if(MSGTYPE_TEXT.equals(type)){
				String content = root.element(CONTENT).getText();
				return  (T) new TextMsg(to,from,time==null||time.isEmpty()?null:Long.parseLong(time),type,content);
			}else if(MSGTYPE_IMAGE.equals(type)){
				
			}else if(MSGTYPE_VIDO.equals(type)){
				
			}else if(MSGTYPE_VOICE.equals(type)){
				
			}
			return (T) d.asXML();
		}
		
		/**
		 * XML输入流获取一个对象
		 * @param input
		 * @return
		 * @throws Exception
		 */
		public static Object getMessage(InputStream input) throws Exception{
			return getMessage(input,Object.class);
		}
		
		/**
		 * 回复文本消息
		 * @param to
		 * @param from
		 * @param time
		 * @param type
		 * @param content
		 * @return 
		 */
		public static String getSendTextMessage(String to,Long time,String content){
			Element r = getBaseMessageElement(to,time);
			r.addElement(CONTENT).addCDATA(content);
			return r.getDocument().asXML();
		}
		
		/**
		 * 设置基本回复消息
		 * @param to
		 * @param from
		 * @param time
		 * @param type
		 * @param content
		 * @return 
		 */
		private static Element getBaseMessageElement(String to,Long time){
			Document d = DocumentHelper.createDocument();
			Element r = d.addElement(XML);
			r.addElement(TOUSERNAME).addCDATA(to);
			r.addElement(FROMUSERNAME).addCDATA(WeixinHanlder.OPENID);
			r.addElement(CREATETIME).addCDATA(time.toString());
			r.addElement(MSGTYPE).addCDATA(MSGTYPE_TEXT);
			return r;
		}
		
		/**
		 * 回复文本消息
		 * @param to
		 * @param content
		 * @return
		 */
		public static String getSendTextMessage(String to,String content){
			return getSendTextMessage(to,WeixinHanlder.getTime(),content);
		}
	}
	
	/**
	 * 微信消息父类实体
	 * @author LGF
	 *
	 */
	public static class Msg{
		
		private  String toUserName;
		private  String fromUserName;
		private  Long createTime;
		private  String msgType;
		
		public Msg(String toUserName, String fromUserName, Long createTime,
				String msgType) {
			this.toUserName = toUserName;
			this.fromUserName = fromUserName;
			this.createTime = createTime;
			this.msgType = msgType;
		}
		
		public Msg() {
			
		}

		public String getToUserName() {
			return toUserName;
		}

		public void setToUserName(String toUserName) {
			this.toUserName = toUserName;
		}

		public String getFromUserName() {
			return fromUserName;
		}

		public void setFromUserName(String fromUserName) {
			this.fromUserName = fromUserName;
		}

		public Long getCreateTime() {
			return createTime;
		}

		public void setCreateTime(Long createTime) {
			this.createTime = createTime;
		}

		public String getMsgType() {
			return msgType;
		}

		public void setMsgType(String msgType) {
			this.msgType = msgType;
		}
	}
	
	/**
	 * 文本消息实体类
	 * @author LGF
	 *
	 */
	public static class TextMsg extends Msg {
		private  String content;
		
		public TextMsg() {
			
		}
		
		public TextMsg(String toUserName, String fromUserName, Long createTime,
				String msgType, String content) {
			super(toUserName,fromUserName,createTime,msgType);
			this.content = content;
		}
		
		public String getContent() {
			return content;
		}
		public void setContent(String content) {
			this.content = content;
		}
	}
	
	/**
	 * 获取微信 access_token 线程
	 * @author LGF
	 *
	 */
	public static class ThreadAccessToken implements Runnable{
		
		private ServletContext servletContext;
		
		//实例化后启动线程
		public ThreadAccessToken(ServletContext servletContext) {
			this.servletContext = servletContext;
			servletContext.setAttribute("wx_openId", OPENID);
			servletContext.setAttribute("wx_appId", APPID);
			servletContext.setAttribute("wx_appSecret", APPSECRET);
			setToken();
			new Thread(this).start();
		}
		
		@Override
		public void run() {
			while(true){
				try {
					//两小时刷新一次签名
					Thread.sleep(60*1000);
					setToken();
				} catch (InterruptedException e) {
					e.printStackTrace();
					new ThreadAccessToken(servletContext);
				}
			}
		}
		
		/**
		 * 设置 access_token
		 */
		private synchronized void setToken(){
			try {
				InputStream input = URLHanlder.getInputStream(URL_ACCESS_TOKEN);
				JSONObject json = JSONObject.fromObject(readString(input));
				String wx_access_token = json.get(Const.ACCESS_TOKEN).toString();
				servletContext.setAttribute("wx_access_token", wx_access_token);
				System.out.println("get access access_token success " + wx_access_token);
				
				InputStream input1 = URLHanlder.getInputStream(MessageFormat.format(URL_JS_TICKET, wx_access_token));
				JSONObject json1 = JSONObject.fromObject(readString(input1));
				String wx_ticket = json1.get(Const.TICKET).toString();
				servletContext.setAttribute("wx_ticket", wx_ticket);
				
				System.out.println("get access ticket success " + wx_ticket);
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
}

/**
 * 常量
 * @author LGF
 *
 */
interface Const{
	public static String ACCESS_TOKEN = "access_token";
	public static String TICKET = "ticket";
}

 * JS安全域名验证

package com.wx.controller;

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

import javax.servlet.ServletException;
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.code.util.JSONHanlder;
import com.code.util.WeixinHanlder;


@WebServlet("/weixin_sign")
public class WXSign extends HttpServlet{

	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("UTF-8");
		
		String url = req.getParameter("url");
		String jsapi_ticket = req.getServletContext().getAttribute("wx_ticket").toString();
		String appid = req.getServletContext().getAttribute("wx_appId").toString();
		Map<String, String> sign = WeixinHanlder.sign(jsapi_ticket, url);
		sign.put("appId", appid);
		String string = JSONHanlder.getObjectAsString(sign);
		ServletOutputStream out = resp.getOutputStream();
		out.print(string);
		System.out.println(sign);
		out.close();
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		
	}
}

 

* JSON 工具类

package com.code.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.processors.JsonValueProcessor;

public class JSONHanlder {

	/**
	 * 获取JSON数据
	 * @param key
	 * @param source
	 * @return
	 */
	public static String getVal(String key,String json){
		if(key!=null&&key.trim().isEmpty()==false&&key.indexOf(".")!=-1&&json!=null&&json.trim().isEmpty()==false){
			String[] ks = key.split("[.]");
			List<String> list = Arrays.asList(ks);
			return getVal(json,list.iterator());
		}else if(key!=null&&key.trim().isEmpty()==false){
			return JSONObject.fromObject(json).get(key).toString();
		}
		return null;
	}
	
	/**
	 * 将对象转换成 JSON
	 * @param obj
	 * @return
	 */
	public static String getObjectAsString(Object obj){
		return getObjectAsString(null,null,obj);
	}
	/**
	 * 将对象转换成 JSON
	 * @param obj
	 * @return
	 */
	public static String getObjectAsString(Object ... obj){
		return getObjectAsString(null,null,obj);
	}
	
	/**
	 * 将对象转换成 JSON
	 * @param parrent 时间格式
	 * @param excludes 不包含的字段
	 * @param obj
	 * @return
	 */
	public static String getObjectAsString(String parrent,String excludes,Object... obj){
		if(obj==null||obj.length==0){
			return "{}";
		}
		if(obj.length==1){
			return JSONObject.fromObject(obj[0],Config.getInstance(parrent,excludes)).toString();
		}
		Data data = new Data();
		data.getRecords().addAll(Arrays.asList(obj));
		return JSONObject.fromObject(data,Config.getInstance(parrent,excludes)).toString();
	}
	
	/**
	 * 将对象转换成 JSON
	 * @param excludes
	 * @param obj
	 * @return
	 */
	public static String getObjectAsString(String excludes,Object... obj){
		return getObjectAsString(null,excludes,obj);
	}
	
	/**
	 * 将对象转换成 JSON
	 * @param parrent
	 * @param obj
	 * @return
	 */
	public static String getObjectAsString(Object parrent,Object... obj){
		if(parrent!=null){
			return getObjectAsString(parrent.toString(),null,obj);
		}
		return getObjectAsString(null,null,obj);
	}
	
	/**
	 * 获取JSON数据
	 * @param source
	 * @param ks
	 * @return
	 */
	private static String getVal(Object source,Iterator<String> ks){
		if(ks.hasNext()){
			source = JSONObject.fromObject(source).get(ks.next());
			if(source==null){
				return null;
			}
			return getVal(source,ks);
		}
		return  source.toString();
	}
	
	/**
	 * JSON 配置
	 * @author LGF
	 *
	 */
	public static class Config extends JsonConfig implements JsonValueProcessor {
		
		/**
		 * 日期格式化
		 */
		private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		/**
		 * 默认实例
		 */
		private static Config config = new Config();
		
		
		/**
		 * 默认构造方法
		 */
		private Config() {
			this.registerJsonValueProcessor(Date.class, this);
		}
		
		/**
		 * 构造方法
		 * @param parrent 日期格式化
		 * @param excludes 不包含的字段
		 */
		private Config(String parrent,String excludes) {
			if(parrent!=null){
				sdf = new SimpleDateFormat(parrent);
			}
			if(excludes!=null){
				this.setExcludes(excludes.split(","));
			}
			this.registerJsonValueProcessor(Date.class, this);
		}
		
		@Override
		public Object processArrayValue(Object date, JsonConfig cfg) {
			if(date instanceof Date){
				return sdf.format(date);
			}
			return null;
		}

		@Override
		public Object processObjectValue(String name, Object date,
				JsonConfig cfg) {
			if(date instanceof Date){
				return sdf.format(date);
			}
			return null;
		}
		
		/**
		 * 获取默认实例
		 * @return
		 */
		public static Config getDefaultInstance(){
			return config;
		}
		
		/**
		 * 日期格式化实例
		 * @param parrent
		 * @return
		 */
		public static Config getInstance(String parrent,String excludes){
			return new Config(parrent,excludes);
		}
		
	}
	
	/**
	 * JSON 数据储存实体
	 * @author LGF
	 *
	 */
	public static class Data{
		private List<Object> records = new ArrayList<Object>();

		public List<Object> getRecords() {
			return records;
		}
		public void setRecords(List<Object> records) {
			this.records = records;
		}
	}
}

 * 加密工具类

package com.code.util;

import java.security.MessageDigest;
import java.util.Formatter;
import java.util.UUID;

public class SecurityHanlder {

	private static final String uuid = "4c7a37a8-b8d7-442f-b9df-31ec4bcacebc";
	
	/**
	 * 获取 md5 加密字符串
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String md5(String str) throws Exception {
		return getSign(str,"MD5");
	}
	
	/**
	 * 获取 md5 加密字符串
	 * 规则 str+uuid
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String md5x(String str) throws Exception {
		return getSign(str+uuid,"MD5");
	}

	/**
	 * 获取 sha1 加密字符串
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String sha1(String str) throws Exception {
		return getSign(str,"SHA-1");
	}
	
	/**
	 * 获取 sha1 加密字符串
	 * 二次加密
	 * 规则 str+uuid
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String sha1x(String str) throws Exception {
		return getSign(str+uuid,"SHA-1");
	}
	
	/**
	 * 获取 sha1进行加密的字符后再进行 md5  加密字符串
	 * 二次加密
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String md5_sha1(String str) throws Exception {
		return  getSign(getSign(str,"MD5"),"SHA-1");
	}
	
	/**
	 * 获取 md5 进行加密的字符后再进行 sha1加密字符串
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String sha1_md5(String str) throws Exception {
		return getSign(getSign(str,"SHA-1"),"MD5");
	}

	/**
	 * 创建随机字符
	 * @return
	 */
	public static String createNonceStr() {
		return UUID.randomUUID().toString();
	}

	/**
	 * 获取加密签名
	 * @param str 字符
	 * @param type 加密类型
	 * @return 
	 * @throws Exception
	 */
	public static String getSign(String str, String type) throws Exception {
		MessageDigest crypt = MessageDigest.getInstance(type);
		crypt.reset();
		crypt.update(str.getBytes("UTF-8"));
		return str = byteToHex(crypt.digest());
	}

	/**
	 * 创建时间戳
	 * @return
	 */
	public static String createTimestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
	}

	/**
	 * 字节转换 16 进制
	 * @param hash
	 * @return
	 */
	private static String byteToHex(final byte[] hash) {
		Formatter formatter = new Formatter();
		for (byte b : hash) {
			formatter.format("%02x", b);
		}
		String result = formatter.toString();
		formatter.close();
		return result;
	}

}

 * URL 工具类

package com.code.util;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

public class URLHanlder {
	
	/**
	 * 发送 HTTP 请求获取输入流
	 * @param str
	 * @param params
	 * @return
	 */
	public static InputStream getInputStream(String str,Map<String,String> params){
		URL url = null;
		try {
			if(params!=null&&params.size()!=0){
				StringBuffer sb = new StringBuffer();
				int index = 0;
				if(str.indexOf("?")!=-1){
					sb.append("&");
				}else{
					sb.append("?");
				}
				for (String s : params.keySet()) {
					sb.append(s);
					sb.append("=");
					sb.append(params.get(s));
					if(params.size()-1!=index){
						sb.append("&");
					}
					index++;
				}
				str+=sb.toString();
			}
			url = new URL(str);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			return conn.getInputStream();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 发送 HTTP 请求获取输入流
	 * @param str
	 * @return
	 */
	public static InputStream getInputStream(String str){
		return getInputStream(str,null);
	}
}

 * 微信监听类(获取 token)

package com.code.util;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class WXListener implements ServletContextListener {

    public WXListener() {
    	System.out.println("start com.code.util.WXListener.WXListener()");
    }
 
    public void contextInitialized(ServletContextEvent e)  { 
    	ServletContext servletContext = e.getServletContext();
    	new WeixinHanlder.ThreadAccessToken(servletContext);
    }

    public void contextDestroyed(ServletContextEvent e)  { 
    	System.out.println("destory com.code.util.WXListener.WXListener()");
    }
	
}

 * 微信 properties 配置

open_id=gh_08d0a8f58b1fsssgf
app_id=wxe0faf281eed31f38899
app_secret=dcc59f91d76ea35a05a56fdc0bf16aa7dfh
token=weixin
url_access_token=https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxe0faf281eed31f38&secret=dcc59f91d76ea35a05a56fdc0bf16aa7
url_js_ticket=https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi
change_token_time=7200

 * web.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  
  <display-name>wx</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <listener>
  	<listener-class>com.code.util.WXListener</listener-class>
  </listener>
  
</web-app>

 * index.jsp 示例

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
<title>index</title>
</head>
<body>
<input type="submit" id="onMenuShareAppMessage" value="submit">
<br/>
<input type="file" />
<br/>
<input type="button" value="reload" onclick="location.reload(true)">
</body>
<script type="text/javascript" src="js/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
	$(function() {
		$.ajax({
			type : "GET",
			url : "weixin_sign",
			async: false,
			data:{url:location.href.split("#")[0]},
			dataType: "JSON",
			success : function(msg) {
				console.debug(msg);
				var params = 
				{
				    //url,jsapi_ticket,nonceStr,timestamp,signature
					debug: true,
					appId:msg.appId,
					timestamp:msg.timestamp,
					nonceStr:msg.nonceStr,
					signature:msg.signature,
					jsApiList: ['checkJsApi',
					             'onMenuShareTimeline',
					             'onMenuShareAppMessage',
					             'onMenuShareQQ',
					             'onMenuShareWeibo',
					             'hideMenuItems',
					             'showMenuItems',
					             'hideAllNonBaseMenuItem',
					             'showAllNonBaseMenuItem',
					             'translateVoice',
					             'startRecord',
					             'stopRecord',
					             'onRecordEnd',
					             'playVoice',
					             'pauseVoice',
					             'stopVoice',
					             'uploadVoice',
					             'downloadVoice',
					             'chooseImage',
					             'previewImage',
					             'uploadImage',
					             'downloadImage',
					             'getNetworkType',
					             'openLocation',
					             'getLocation',
					             'hideOptionMenu',
					             'showOptionMenu',
					             'closeWindow',
					             'scanQRCode',
					             'chooseWXPay',
					             'openProductSpecificView',
					             'addCard',
					             'chooseCard',
					             'openCard']
				}
					wx.config(params);
			}
		});

	});
	
	wx.ready(function(){
		
		$("#onMenuShareAppMessage").click(function(){
			
			 wx.openLocation({
			      latitude: 23.099994,
			      longitude: 113.324520,
			      name: 'TIT 创意园',
			      address: '广州市海珠区新港中路 397 号',
			      scale: 14,
			      infoUrl: 'http://weixin.qq.com'
			    });
		});
	});	
	
	wx.error(function(res){
		alert("not success");
	});
</script>
</html>

 

 



    本文附件下载:
  • wx.zip (3 MB)


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [微信 开发] 推荐:

微信开发入门

- - 行业应用 - ITeye博客
【做微信平台开发需要以下步骤,wx.zip示例可以参考,修改配置即可】. 1.申请一个公众号(订阅号或者服务号). 2.需要有自己的服务器(建议使用花生壳做内网映射). * 检查是否是微信发送的请求. * @param signature 签名. * @param timestamp 时间戳. * @param nonce 随机数.

微信公众平台开发(一)

- - BlogJava-首页技术区
  开始微信公众平台的开发,我们首先要了解微信平台可以帮助我们做哪些事情. 使用您的公众账号登陆http://mp.weixin.qq.com/,选择菜单--高级功能-开发模式--查看文档,即能看到微信公众平台目前所能开发的功能. 接受用户发送给您公众账号的消息. 需要特别说明的是,发送消息和回复消失是一个连贯的过程,只能在一个对话中完成.

如何成为微信开发者

- - 神刀网
要成为微信开发者,准备工作如下:. a.这个可以自己购买,如果之前已有网站,可直接使用其服务器,这样也不用再购买域名了. b.也可以使用免费的服务器,搜索一下,有很多. c.还可以使用 百度云开发平台或者 新浪云平台,是免费的. a.如果服务器自己购买,也需要购买域名,然后要设置域名DNS,将域名绑定到购买的服务器.

微信公众平台接口开发

- - CSDN博客互联网推荐文章
随着微信公众平台的开放,微信营销推广也越发受到重视. 现在企业越来越注重求职者是否拥有“微信公众平台接口开发”的经验. 现在参考资料介绍下微信公众平台接口开发模式:. 首先你得有个微信公众平台账号,注册地址:http://mp.weixin.qq.com/. 开发者提交信息后,微信服务器将发送GET请求到填写的URL上,GET请求携带四个参数:.

微信公众平台开发入门

- - Web前端 - ITeye博客
在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序、MySQL数据库、计算机网络通讯、及HTTP/XML/CSS/JS等基础. 我们将使用微信公众账号方倍工作室作为讲解的例子,二维码见底部. 本系列教程将引导你完成如下任务:. 我们使用SAE新浪云计算平台作为服务器资源,并且申请PHP环境+MySQL数据库作为程序运行环境.

Vue2 全家桶与微信开发

- - IT瘾-dev
此项目本身有一个APP了,为了方便将APP和微信端数据打通,需要用户微信和APP用户绑定. 在开发的过程中单页面的模式在微信JS API的配置踩了很多坑,特别是IOS. 由于本人表述能力和篇幅有限Orz,这里只介绍关键的实现步骤和代码,有些安全的地方和路由地方处理当时比较暴力没有细化,还望交流指导.

如何基于微信开放接口开发企业的微信 CRM?

- - 极客公园-GeekPark
我是极客公园黑板报认证值日生. [核心提示]企业要开发微信 CRM,首先要从业务架构上进行设计清楚. 微信 CRM 的本质,是在微信渠道上利用微信的特点和接口而扩展的 CRM 系统. 业内一直都在传说 微信是天生的 CRM,可是没有人看到过微信 CRM 的真容. 随着微信最新公众平台的改版和开放接口的微信认证开放,微信 CRM 离企业越来越近.

微信公众平台开发(三)--位置信息的识别

- - BlogJava-首页技术区
位置识别这是实际应用经常应用的消息,特别是很多商家,通过了解用户位置,给用户提供特别的产品或是商场的推荐. 其中用户可能发送两种类型的消息:. 2.路名、标志性建筑或是商场名称. 认识一下,微信地理位置消息,包含一些什么信息. . 包含的主要信息有经度纬度和Label的位置.

摩拜单车微信小程序开发技术总结

- - SegmentFault 最新的文章
摩拜单车小程序已于微信小程序上线第一天正式发布,刷爆微博媒体朋友圈. 本文主要讲讲技术方向的总结,在段时间的开发周期内内如何一步步从学习到进阶. 微信小程序没有HTML的常用标签,而是类似. React的微信自定义组件,比如. window变量,但微信提供了. React的state)来改变视图展现.

腾讯开源:微信和移动开发的 10 大项目

- -
腾讯开源了许多非常有价值的项目,下面我们一起来看看腾讯10大开源项目有哪些. 1、Android 热修复框架 Tinker. Tinker 是微信官方的 Android 热补丁解决方案,它支持动态下发代码、So 库以及资源,让应用能够在不需要重新安装的情况下实现更新. 当然,你也可以使用 Tinker 来更新你的插件.