微信公众平台开发(1) 通用的工具类CommonUtil
1、通用的调用微信的方法

/**
*
* @param requestUrl 接口地址
* @param requestMethod 请求方法:POST、GET...
* @param output 接口入参
* @param needCert 是否需要数字证书
* @return
*/
private static StringBuffer httpsRequest(String requestUrl, String requestMethod, String output,boolean needCert)
throws NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException, MalformedURLException,
IOException, ProtocolException, UnsupportedEncodingException { URL url = new URL(requestUrl);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); //是否需要数字证书
if(needCert){
//设置数字证书
setCert(connection);
}
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod(requestMethod);
if (null != output) {
OutputStream outputStream = connection.getOutputStream();
outputStream.write(output.getBytes("UTF-8"));
outputStream.close();
} // 从输入流读取返回内容
InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
} bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
connection.disconnect();
return buffer;
}

2、获取数字证书。JAVA只需要使用apiclient_cert.p12即可

/**
* 给HttpsURLConnection设置数字证书
* @param connection
* @throws IOException
*/
private static void setCert(HttpsURLConnection connection) throws IOException{
FileInputStream instream = null;
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//读取本机存放的PKCS12证书文件
instream = new FileInputStream(new File("certPath")); //certPath:数字证书路径 //指定PKCS12的密码(商户ID)
keyStore.load(instream, "商户ID".toCharArray());
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "商户ID".toCharArray()).build();
//指定TLS版本
SSLSocketFactory ssf = sslcontext.getSocketFactory();
connection.setSSLSocketFactory(ssf);
} catch (Exception e){
e.printStackTrace();
}finally {
instream.close();
}
}

3、调用微信接口后,返回数据格式转换

