Java 发送HTTP或HTTPS请求获取网页码源(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HoKis/article/details/53445964
闲来无事,封装了一个简单的工具类,用于向某个URL发送请求并获取响应的文本内容。发送HTTP请求的方式比较简单,但用来发送HTTPS请求却不行的。
于是查了一些资料,根据前人经验写了这个工具类,能够区分URL是HTTP类型还是HTTPS类型的,但对HTTPS方式的原理的研究尚浅,也只是拿来便用。
因为是工具类,所有方法均为static修饰,但只对外部提供了getSourceFromUrl(String url,String charsetName) 和 getSourceFromUrl(String url) 
两个重载的方法,第一个可以按指定编码读取流。
码源如下,JDK1.7下测试通过,仅使用JDK提供的Jar包:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * 通用工具类
 * 更新:2016-12-3 16:13:27
 * 版本:1.0.0
 */
public final class CommonNetUtil {
    //默认编码
    private final static String CHARSETNAME = "UTF-8";

    //协议类型
    private final static String HTTP = "http:";
    private final static String HTTPS = "https:";


    /**
     * 判断协议类型,转发到不同的方法进行处理
     * @throws IOException 
     */
    private static String chooseProtocol(String url,String charsetName) throws IOException{
        if (url == null) {
            throw new RuntimeException("url shouldn't be null.");
        }
        //字符编码格式
        if (charsetName == null){
            throw new NullPointerException("charsetName shouldn't be null.");
        }

        if (!url.startsWith(HTTP) && !url.startsWith(HTTPS)) {
            throw new RuntimeException("url format is not supported.");
        }
        //如果是http协议
        if (url.startsWith(HTTP)) {
            return getFromHttp(url,charsetName);

        }else if (url.startsWith(HTTPS)) {
            //如果是https协议
            return getFromHttps(url, charsetName);
        }
        return null;
    }

    /**
     * http协议的url
     * @param url
     * @param charsetName
     * @return
     * @throws IOException
     */
    private static String getFromHttp(String url,String charsetName) throws IOException{
        HttpURLConnection con = null;
        try {
            // 打开网页
            con = (HttpURLConnection) new URL(url).openConnection();
            con.connect();
            //判断状态码
            if (con.getResponseCode() == 200) {
                //读取流
                return getTextFromCon(con,charsetName);
            }
        } catch (IOException e) {
            throw new IOException("Connet exception.", e);
        } finally { 
            if (con != null) {
                con.disconnect();
            }
        }

        return null;
    }

    /**
     * https协议的url
     * @param url
     * @param charsetName
     * @return
     * @throws IOException
     */
    private static String getFromHttps(String url,String charsetName) throws IOException{
        HttpsURLConnection httpsConn = null;
        try {
            //构造TrustManager 对象数组
            TrustManager[] tm = {new X509TrustManager() {

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

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {

                }

                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {

                }
            }}; 

            //创建SSLContext对象,并使用我们指定的信任管理器初始化
            SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); 
            sslContext.init(null, tm, new SecureRandom());

            //从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            //创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
            httpsConn = (HttpsURLConnection)new URL(url).openConnection();
            httpsConn.setSSLSocketFactory(ssf);
            //连接
            httpsConn.connect();

            //判断状态码
            if (httpsConn.getResponseCode() == 200) {
                //读取流
                return getTextFromCon(httpsConn,charsetName);
            }

        } catch (Exception e) {
            throw new IOException("Connet exception.", e);
        }finally{
            if (httpsConn != null) {
                httpsConn.disconnect();
            }

        }
        return null;
    }

    /**
     * 从流中读取数据
     * @param con
     * @param charsetName
     * @return
     * @throws IOException
     */
    private static String getTextFromCon(URLConnection con,String charsetName) throws IOException{
        StringBuffer sb = new StringBuffer();
        try(
                BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),charsetName));
                ) {
            String s = null;
            while ((s = br.readLine()) != null)  {
                //sb.append(s);  //不换行
                sb.append(s + "\n"); //换行
            }
            return sb.toString();

        } catch (IOException e) {
            throw new IOException("Read stream exception.", e);
        }
    }


    /**
     * 根据URL获取码源
     * @param url
     * @return 返回字符串型码源
     * @throws IOException
     */
    public static String getSourceFromUrl(String url) throws IOException {
        return chooseProtocol(url, CHARSETNAME);
    }

    /**
     * 根据URL获取码源,可指定用何种编码进行解码
     * @param url 
     * @param charsetName 编码类型
     * @return 返回字符串型码源
     * @throws IOException
     */
    public static String getSourceFromUrl(String url,String charsetName) throws IOException {

        return chooseProtocol(url, charsetName);

    }

}

测试类:

import java.io.IOException;
/* 测试类*/
public class Test {

    public static void main(String[] args) {

        String url = "https://www.baidu.com";
        try {
            String content= CommonNetUtil.getSourceFromUrl(url);
            System.out.println(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果:
效果图

记录到此。

发送HTTPS请求参考了此文,http://blog.csdn.net/lifj07/article/details/8638098,表示感谢。

猜你喜欢

转载自blog.csdn.net/HoKis/article/details/53445964