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 }