这里springmvc的配置 请见我别的文章http://my.oschina.net/angleshuai/blog/410960
这里只写微信相关的代码(相关jar包和源码会在最下面为大家呈上)
前台可以引导用户到此页授权scope参数中的snsapi_base和snsapi_userinfo。 redirect_uri就是下面/hongbao/index的连接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=/hongbao/index&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
首先放上根据code获取access_token和openid和unionid的代码
@RequestMapping("/hongbao/index") @ResponseBody public Object hongbaoIndex(String code,String STATE,HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception { if(code==null){ return "code为空"; } Map<String , Object> map= new HashMap<String, Object>(); URL url=new URL("https://api.weixin.qq.com/sns/oauth2/access_token?appid="+WeiXinRequest.appId+"&secret="+WeiXinRequest.appSecret+"&code="+code+"&grant_type=authorization_code"); System.out.println("code+++++++++++++++++++++ "+code); System.out.println("url+++++++++++++++++++++ "+url); JSONObject param= WeiXinRequest.getConnection(url); System.out.println("JSONparam+++++++++++++++++++++ "+param); String access_token=param.getString("access_token"); String refresh_token=param.getString("refresh_token");//刷新token String openid=param.getString("openid"); String scope=param.getString("scope"); String unionid=param.getString("unionid"); System.out.println("access_token+++++++++++++++++++++ "+access_token); System.out.println("openid+++++++++++++++++++++ "+openid); System.out.println("unionid+++++++++++++++++++++ "+unionid); if(access_token==null){ return "access_token为空"; }else if(openid==null){ return "access_token为空"; } map.put("access_token", access_token); map.put("openid", openid); map.put("refresh_token", access_token); map.put("unionid", access_token); //前台可以验证https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID 是否有效 return map; }
那个getconnection的方法
public static JSONObject getConnection(URL url) throws IOException { HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestMethod("GET"); connection.setUseCaches(false); connection.setInstanceFollowRedirects(true); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.connect(); JSONObject jsono = new JSONObject(new JSONTokener( new InputStreamReader(connection.getInputStream()))); connection.disconnect(); return jsono; }
然后是比较关键的发红包的方法
@RequestMapping("/hongbao") @ResponseBody public Object hongbao(String access_token,String re_openid,String total_amount,HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception { URL urlUnionInfo=new URL("https://api.weixin.qq.com/sns/userinfo?access_token="+access_token+"&openid="+re_openid+"&lang=zh_CN"); String urlhongbao="https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack" ; JSONObject UnionInfo= WeiXinRequest.getConnection(urlUnionInfo); String nick_name =""; if(UnionInfo.toString().contains("nickname")){ nick_name=UnionInfo.getString("nickname"); }else{ } /*String city =UnionInfo.getString("city"); String province =UnionInfo.getString("province"); String country =UnionInfo.getString("country"); String headimgurl =UnionInfo.getString("country");//用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 */ //解决XStream对出现双下划线的bug XStream xStreamForRequestPostData = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"))); xStreamForRequestPostData.alias("xml", xml.class); Random random = new Random(); SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMdd"); String mch_billno =WeiXinRequest.mch_id+sdf.format(new Date())+random.nextInt(); String client_ip = request.getHeader("X-Forwarded-For"); if (client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) { client_ip = request.getHeader("Proxy-Client-IP"); } if (client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) { client_ip = request.getHeader("WL-Proxy-Client-IP"); } if (client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) { client_ip = request.getRemoteAddr(); } if(client_ip.length()>15){ client_ip=client_ip.split(",")[0]; } Map<String, String> map=new HashMap<String, String>(); map.put("nick_name", nick_name); map.put("nonce_str", random.nextInt(1000000)+""); map.put("wxappid", WeiXinRequest.appId); map.put("mch_id", WeiXinRequest.mch_id); map.put("mch_billno", mch_billno); map.put("wxappid", WeiXinRequest.appId); map.put("send_name", "优卖网"); map.put("re_openid", re_openid); map.put("total_amount", total_amount); map.put("min_value", total_amount); map.put("max_value", total_amount); map.put("total_num", "1"); map.put("wishing", "感谢您对优卖网的支持!"); map.put("client_ip",client_ip); map.put("act_name", "优卖发钱活动"); map.put("remark", "不要白不要"); map.put("logo_imgurl","http://umaiw.com/favicon.ico"); map.put("share_content", "快点接啊过24小时就没啦"); map.put("share_url", "http://www.baidu.com"); map.put("share_imgurl", "https://wx.baidu.com/mch/img/ico-logo.png"); //string签名 Set<String> sr= map.keySet(); Object[] oj= sr.toArray(); Arrays.sort(oj); String stringA=""; for(int i=0;i<oj.length;i++){ stringA+=oj[i]+"="+map.get(oj[i]); if(i!=(oj.length-1)){ stringA+="&&"; } } String stringSignTemp= stringA+"&key="+WeiXinRequest.key; String sign=MD5Ecode.getMD5Str(stringSignTemp).toUpperCase(); //发送xml xml xml=new xml(WeiXinRequest.appId, WeiXinRequest.mch_id, random.nextInt(1000000)+"", sign, mch_billno, "", nick_name, "优卖网", re_openid, total_amount, total_amount, total_amount, "1", "感谢您对优卖网的支持!", client_ip, "优卖发钱活动", "不要白不要", "http://umaiw.com/favicon.ico", "快点接啊过24小时就没啦", "http://www.baidu.com", "https://wx.baidu.com/mch/img/ico-logo.png"); //将要提交给API的数据对象转换成XML格式数据Post给API String postDataXML = xStreamForRequestPostData.toXML(xml); System.out.println("发送的xml++++++++++++++++++++++++++++++++++"+postDataXML); String result = null; HttpPost httpPost = new HttpPost(urlhongbao); //得指明使用UTF-8编码,否则到API服务器XML的中文不能被成功识别 StringEntity postEntity = new StringEntity(postDataXML, "UTF-8"); httpPost.addHeader("Content-Type", "text/xml"); httpPost.setEntity(postEntity); System.out.println("executing request" + httpPost.getRequestLine()); KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File(WeiXinRequest.certLocalPath));//加载本地的证书进行https加密传输 try { keyStore.load(instream,WeiXinRequest.certPassword.toCharArray());//设置证书密码 } catch (CertificateException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, WeiXinRequest.certPassword.toCharArray()) .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); CloseableHttpClient httpClient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); //根据默认超时限制初始化requestConfig //连接超时时间,默认10秒 //传输超时时间,默认30秒 RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(30000).build(); //设置请求器的配置 httpPost.setConfig(requestConfig); try { HttpResponse response1 = httpClient.execute(httpPost); HttpEntity entity = response1.getEntity(); result = EntityUtils.toString(entity, "UTF-8"); } catch (Exception e) { e.printStackTrace(); } finally { httpPost.abort(); } return result; }
其中的参数含义大家可以参考http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html 这个微信开发文档
证书什么的 大家去申请微信支付 通过就会给你了
然后是转xml的实体(这里用的xstream来实体转xml的)
package com.model; public class xml { private String wxappid; private String mch_id; private String nonce_str; private String sign; private String mch_billno; private String sub_mch_id; private String nick_name; private String send_name; private String re_openid; private String total_amount; private String min_value; private String max_value; private String total_num; private String wishing; private String client_ip ; private String act_name; private String remark; private String logo_imgurl; private String share_content; private String share_url; private String share_imgurl; public xml(String wxappid, String mch_id, String nonce_str, String sign, String mch_billno, String sub_mch_id, String nick_name, String send_name, String re_openid, String total_amount, String min_value, String max_value, String total_num, String wishing, String client_ip, String act_name, String remark, String logo_imgurl, String share_content, String share_url, String share_imgurl) { super(); this.wxappid = wxappid; this.mch_id = mch_id; this.nonce_str = nonce_str; this.sign = sign; this.mch_billno = mch_billno; this.sub_mch_id = sub_mch_id; this.nick_name = nick_name; this.send_name = send_name; this.re_openid = re_openid; this.total_amount = total_amount; this.min_value = min_value; this.max_value = max_value; this.total_num = total_num; this.wishing = wishing; this.client_ip = client_ip; this.act_name = act_name; this.remark = remark; this.logo_imgurl = logo_imgurl; this.share_content = share_content; this.share_url = share_url; this.share_imgurl = share_imgurl; } public xml() { } public String getWxappid() { return wxappid; } public void setWxappid(String wxappid) { this.wxappid = wxappid; } public String getMch_id() { return mch_id; } public void setMch_id(String mch_id) { this.mch_id = mch_id; } public String getNonce_str() { return nonce_str; } public void setNonce_str(String nonce_str) { this.nonce_str = nonce_str; } public String getSign() { return sign; } public void setSign(String sign) { this.sign = sign; } public String getMch_billno() { return mch_billno; } public void setMch_billno(String mch_billno) { this.mch_billno = mch_billno; } public String getSub_mch_id() { return sub_mch_id; } public void setSub_mch_id(String sub_mch_id) { this.sub_mch_id = sub_mch_id; } public String getNick_name() { return nick_name; } public void setNick_name(String nick_name) { this.nick_name = nick_name; } public String getSend_name() { return send_name; } public void setSend_name(String send_name) { this.send_name = send_name; } public String getRe_openid() { return re_openid; } public void setRe_openid(String re_openid) { this.re_openid = re_openid; } public String getTotal_amount() { return total_amount; } public void setTotal_amount(String total_amount) { this.total_amount = total_amount; } public String getMin_value() { return min_value; } public void setMin_value(String min_value) { this.min_value = min_value; } public String getMax_value() { return max_value; } public void setMax_value(String max_value) { this.max_value = max_value; } public String getTotal_num() { return total_num; } public void setTotal_num(String total_num) { this.total_num = total_num; } public String getWishing() { return wishing; } public void setWishing(String wishing) { this.wishing = wishing; } public String getClient_ip() { return client_ip; } public void setClient_ip(String client_ip) { this.client_ip = client_ip; } public String getAct_name() { return act_name; } public void setAct_name(String act_name) { this.act_name = act_name; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public String getLogo_imgurl() { return logo_imgurl; } public void setLogo_imgurl(String logo_imgurl) { this.logo_imgurl = logo_imgurl; } public String getShare_content() { return share_content; } public void setShare_content(String share_content) { this.share_content = share_content; } public String getShare_url() { return share_url; } public void setShare_url(String share_url) { this.share_url = share_url; } public String getShare_imgurl() { return share_imgurl; } public void setShare_imgurl(String share_imgurl) { this.share_imgurl = share_imgurl; } }
源码与jar包