1、通用的调用微信的方法


1      /**
2 *
3 * @param requestUrl 接口地址
4 * @param requestMethod 请求方法:POST、GET...
5 * @param output 接口入参
6 * @param needCert 是否需要数字证书
7 * @return
8 */
9 private static StringBuffer httpsRequest(String requestUrl, String requestMethod, String output,boolean needCert)
10 throws NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException, MalformedURLException,
11 IOException, ProtocolException, UnsupportedEncodingException {
12
13
14 URL url = new URL(requestUrl);
15 HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
16
17 //是否需要数字证书
18 if(needCert){
19 //设置数字证书
20 setCert(connection);
21 }
22 connection.setDoOutput(true);
23 connection.setDoInput(true);
24 connection.setUseCaches(false);
25 connection.setRequestMethod(requestMethod);
26 if (null != output) {
27 OutputStream outputStream = connection.getOutputStream();
28 outputStream.write(output.getBytes("UTF-8"));
29 outputStream.close();
30 }
31
32 // 从输入流读取返回内容
33 InputStream inputStream = connection.getInputStream();
34 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
35 BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
36 String str = null;
37 StringBuffer buffer = new StringBuffer();
38 while ((str = bufferedReader.readLine()) != null) {
39 buffer.append(str);
40 }
41
42 bufferedReader.close();
43 inputStreamReader.close();
44 inputStream.close();
45 inputStream = null;
46 connection.disconnect();
47 return buffer;
48 }



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



1     /**
2 * 给HttpsURLConnection设置数字证书
3 * @param connection
4 * @throws IOException
5 */
6 private static void setCert(HttpsURLConnection connection) throws IOException{
7 FileInputStream instream = null;
8 try {
9 KeyStore keyStore = KeyStore.getInstance("PKCS12");
10 //读取本机存放的PKCS12证书文件
11 instream = new FileInputStream(new File("certPath")); //certPath:数字证书路径
12
13 //指定PKCS12的密码(商户ID)
14 keyStore.load(instream, "商户ID".toCharArray());
15 SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "商户ID".toCharArray()).build();
16 //指定TLS版本
17 SSLSocketFactory ssf = sslcontext.getSocketFactory();
18 connection.setSSLSocketFactory(ssf);
19 } catch (Exception e){
20 e.printStackTrace();
21 }finally {
22 instream.close();
23 }
24 }



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


1 /**
2 * 如果返回JSON数据包,转换为 JSONObject
3 * @param requestUrl
4 * @param requestMethod
5 * @param outputStr
6 * @param needCert
7 * @return
8 */
9 public static JSONObject httpsRequestToJsonObject(String requestUrl, String requestMethod, String outputStr,boolean needCert) {
10 JSONObject jsonObject = null;
11 try {
12 StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr,needCert);
13 jsonObject = JSONObject.fromObject(buffer.toString());
14 } catch (ConnectException ce) {
15 log.error("连接超时:"+ce.getMessage());
16 } catch (Exception e) {
17 log.error("https请求异常:"+e.getMessage());
18 }
19
20 return jsonObject;
21 }
22
23 /**
24 * 如果返回xml数据包,转换为Map<String, String>
25 * @param requestUrl
26 * @param requestMethod
27 * @param outputStr
28 * @param needCert
29 * @return
30 */
31 public static Map<String, String> httpsRequestToXML(String requestUrl, String requestMethod, String outputStr,boolean needCert) {
32 Map<String, String> result = new HashMap<>();
33 try {
34 StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr,needCert);
35 result = parseXml(buffer.toString());
36 } catch (ConnectException ce) {
37 log.error("连接超时:"+ce.getMessage());
38 } catch (Exception e) {
39 log.error("https请求异常:"+e.getMessage());
40 }
41 return result;
42 }
43
44 /**
45 * xml转为map
46 * @param xml
47 * @return
48 */
49 @SuppressWarnings("unchecked")
50 public static Map<String, String> parseXml(String xml) {
51 Map<String, String> map = new HashMap<String, String>();
52 try {
53 Document document = DocumentHelper.parseText(xml);
54
55 Element root = document.getRootElement();
56 List<Element> elementList = root.elements();
57
58 for (Element e : elementList){
59 map.put(e.getName(), e.getText());
60 }
61 } catch (DocumentException e1) {
62 // TODO Auto-generated catch block
63 e1.printStackTrace();
64 }
65 return map;
66 }


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