/**
* 如果返回JSON数据包,转换为 JSONObject
* @param requestUrl
* @param requestMethod
* @param outputStr
* @param needCert
* @return
*/
public static JSONObject httpsRequestToJsonObject(String requestUrl, String requestMethod, String outputStr,boolean needCert) {
JSONObject jsonObject = null;
try {
StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr,needCert);
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:"+ce.getMessage());
} catch (Exception e) {
log.error("https请求异常:"+e.getMessage());
} return jsonObject;
} /**
* 如果返回xml数据包,转换为Map<String, String>
* @param requestUrl
* @param requestMethod
* @param outputStr
* @param needCert
* @return
*/
public static Map<String, String> httpsRequestToXML(String requestUrl, String requestMethod, String outputStr,boolean needCert) {
Map<String, String> result = new HashMap<>();
try {
StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr,needCert);
result = parseXml(buffer.toString());
} catch (ConnectException ce) {
log.error("连接超时:"+ce.getMessage());
} catch (Exception e) {
log.error("https请求异常:"+e.getMessage());
}
return result;
} /**
* xml转为map
* @param xml
* @return
*/
@SuppressWarnings("unchecked")
public static Map<String, String> parseXml(String xml) {
Map<String, String> map = new HashMap<String, String>();
try {
Document document = DocumentHelper.parseText(xml); Element root = document.getRootElement();
List<Element> elementList = root.elements(); for (Element e : elementList){
map.put(e.getName(), e.getText());
}
} catch (DocumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return map;
}

4、微信回调系统,将回调结果转换为map类型。支付通知等场景使用

public static Map<Object, Object> parseXml(HttpServletRequest request)
{
// 解析结果存储在HashMap
Map<Object, Object> map = new HashMap<Object, Object>();
try {
InputStream inputStream; inputStream = request.getInputStream(); // 读取输入流
SAXReader reader = new SAXReader();
Document document = reader.read(inputStream);
System.out.println(document);
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List<Element> elementList = root.elements(); // 遍历所有子节点
for (Element e : elementList)
map.put(e.getName(), e.getText()); // 释放资源
inputStream.close();
inputStream = null;
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (DocumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return map;
}

5、普通javabean转换为排序SortedMap<Object,Object>,及签名。因微信签名要求按照accsii排序(升序)

/**
* 将一个 JavaBean 对象转化为一个 Map
* @param bean 要转化的JavaBean 对象
* @return 转化出来的 Map 对象
* @throws IntrospectionException 如果分析类属性失败
* @throws IllegalAccessException 如果实例化 JavaBean 失败
* @throws InvocationTargetException 如果调用属性的 setter 方法失败
*/
@SuppressWarnings({ "rawtypes"})
public static SortedMap<Object,Object> convertBean(Object bean) {
SortedMap<Object,Object> returnMap = new TreeMap<Object,Object>();
try {
Class type = bean.getClass();
BeanInfo beanInfo = Introspector.getBeanInfo(type);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i< propertyDescriptors.length; i++) {
PropertyDescriptor descriptor = propertyDescriptors[i];
String propertyName = descriptor.getName();
if (!propertyName.equals("class")) {
Method readMethod = descriptor.getReadMethod();
Object result = readMethod.invoke(bean, new Object[0]);
if (result != null) {
returnMap.put(propertyName, result);
} else {
returnMap.put(propertyName, "");
}
}
}
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return returnMap;
} /**
* 生成签名
* @param parameters
* @return
*/
public static String createSgin(SortedMap<Object,Object> parameters)
{
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
if(null != v && !"".equals(v)
&& !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + wxConfig.getWxKey());
String sgin=MD5.sign(sb.toString());
return sgin;
}


/**
* 获取ip地址
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
return request.getRemoteAddr();
}
byte[] ipAddr = addr.getAddress();
String ipAddrStr = "";
for (int i = 0; i < ipAddr.length; i++) {
if (i > 0) {
ipAddrStr += ".";
}
ipAddrStr += ipAddr[i] & 0xFF;
}
return ipAddrStr;
}

6、其他一些辅助类、方法

/**
* 获得指定长度的随机字符串
* @author Administrator
*
*/
public class StringWidthWeightRandom {
private int length = 32;
private char[] chars = new char[]{
'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','V','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
};
private Random random = new Random(); //参数为生成的字符串的长度,根据给定的char集合生成字符串
public String getNextString(int length){ char[] data = new char[length]; for(int i = 0;i < length;i++){
int index = random.nextInt(chars.length);
data[i] = chars[index];
}
String s = new String(data);
return s;
} public int getLength() {
return length;
} public void setLength(int length) {
this.length = length;
}
}


public class UtilDate { /** 年月日时分秒(无下划线) yyyyMMddHHmmss */
public static final String dtLong = "yyyyMMddHHmmss"; /** 完整时间 yyyy-MM-dd HH:mm:ss */
public static final String simple = "yyyy-MM-dd HH:mm:ss"; /** 年月日(无下划线) yyyyMMdd */
public static final String dtShort = "yyyyMMdd"; /**
* 返回系统当前时间(精确到毫秒),作为一个唯一的订单编号
* @return
* 以yyyyMMddHHmmss为格式的当前系统时间
*/
public static String getDateLong(){
Date date=new Date();
DateFormat df=new SimpleDateFormat(dtLong);
return df.format(date);
} /**
* 获取系统当前日期(精确到毫秒),格式:yyyy-MM-dd HH:mm:ss
* @return
*/
public static String getDateFormatter(){
Date date=new Date();
DateFormat df=new SimpleDateFormat(simple);
return df.format(date);
} /**
* 获取系统当期年月日(精确到天),格式:yyyyMMdd
* @return
*/
public static String getDate(){
Date date=new Date();
DateFormat df=new SimpleDateFormat(dtShort);
return df.format(date);
} }


public class MD5 {
public static String sign(String str){
MessageDigest md5;
String sgin = "";
try {
md5 = MessageDigest.getInstance("MD5");
md5.reset();
md5.update(str.getBytes("UTF-8"));
sgin = byteToStr(md5.digest()).toUpperCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return sgin;
} /**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
public static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
} /**
* 将字节转换为十六进制字符串
*
* @param btyes
* @return
*/
public static String byteToHexStr(byte bytes) {
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[(bytes >>> 4) & 0X0F];
tempArr[1] = Digit[bytes & 0X0F]; String s = new String(tempArr);
return s;
} }

微信公众平台开发(1) 通用的工具类CommonUtil的更多相关文章
- Senparc.Weixin.MP SDK 微信公众平台开发教程(八):通用接口说明
一.基础说明 这里说的“通用接口(CommonAPIs)”是使用微信公众账号一系列高级功能的必备验证功能(应用于开发模式). 我们通过微信后台唯一的凭证,向通用接口发出请求,得到访问令牌(Access ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十七):个性化菜单接口说明
前不久微信上线了个性化菜单接口,Senparc.Weixin SDK也已经同步更新. 本次更新升级Senparc.Weixin.MP版本到v13.5.2,依赖Senparc.Weixin版本4.5.4 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK
Senparc.Weixin.MP SDK已经涵盖了微信6.x的所有公共API. 整个项目的源代码以及已经编译好的程序集可以在这个项目中获取到:https://github.com/JeffreySu ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十四):请求消息去重
为了确保信息请求消息的到达率,微信服务器在没有及时收到响应消息(ResponseMessage)的情况下,会多次发送同一条请求消息(RequestMessage),包括MsgId等在内的所有文本内容都 ...
- 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单
我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...
- 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token
一.access_token简介 为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等, 开 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(二十):使用菜单消息功能
在<Senparc.Weixin.MP SDK 微信公众平台开发教程(十一):高级接口说明>教程中,我们介绍了如何使用“客服接口”,即在服务器后台,在任意时间向微信发送文本.图文.图片等不 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(二十二):如何安装 Nuget(dll) 后使用项目源代码调试
最近碰到开发者问:我使用 nuget 安装了 Senparc.Weixin SDK,但是有一些已经封装好的过程想要调试,我又不想直接附加源代码项目,这样就没有办法同步更新了,我应该怎么办? 这其实是一 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十八):Web代理功能
在Senparc.Weixin.dll v4.5.7版本开始,我们提供了Web代理功能,以方便在受限制的局域网内的应用可以顺利调用接口. 有关的修改都在Senparc.Weixin/Utilities ...
随机推荐
- ntp 服务器
ntp.sjtu.edu.cn 202.120.2.101 (上海交通大学网络中心NTP服务器地址)s1a.time.edu.cn 北京邮电大学s1b.time.edu.cn 清华大学s1c.time ...
- (转)iptables常用规则:屏蔽IP地址、禁用ping、协议设置、NAT与转发、负载平衡、自定义链
转自:http://lesca.me/archives/iptables-examples.html 本文介绍25个常用的iptables用法.如果你对iptables还不甚了解,可以参考上一篇ipt ...
- 管理aix的密码策略
aix 中 /etc/security/user 存放用户的概要 常用参数参数如下 1.account_locked defines whether the account is locke ...
- 短网址ShortUrl的算法
场景: 我们在新浪微博上公布网址的时候.微博会自己主动判别网址.并将其转换.比如:http://t.cn/hrYnr0. 为什么要这样做的,原因我想有这样几点: 1.微博限制字数为140字一条,那么假 ...
- 关于android的2.2与4.4的文件读取的一点发现
好久没有写文章了,本来想写的东西,时间一长,就感觉不想写了.没什么用,到用时.又不知道去哪找了或怎么解决. 有一句话说的好啊,好记性不如烂笔头. 我要做到善于总结.及时整理,额............ ...
- UI 06 ScrollView 的手动循环播放 与 自己主动循环播放
假设想要循环播放的话, scrollView的照片前要加上最后一张图片, 最后要加上第一张图片. - (void)viewDidLoad { [super viewDidLoad]; // Do an ...
- [TypeStyle] Add type safety to CSS using TypeStyle
TypeStyle is the only current CSS in JS solution that is designed with TypeSafety and TypeScript dev ...
- android 应用内部获取本应用或者相应包名的应用的SHA1签名的办法
我这个人比較懒.每次做的都是心血来潮,所以打算改掉这个坏毛病.昨晚非常晚才睡,躺在床上一直在回忆.这两年来,我以前的目标是什么,我放弃了什么,我完毕了什么. 结果目标非常多,也放弃了一些. 完毕的差点 ...
- Nginx+ 多个Memcached+ 多个Tomcat集群配置来实现 sticky Session
假如有 大于2 台的Tomcat servers,如何实现sticky session特点的高可靠web 服务? 方案设计: 前端使用nginx(最好是淘宝的 tengine)作为we 流量分发器,向 ...
- angular管道相关知识
原文地址 https://www.jianshu.com/p/22e0f95bcf24 什么是管道 每个应用开始的时候差不多都是一些简单任务:获取数据.转换它们,然后把它们显示给用户. 获取数据可能简 ...