會員註冊 / 登入  |  電腦版  |  Jump to bottom of page

網頁程式設計 Web Development » 如何用httpclient4去存取SSL的網頁資料?

發表人: collectWu, 十級學員
2011-05-10 17:05:55
版主,您好,

我想用httpclient4來存取SSL的網頁,但又不想匯入對方憑証,有什麼好方法嗎?感謝!

發表人: andowson, 七段學員
2011-05-18 11:54:41
下載函式庫: HttpClient 4.1.1 (GA)
http://hc.apache.org/downloads.cgi

預先安裝函式庫:commons-logging-1.1.1.jar, httpcore-4.1.jar, httpclient-4.1.1.jar

這裡我以Servlet 3.0標準來當做練習,請在Tomcat 7.0以上版本執行:
HttpClientServlet.java:
package com.andowson.httpclient;


import java.io.IOException;
import java.io.PrintWriter;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

/**
* Servlet implementation class HttpClientServlet
*/
@WebServlet("/HttpClientServlet")
public class HttpClientServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public HttpClientServlet() {
super();
}

/**
* @see Servlet#getServletInfo()
*/
public String getServletInfo() {
return "HttpClient Servlet";
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String url = request.getParameter("url");
if (url == null) {
url = "https://ups.moe.edu.tw/";
}

DefaultHttpClient httpclient = new DefaultHttpClient();
HttpHost proxy = new HttpHost("10.160.3.88", 8080);
httpclient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
try {
TrustManager easyTrustManager = new X509TrustManager() {

@Override
public void checkClientTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
// Oh, I am easy!
}

@Override
public void checkServerTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
// Oh, I am easy!
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};

SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(null, new TrustManager[] { easyTrustManager }, null);

SSLSocketFactory socketFactory = new SSLSocketFactory(sslcontext,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme sch = new Scheme("https", 443, socketFactory);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);

HttpGet httpget = new HttpGet(url);

System.out.println("executing request " + httpget.getRequestLine());

HttpResponse resp = httpclient.execute(httpget);
HttpEntity entity = resp.getEntity();
System.out.println("----------------------------------------");
System.out.println(resp.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
EntityUtils.consume(entity);

response.setContentType(entity.getContentType().toString());
PrintWriter out = response.getWriter();

ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpget, responseHandler);
System.out.println("----------------------------------------");
System.out.println(responseBody);
out.println(responseBody);
System.out.println("----------------------------------------");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} finally {
httpclient.getConnectionManager().shutdown();
}
}

/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}

}


修改web.xml,加入下列項目:

<servlet>
<servlet-name>HttpClientServlet</servlet-name>
<servlet-class>com.andowson.httpclient.HttpClientServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HttpClientServlet</servlet-name>
<url-pattern>/servlet/httpclient</url-pattern>
</servlet-mapping>


說明:
63-64行是如果伺服器需要透過Proxy才能連到Internet(例如公司內部網站)執行時需透過Proxy的設定方式,如果伺服器可以直接連接到Internet時這兩行需要mark為註解掉。

參考資料:
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e537

檔案名稱 HttpClientServlet.java
描述 HttpClientServlet.java
檔案大小 4 Kbytes
下載次數 4 次
[Disk] 下載


發表人: bious3927, 十級學員
2011-06-02 15:01:07
如果要輸出檔案的話,也非常簡便,可以使用HttpEntity 提供的方法: writeTo()

比以下常用的寫法節省不少程式, 也避免了特殊字無法正常輸出的情況:

FileOutputStream fos = new FileOutputStream(request.getParameter("path"));
ByteArrayInputStream bais = new ByteArrayInputStream(httpclient.execute(httpget, responseHandler).getBytes());

byte[] bytes = new byte[1024];
int count = 0;

while (bais!=null && (count = bais.read(bytes))!=-1) {
fos.write(bytes, 0, count);
}


可於版主提供的程式105行中,加入以下程式


entity.writeTo(new FileOutputStream(request.getParameter("path")));




會員註冊 / 登入  |  電腦版  |  Jump to top of page