1 public static Map<Object, Object> parseXml(HttpServletRequest request) 
2 {
3 // 解析结果存储在HashMap
4 Map<Object, Object> map = new HashMap<Object, Object>();
5 try {
6 InputStream inputStream;
7
8 inputStream = request.getInputStream();
9
10 // 读取输入流
11 SAXReader reader = new SAXReader();
12 Document document = reader.read(inputStream);
13 System.out.println(document);
14 // 得到xml根元素
15 Element root = document.getRootElement();
16 // 得到根元素的所有子节点
17 List<Element> elementList = root.elements();
18
19 // 遍历所有子节点
20 for (Element e : elementList)
21 map.put(e.getName(), e.getText());
22
23 // 释放资源
24 inputStream.close();
25 inputStream = null;
26 } catch (IOException e1) {
27 // TODO Auto-generated catch block
28 e1.printStackTrace();
29 } catch (DocumentException e1) {
30 // TODO Auto-generated catch block
31 e1.printStackTrace();
32 }
33 return map;
34 }



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



1 /** 
2 * 将一个 JavaBean 对象转化为一个 Map
3 * @param bean 要转化的JavaBean 对象
4 * @return 转化出来的 Map 对象
5 * @throws IntrospectionException 如果分析类属性失败
6 * @throws IllegalAccessException 如果实例化 JavaBean 失败
7 * @throws InvocationTargetException 如果调用属性的 setter 方法失败
8 */
9 @SuppressWarnings({ "rawtypes"})
10 public static SortedMap<Object,Object> convertBean(Object bean) {
11 SortedMap<Object,Object> returnMap = new TreeMap<Object,Object>();
12 try {
13 Class type = bean.getClass();
14 BeanInfo beanInfo = Introspector.getBeanInfo(type);
15 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
16 for (int i = 0; i< propertyDescriptors.length; i++) {
17 PropertyDescriptor descriptor = propertyDescriptors[i];
18 String propertyName = descriptor.getName();
19 if (!propertyName.equals("class")) {
20 Method readMethod = descriptor.getReadMethod();
21 Object result = readMethod.invoke(bean, new Object[0]);
22 if (result != null) {
23 returnMap.put(propertyName, result);
24 } else {
25 returnMap.put(propertyName, "");
26 }
27 }
28 }
29 } catch (IntrospectionException e) {
30 e.printStackTrace();
31 } catch (IllegalAccessException e) {
32 e.printStackTrace();
33 } catch (IllegalArgumentException e) {
34 e.printStackTrace();
35 } catch (InvocationTargetException e) {
36 e.printStackTrace();
37 }
38 return returnMap;
39 }
40
41
42 /**
43 * 生成签名
44 * @param parameters
45 * @return
46 */
47 public static String createSgin(SortedMap<Object,Object> parameters)
48 {
49 StringBuffer sb = new StringBuffer();
50 Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
51 Iterator it = es.iterator();
52 while(it.hasNext()) {
53 Map.Entry entry = (Map.Entry)it.next();
54 String k = (String)entry.getKey();
55 Object v = entry.getValue();
56 if(null != v && !"".equals(v)
57 && !"sign".equals(k) && !"key".equals(k)) {
58 sb.append(k + "=" + v + "&");
59 }
60 }
61 sb.append("key=" + wxConfig.getWxKey());
62 String sgin=MD5.sign(sb.toString());
63 return sgin;
64 }
1 /**
2 * 获取ip地址
3 * @param request
4 * @return
5 */
6 public static String getIpAddr(HttpServletRequest request) {
7 InetAddress addr = null;
8 try {
9 addr = InetAddress.getLocalHost();
10 } catch (UnknownHostException e) {
11 return request.getRemoteAddr();
12 }
13 byte[] ipAddr = addr.getAddress();
14 String ipAddrStr = "";
15 for (int i = 0; i < ipAddr.length; i++) {
16 if (i > 0) {
17 ipAddrStr += ".";
18 }
19 ipAddrStr += ipAddr[i] & 0xFF;
20 }
21 return ipAddrStr;
22 }



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


