HTTP-java模拟GET/POST请求(忽略/不忽略证书)

1、请求的形式

  • GET请求:把请求的数据放在URL上,用?分割URL和传输的数据,多个参数的话用&符号连接。
  • POST请求:把请求的数据放在HTTP请求包的包体中(requrest body)。

            POST请求包含两个部分:请求头(header)和请求体(body)

1.Java发送post请求:

        代码示例如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import org.apache.log4j.Logger;

import com.xwtech.parser.PostRequestHtmlParser;

/**
 * Post请求类——得到HTML响应
 */
public class PostRequest extends Thread {
    private String url = "https://b2b.10086.cn/b2b/main/listVendorNoticeResult.html?noticeBean.noticeType=";
    private String params;
    private Logger logger;

    public PostRequest(int noticeType, int perPageSize) {
        logger = Logger.getLogger(PostRequest.class);
        this.url = this.url + noticeType;  //拼接URL请求,不包含参数
        params = "page.currentPage=" + currentPage + "&page.perPageSize=" + perPageSize
                + "&noticeBean.sourceCH=&noticeBean.source="
                + "&noticeBean.title=&noticeBean.startDate=&noticeBean.endDate=";
    }

    public void run() {
        PrintWriter out = null;
        BufferedReader in = null;
        URLConnection conn = null;
        String result = "";
        try {
            conn = new URL(url).openConnection();
            conn.setUseCaches(false);
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36");
            conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);

            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(params);
            // flush输出流的缓冲
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            logger.error(currentThread().getName() + "线程Post请求出现问题!\n" + e.getMessage() + "\n");
        } finally {// 使用finally块来关闭输出流、输入流
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                logger.error(currentThread().getName() + "线程Post请求数据流出现问题!\n" + ex.getMessage() + "\n");
            }
        }
        //获取到相应结果result ,可以直接在这里进行下一步处理,或者放入到全局字段中,通过其他方式获取......
    }
}

2.Java发送get请求:

        代码示例如下:

1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 import java.net.HttpURLConnection;
 5 import java.net.URL;
 6  8 import javax.net.ssl.HttpsURLConnection;10 
11 import org.apache.log4j.Logger;13 16 /*
17  * GET请求类,非线程类
18  */
19 public class GetRequest {
20     private String url = "https://b2b.10086.cn/b2b/main/viewNoticeContent.html?noticeBean.id=";
21     private Logger logger;
22     public GetRequest() {
23         logger = Logger.getLogger(GetRequest.class);
24     }
25 
26     public ExtendCandidate getData(String id) {
27         this.url = url + id;
28         BufferedReader in = null;
29         HttpURLConnection conn = null;
30         String result = "";
31         try {
32             conn = (HttpURLConnection)new URL(url).openConnection();
33             // 发送GET请求必须设置如下两行
34             conn.setDoInput(true);
35             conn.setRequestMethod("GET");
36             // flush输出流的缓冲
37             in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
38             String line;
39             while ((line = in.readLine()) != null) {
40                 result += line;
41             }
42         } catch (Exception e) {
43             logger.error("发送 GET 请求出现异常!\t请求ID:"+id+"\n"+e.getMessage()+"\n");
44         } finally {// 使用finally块来关闭输出流、输入流
45             try {
46                 if (in != null) {
47                     in.close();
48                 }
49             } catch (IOException ex) {
50                 logger.error("关闭数据流出错了!\n"+ex.getMessage()+"\n");
51             }
52         }
53         //获取到结果result,可以直接添加处理,或者存储到全局变量......
54     }
55 }

3.Java发送get/post请求(忽略证书信任问题):

java程序在访问https资源时,出现如下报错:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.ssl.Alert.createSSLException(Alert.java:131)
	at sun.security.ssl.TransportContext.fatal(TransportContext.java:353)
......
	at java.lang.Thread.run(Thread.java:748)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
	at sun.security.validator.Validator.validate(Validator.java:271)
	at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:312)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:221)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:128)
	at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:636)
	... 107 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
	... 113 more

下面解决示例:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import org.apache.log4j.Logger;
import org.htmlparser.util.ParserException;

import com.xwtech.parser.GetRequestHtmlParser;
import com.xwtech.pojo.ExtendCandidate;
/*
 * GET请求类
 */
public class GetRequest {
    private String url = "https://b2b.10086.cn/b2b/main/viewNoticeContent.html?noticeBean.id=";
    private Logger logger;
    public GetRequest() {
        logger = Logger.getLogger(GetRequest.class);
    }
    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());
    }
    //为更好的演示,去掉了不相关的代码
    public void getData(String id) {
        this.url = url + id;
        BufferedReader in = null;
        HttpURLConnection conn = null;
        String result = "";
        try {        //该部分必须在获取connection前调用
            trustAllHttpsCertificates();
            HostnameVerifier hv = new HostnameVerifier() {
                public boolean verify(String urlHostName, SSLSession session) {
                    logger.info("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                    return true;
                }
            };
            HttpsURLConnection.setDefaultHostnameVerifier(hv);
            conn = (HttpURLConnection)new URL(url).openConnection();
            // 发送GET请求必须设置如下两行
            conn.setDoInput(true);
            conn.setRequestMethod("GET");
            // flush输出流的缓冲
            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            logger.error("发送 GET 请求出现异常!\t请求ID:"+id+"\n"+e.getMessage()+"\n");
        } finally {// 使用finally块来关闭输出流、输入流
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                logger.error("关闭数据流出错了!\n"+ex.getMessage()+"\n");
            }
        }
        // 获得相应结果result,可以直接处理......
        
    }
    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;
        }
    }
}

 就是在进行连接前需要显示调用以下进行忽略证书信任 

