package com.isoftstone.core.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; /**
* https post发送工具
*
* @author 超神之巅
*
*/
public class HttpsTool {
private static final String LINE_SEPARATOR = System.getProperty("line.separator"); static HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
}; private static void trustAllHttpsCertificates() throws Exception {
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new miTM();
trustAllCerts[0] = tm;
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
.getInstance("SSL");
sc.init(null, trustAllCerts, null);
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
.getSocketFactory());
} static class miTM implements javax.net.ssl.TrustManager,
javax.net.ssl.X509TrustManager {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
} public boolean isServerTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
} public boolean isClientTrusted(
java.security.cert.X509Certificate[] certs) {
return true;
} public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
} public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType)
throws java.security.cert.CertificateException {
return;
}
} /**
* 发送报文
*
* 通信失败时返回分两种:一种是抛异常,一种是返回"",本方法取前者
*
* @param requestData
* 请求报文
* @param headMap
* head请求头参数 conn.setRequestProperty(key,value)
* @param urlStr
* 请求地址
* @param sendEncoding
* 请求编码
* @param recvEncoding
* 返回编码
* @param connectionTimeout
* 链接超时时间 1000代表 1秒
* @param readTimeout
* 读取超时时间 1000代表1秒
* @return
* @throws IOException
* @author 超神之巅
*/
public static String send(String requestData,Map<String,String> headMap, String urlStr, String sendEncoding, String recvEncoding, int connectionTimeout, int readTimeout,String contentType) throws Exception {
URL url = null;
HttpsURLConnection conn = null;
ByteArrayOutputStream byteOut = null;
BufferedReader readInfo = null;
StringBuilder retBuilder = new StringBuilder();// 这里用不着多线程安全的StringBuffer
OutputStream out = null;
String line = null;
StringBuilder reqDetailProcedure = new StringBuilder();// 这里用不着多线程安全的StringBuffer
Date startTime = new Date();
reqDetailProcedure.append("请求时间:【" + DATE_FORMATER.format(startTime) + "】").append("\r\n");
reqDetailProcedure.append("请求地址:【" + urlStr + "】").append("\r\n");
reqDetailProcedure.append("真实请求方式及编码:【post " + sendEncoding + "】").append("\r\n");
reqDetailProcedure.append("期望返回编码:【" + recvEncoding + "】").append("\r\n");
reqDetailProcedure.append("请求超时时间:【" + readTimeout / 1000 + "s】").append("\r\n");
reqDetailProcedure.append("请求报文:【" + requestData + "】").append("\r\n");
try {
// 如有必要,给?后的参数加encode(xxx,"UTF-8"),不然目标系统可能收到的request.getParameter()是乱码
// String arg = java.net.URLEncoder.encode("中国","UTF-8");
// url = new URL(urlStr+"?deptname="+arg); url = new URL(urlStr); trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv); conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");
// 新增部分
//conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.setRequestProperty("SOAPAction", "\"\"");
conn.setRequestProperty("Accept", "application/xml, application/json,application/dime, multipart/related, text/*"); // 如果没有下面这一行代码,服务器端可以通过request.getParameter()和request.getInputStream()都接收到相同信息 // Content-Type相关知识链接: http://www.cnblogs.com/whatlonelytear/p/6187575.html
// conn如果不设Content-Type,则默认成application/x-www-form-urlencoded
// 当然也可以配置成application/x-www-form-urlencoded;charset=UTF-8,此时要求服务端返回UTF-8编码,如果本地还用gbk去解码,有可能得到乱码
conn.setRequestProperty("Content-Type", contentType);
// 如果把Content-Type的类型改变成非application/x-www-form-urlencoded,如改成text/xml,
// 则目标服务器端仅能通过request.getInputStream()接收信息, 如conn.setRequestProperty("Content-Type", "text/xml;charset=GBK");
// Content-Type各类型解释: http://blog.csdn.net/blueheart20/article/details/45174399 // conn.setRequestProperty("Accept-Charset", "utf-8");//未知 //Cache-Control说明链接:http://huangyunbin.iteye.com/blog/1943310 或 http://www.cnblogs.com/whatlonelytear/articles/6385390.html
conn.setRequestProperty("Cache-Control", "no-cache"); //设置head头,如果已存在,则覆盖之前的head配置
if(headMap != null){
for(Map.Entry<String, String > entry : headMap.entrySet()){
conn.setRequestProperty(entry.getKey(),entry.getValue());
} } // conn.setRequestProperty("appName", appName);//各系统需要设置应用系统名,如电销为telesales(无意义,本人自定义)
conn.setUseCaches(false); // 忽略缓存
// get请求用不到conn.getOutputStream(),因为参数直接追加在地址后面,因此默认是false.
// post请求(比如:文件上传)需要往服务区传输大量的数据,这些数据是放在http的body里面的,因此需要在建立连接以后,往服务端写数据.
// 因为总是使用conn.getInputStream()获取服务端的响应,因此默认值是true.
conn.setDoOutput(true); // 使用 URL
// 连接进行输出,允许使用conn.getOutputStream().write()
conn.setDoInput(true); // 使用 URL
// 连接进行输入,允许使用conn.getInputStream().read();
conn.setConnectTimeout(connectionTimeout);// 链接超时
conn.setReadTimeout(readTimeout);// 读取超时
conn.connect();// 建立链接
byteOut = new ByteArrayOutputStream();
byteOut.write(requestData.getBytes(sendEncoding));// 以指定编码发送,如果有乱码,修改之
byte[] buf = byteOut.toByteArray();
out = conn.getOutputStream();
out.write(buf);
out.flush();
reqDetailProcedure.append("响应码和状态:【" + conn.getResponseCode() + "/" + conn.getResponseMessage() + "】").append("\r\n");
if (HttpURLConnection.HTTP_OK == conn.getResponseCode()) {// 正确返回
InputStream tempStream = conn.getInputStream();
readInfo = new BufferedReader(new java.io.InputStreamReader(tempStream, recvEncoding));// 以指定编码读取返回信息,如果有乱码,修改之
while ((line = readInfo.readLine()) != null) {
retBuilder.append(line).append(LINE_SEPARATOR);
}
} else {// 没有正确返回
// 这个else分支有冗余代码,一来代码不多,二来这个分支是经过长时间思考,还是保留了下来,方便我以后对错误做不抛异常处理等
InputStream tempStream = conn.getInputStream();// 如果响应码不是200,一般在这里就开始报异常,不会走到下面几行中去的.
readInfo = new BufferedReader(new java.io.InputStreamReader(tempStream, recvEncoding));// cannotReach
while ((line = readInfo.readLine()) != null) {// cannotReach
retBuilder.append(line);// cannotReach
}// cannotReach
reqDetailProcedure.append("@@返回异常报文:【" + retBuilder + "】").append("\r\n");// cannotReach
}
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
// 目标服务端用response.setContentType("text/html;charset=UTF-8");然后源调用方可以用conn.getContentType()获取到[猜测,暂未测试]
// conn.getContentType()包含在Head返回的内容中.
// 返回如果带编码,可以做成动态编码去把流转成字符串,暂不优化.这是极好的l优化点.
reqDetailProcedure.append("返回内容类型及编码:【" + conn.getContentType() + "】").append("\r\n");
reqDetailProcedure.append("返回HEAD头信息:【" + conn.getHeaderFields() + "】").append("\r\n");
reqDetailProcedure.append("返回报文:【" + retBuilder.toString() + "】").append("\r\n");
Date endTime = new Date();
reqDetailProcedure.append("返回时间:【" + DATE_FORMATER.format(endTime) + "】").append("\r\n");
long diffMilliSecond = endTime.getTime() - startTime.getTime();
long diffSecond = (diffMilliSecond / 1000);
reqDetailProcedure.append("耗时:【" + diffMilliSecond + "】毫秒,大约" + "【" + diffSecond + "】秒").append("\r\n");
System.out.println(reqDetailProcedure.toString());
//ThreadLocalListContainer.put(reqDetailProcedure.toString());
// ThreadLocalMapContainer.put(KingConstants.REQ_DETAIL_PROCEDURE,reqDetailProcedure.toString())
try {
if (readInfo != null) {
readInfo.close();
}
if (byteOut != null) {
byteOut.close();
}
if (out != null) {
out.close();
}
if (conn != null) {
conn.disconnect();
}
} catch (Exception e) {
System.out.println("关闭链接出错!" + e.getMessage());
} }
return retBuilder.toString();
} /**
* 发送报文
*
* 通信失败时返回分两种:一种是抛异常,一种是返回"",本方法取前者
*
* @param requestData
* 请求报文
* @param urlStr
* 请求地址
* @param sendEncoding
* 请求编码
* @param recvEncoding
* 返回编码
* @param connectionTimeout
* 链接超时时间 1000代表 1秒
* @param readTimeout
* 读取超时时间 1000代表1秒
* @return
* @throws IOException
* @author 超神之巅
*/
public static String send(String requestData, String urlStr, String sendEncoding, String recvEncoding, int connectionTimeout, int readTimeout) throws Exception {
boolean flag = isJson(requestData);//是否JSON
String contentType="application/soap+xml";
if(flag) {
contentType = "application/json";
}
return send( requestData,null, urlStr, sendEncoding, recvEncoding, connectionTimeout, readTimeout,contentType);
} /**
*
* @param filePath
* 文件绝对路径
* @param encoding
* 读取文件的编码
* @return
* @author 超神之巅
* @throws Exception
*/
public static String readStringFromFile(String filePath, String encoding) {
File file = new File(filePath);
// System.out.println("文件 "+filePath+"存在与否?: "+ file.exists());
String tempLine = null;
String retStr = "";
InputStreamReader isr = null;// way1:
// FileReader fr = null;//way2
StringBuilder sb = new StringBuilder();
try {
if (file.exists()) {
isr = new InputStreamReader(new FileInputStream(file), encoding);// way1:
// fr = new FileReader(file);//way2
BufferedReader br = new BufferedReader(isr);// way1:
// BufferedReader br = new BufferedReader(fr);;//way2:
tempLine = br.readLine();
while (tempLine != null) {
sb.append(tempLine).append(System.getProperty("line.separator"));
tempLine = br.readLine();
}
retStr = sb.toString();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (isr != null)
isr.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// System.out.println("读到的文件内容如下:");
// System.out.println(retStr);
return retStr;
}
/**
* 判断字符串是否为JSON格式
* @param str
* @return
*/
public static boolean isJson(String str){
if (StringUtils.isBlank(str)) {
return false;
} boolean flag1 = (str.startsWith("{") && str.endsWith("}"));
boolean flag2 = (str.startsWith("[") && str.endsWith("]")); return (flag1 || flag2);
} /*public static final void writeInfo(HttpServletResponse resp, String errorCode, String respInfo, Map<String, Object> map) {
map.put("errorCode", errorCode);
map.put("respInfo", respInfo);
String detail = ThreadLocalListContainer.getAll();
map.put(KingConstants.DETAIL_PROCEDURE, detail);
ThreadLocalListContainer.clearAll();
// map.put(KingConstants.DETAIL_PROCEDURE, detail);
try {
// String gsonInfo = new Gson().toJson(map);//old
Gson gson = new GsonBuilder().setPrettyPrinting().create();//new
String gsonInfo = gson.toJson(map);
PrintWriter pw = resp.getWriter();
pw.print(gsonInfo);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}*/ /**
*
* @param resp
* @param errorCode
* @param respInfo
* @param map
* ......
* @time 2017年4月23日 上午9:12:43
* @author 超神之巅
*/
/*public static final void writeInfo(HttpServletResponse resp, KingResp result) {
String detail = ThreadLocalListContainer.getAll();
result.setDetailProcedure(detail);
ThreadLocalListContainer.clearAll();
try {
// String gsonInfo = new Gson().toJson(map);//old
Gson gson = new GsonBuilder().setPrettyPrinting().create();//new
String gsonInfo = gson.toJson(result);
FileTool.writeStringToFile("d:/temp/myinfo.txt", gsonInfo, "gbk", false);
PrintWriter pw = resp.getWriter();
pw.print(gsonInfo);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}*/ public static final void writeInfo(HttpServletResponse resp, String respInfo) {
try {
PrintWriter pw = resp.getWriter();
pw.print(respInfo);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
} public static final SimpleDateFormat DATE_FORMATER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:sss"); public static void main(String[] args) throws Exception {
String requestUrl = "https://bx.zhcgs.gov.cn:8060/NewBxInfo/BxInfo.asmx";
//把cacerts20181015文到该目录
System.setProperty("javax.net.ssl.trustStore",
"K:\\myprogram\\jdk\\jdk8\\jdk1.8.0_141\\jre\\lib\\security\\cacerts20181015");
String requestData = readStringFromFile("d:/file/send.xml", "UTF-8");// 有乱码,请修改指定编码
String sencXml = HttpsTool.send(requestData, requestUrl, "utf-8", "utf-8", 300 * 1000, 300 * 1000);// 大家最终只要使用这一句代码就可调用
}
}

https请求之绕过证书安全校验工具类(原)的更多相关文章

  1. https请求之绕过证书安全校验相关配置

    需在weblogic服务器上配置内存溢出的地方加入一行配置: -DUseSunHttpHandler=true      注:空格隔开 然后调用工具类:https://www.cnblogs.com/ ...

  2. Requests对HTTPS请求验证SSL证书

    SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socket layer(SSL)安全协议是由Netscape Communication公司设计开发.该安全协议主 ...

  3. requests发送HTTPS请求(处理SSL证书验证)

    1.SSL是什么,为什么发送HTTPS请求时需要证书验证? 1.1 SSL:安全套接字层.是为了解决HTTP协议是明文,避免传输的数据被窃取,篡改,劫持等. 1.2 TSL:Transport Lay ...

  4. java-TokenProcessor令牌校验工具类

    TokenProcessor令牌校验工具类 public class TokenProcessor { private long privious;// 上次生成表单标识号得时间值 private s ...

  5. java常用正则校验工具类

    正则常用校验工具类 import java.util.regex.Pattern; /** * @program: * @description: 校验工具类 * @author: xujingyan ...

  6. JavaScript 数据值校验工具类

    /** * 数据值校验工具类 */ var checkService = { // 不校验 none: function () { return true; }, //非空校验 isEmpty: fu ...

  7. iOS开发 支持https请求以及ssl证书配置(转)

    原文地址:http://blog.5ibc.net/p/100221.html 众所周知,苹果有言,从2017年开始,将屏蔽http的资源,强推https 楼主正好近日将http转为https,给还没 ...

  8. jmeter测试https请求之导入证书

    jmeter测试https请求   公司最近在搞全站HTTPS改造,进一步提高网站的安全性,防止运营商劫持.那么,改造完成后,所有前后端的URL将全部为https. So ,研究下怎么用Jmeter访 ...

  9. 前端参数统一校验工具类ValidParamUtils

    1,前端参数不可信,对于后端开发人员来说应该是一条铁律,所以对于前端参数的校验,必不可少,而统一的前端参数校验工具,对我们进行参数校验起到事半功倍的效果 2,统一参数校验工具ValidParamUti ...

随机推荐

  1. ZooKeeper连接并创建节点以及实现分布式锁操作节点排序输出最小节点Demo

    class LockThread implements Runnable { private DistributedLock lock; public LockThread(int threadId, ...

  2. iptables 限制ip访问3306端口

    *filter:INPUT DROP [0:0]  #全部关闭:FORWARD ACCEPT [0:0]:OUTPUT ACCEPT [0:0]-A INPUT -s 172.4.4.14 -p tc ...

  3. 「洛谷3870」「TJOI2009」开关【线段树】

    题目链接 [洛谷] 题解 来做一下水题来掩饰ZJOI2019考炸的心情QwQ. 很明显可以线段树. 维护两个值,\(Lazy\)懒标记表示当前区间是否需要翻转,\(s\)表示区间还有多少灯是亮着的. ...

  4. java实现 链表反转

    输入一个链表,反转链表后,输出新链表的表头. 递归法 public class RevnNode { public static class Node { public int value; publ ...

  5. SNOI 2019 字符串

    SNOI 2019 字符串 题目 题解: 解法一: 记一个数组\(f\),\(f[i]=\min_j\ s[j]\neq s[j+1] (j\geq i)\),直接sort即可,复杂度\(O(nlog ...

  6. Bellman-Ford&&SPFA

    我们前文说过,有关最短路径除了Floyed算法之外,还有许多更加好的方法.这里讲一下有关 Bellman-Ford和SPFA的知识 Bellman-Ford:复杂度O(VE) 有关Bellman-Fo ...

  7. 第四十四篇--做一个简单的QQ登录界面

    功能:输入用户名和密码,正确,显示登录成功,为空的话,提示用户名和密码不能为空,还有记住密码功能. MainActivity.java package com.aimee.android.play.q ...

  8. 20175209 《Java程序设计》第七周学习总结

    20175209 <Java程序设计>第七周学习总结 一.教材知识点总结 第八章 常用类和实用类 1.String类 构造String对象 常量对象:""中的字符序列, ...

  9. 03-oracle中的高级查询

    1.连接查询 1.1 使用连接谓词指定的连接 介绍: 在连接谓词表示形式中,连接条件由比较运算符在WHERE子句中给出,将这种表示形式称为连接谓词表示形式,连接谓词又称为连接条件. 语法: [< ...

  10. Vue学习笔记四:跑马灯效果

    目录 跑马灯原理 HTML 箭头函数 计时器 跑马灯效果 跑马灯原理 先讲讲跑马灯的原理,就是一行字,会滚动,思路是这样的,使用substring方法,一个获取字符串的第一个字,一个获取1后面所有的字 ...