1 /**
2 * 获得指定长度的随机字符串
3 * @author Administrator
4 *
5 */
6 public class StringWidthWeightRandom {
7 private int length = 32;
8 private char[] chars = new char[]{
9 '0','1','2','3','4','5','6','7','8','9',
10 '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',
11 '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'
12 };
13 private Random random = new Random();
14
15 //参数为生成的字符串的长度,根据给定的char集合生成字符串
16 public String getNextString(int length){
17
18 char[] data = new char[length];
19
20 for(int i = 0;i < length;i++){
21 int index = random.nextInt(chars.length);
22 data[i] = chars[index];
23 }
24 String s = new String(data);
25 return s;
26 }
27
28 public int getLength() {
29 return length;
30 }
31
32 public void setLength(int length) {
33 this.length = length;
34 }
35 }


1 public class UtilDate {
2
3 /** 年月日时分秒(无下划线) yyyyMMddHHmmss */
4 public static final String dtLong = "yyyyMMddHHmmss";
5
6 /** 完整时间 yyyy-MM-dd HH:mm:ss */
7 public static final String simple = "yyyy-MM-dd HH:mm:ss";
8
9 /** 年月日(无下划线) yyyyMMdd */
10 public static final String dtShort = "yyyyMMdd";
11
12
13 /**
14 * 返回系统当前时间(精确到毫秒),作为一个唯一的订单编号
15 * @return
16 * 以yyyyMMddHHmmss为格式的当前系统时间
17 */
18 public static String getDateLong(){
19 Date date=new Date();
20 DateFormat df=new SimpleDateFormat(dtLong);
21 return df.format(date);
22 }
23
24 /**
25 * 获取系统当前日期(精确到毫秒),格式:yyyy-MM-dd HH:mm:ss
26 * @return
27 */
28 public static String getDateFormatter(){
29 Date date=new Date();
30 DateFormat df=new SimpleDateFormat(simple);
31 return df.format(date);
32 }
33
34 /**
35 * 获取系统当期年月日(精确到天),格式:yyyyMMdd
36 * @return
37 */
38 public static String getDate(){
39 Date date=new Date();
40 DateFormat df=new SimpleDateFormat(dtShort);
41 return df.format(date);
42 }
43
44
45
46 }


1 public class MD5 {
2 public static String sign(String str){
3 MessageDigest md5;
4 String sgin = "";
5 try {
6 md5 = MessageDigest.getInstance("MD5");
7 md5.reset();
8 md5.update(str.getBytes("UTF-8"));
9 sgin = byteToStr(md5.digest()).toUpperCase();
10 } catch (NoSuchAlgorithmException e) {
11 e.printStackTrace();
12 } catch (UnsupportedEncodingException e) {
13 e.printStackTrace();
14 }
15 return sgin;
16 }
17
18 /**
19 * 将字节数组转换为十六进制字符串
20 *
21 * @param byteArray
22 * @return
23 */
24 public static String byteToStr(byte[] byteArray) {
25 String strDigest = "";
26 for (int i = 0; i < byteArray.length; i++) {
27 strDigest += byteToHexStr(byteArray[i]);
28 }
29 return strDigest;
30 }
31
32 /**
33 * 将字节转换为十六进制字符串
34 *
35 * @param btyes
36 * @return
37 */
38 public static String byteToHexStr(byte bytes) {
39 char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
40 char[] tempArr = new char[2];
41 tempArr[0] = Digit[(bytes >>> 4) & 0X0F];
42 tempArr[1] = Digit[bytes & 0X0F];
43
44 String s = new String(tempArr);
45 return s;
46 }
47
48 }