trustAllHttpsCertificates();    // 这是一个方法,具体见上面
HttpsURLConnection.setDefaultHostnameVerifier(hv);        //这里HttpsURLConnection是类名,hv参数需要自己创建,具体可以参考上面。

Post请求需要忽略证书信任与这个一样,在获取连接前,加上trustAllHttpsCertificates方法。


                
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Qt可以通过QNetworkAccessManager类来实现HTTP的GET/POST请求。 1. GET请求: ```cpp QNetworkAccessManager *manager = new QNetworkAccessManager(this); QNetworkRequest request; request.setUrl(QUrl("http://www.example.com")); QNetworkReply *reply = manager->get(request); connect(reply, &QNetworkReply::finished, [=]() { if (reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); // 处理返回的数据 } else { // 处理错误 } reply->deleteLater(); }); ``` 2. POST请求: ```cpp QNetworkAccessManager *manager = new QNetworkAccessManager(this); QNetworkRequest request; request.setUrl(QUrl("http://www.example.com")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); QByteArray postData; postData.append("key1=value1&key2=value2"); QNetworkReply *reply = manager->post(request, postData); connect(reply, &QNetworkReply::finished, [=]() { if (reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); // 处理返回的数据 } else { // 处理错误 } reply->deleteLater(); }); ``` 以上代码仅供参考,具体实现还需要根据实际情况进行调整。 ### 回答2: Qt是一个跨平台的GUI应用程序开发框架,也支持网络编程。Qt通过QNetworkAccessManager类来访问网络资源,可以很容易地实现HTTP的GETPOST请求GET请求: 使用Qt进行GET请求时,需要创建QNetworkRequest对象并设置URL,然后传递到QNetworkAccessManager的get函数中。QNetworkAccessManager会自动地发送请求,并在请求完成时发出finished信号。 示例代码如下: ``` QNetworkRequest request; request.setUrl(QUrl("http://www.example.com")); QNetworkReply *reply = manager->get(request); connect(reply, &QNetworkReply::finished, [=]() { if (reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); qDebug() << data; } else { qDebug() << reply->errorString(); } reply->deleteLater(); }); ``` POST请求: 使用Qt进行POST请求时,需要创建QNetworkRequest对象并设置URL,然后传递到QNetworkAccessManager的post函数中,同时传递POST数据。Qt支持多种数据格式,包括字符串、字节数组和QIODevice对象。在POST请求中,需要设置Content-Type头部以指定POST数据的格式。 示例代码如下: ``` QNetworkRequest request; request.setUrl(QUrl("http://www.example.com")); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); QByteArray postData; postData.append("param1=value1&param2=value2"); QNetworkReply *reply = manager->post(request, postData); connect(reply, &QNetworkReply::finished, [=]() { if (reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); qDebug() << data; } else { qDebug() << reply->errorString(); } reply->deleteLater(); }); ``` 以上是Qt实现HTTP的GETPOST请求的基本方案,根据实际需求可以自行调整和添加参数。 ### 回答3: Qt是一种跨平台应用程序开发框架,它提供了许多方便的类和函数,方便程序员开发功能强大的应用程序。Qt提供了QNetworkAccessManager类,可以用来实现Http请求GETPOST方法。 QNetworkAccessManager是Qt中提供的用于管理网络请求的类,它使我们可以进行HTTP请求,下载和上传文件等操作。在使用QNetworkAccessManager时,首先要创建一个实例对象,并为该对象关联一个信号槽。当网络请求完成时,QNetworkAccessManager会发出一个信号,告知程序请求已完成。 下面是一个简单的例子,展示了如何使用QNetworkAccessManager实现Http的GET请求: ``` QNetworkAccessManager *manager = new QNetworkAccessManager(this); QUrl url("http://www.example.com"); QNetworkRequest request(url); QNetworkReply *reply = manager->get(request); connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); void MyClass::replyFinished() { qDebug() << reply->readAll(); reply->deleteLater(); } ``` 在上面的代码中,我们首先创建了QNetworkAccessManager的一个实例对象,然后为其关联了一个URL,发起了一个GET请求。当请求完成后,replyFinished()函数会被调用,我们在该函数中使用readAll()函数读取服务器返回的数据,并将其打印到应用程序的控制台上。 如果我们需要实现POST请求,则只需要将上面的代码稍作修改即可: ``` QNetworkAccessManager *manager = new QNetworkAccessManager(this); QUrl url("http://www.example.com"); QNetworkRequest request(url); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); QByteArray postData; postData.append("key1=value1"); postData.append("&key2=value2"); QNetworkReply *reply = manager->post(request, postData); connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); void MyClass::replyFinished() { qDebug() << reply->readAll(); reply->deleteLater(); } ``` 在上述代码中,我们创建了一个QByteArray对象,用来存放需要提交的POST数据。然后用QNetworkAccessManager的post()函数提交POST请求,并在请求完成后读取服务器的响应数据。其中setHeader()函数用来设置POST请求的Content-Type header,告诉服务器发送的数据的格式。 总之,Qt提供的QNetworkAccessManager类可以方便实现HTTP的GETPOST请求。开发者可以根据自己的需求进行调整,并根据服务器返回的数据进行相应的处理和逻辑控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微笑乀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值