Java 工具类 —— HttpClient从官网示例到工具类开发

作为一个Java开发,相信大家都用过HttpClient去请求外部资源,而在用的时候都是直接在网上Copy工具类,直接调用,而我们不用不了解Client中的一些参数是怎么配置的。所以在出问题了的时候都束手无策。本文就和大家一起从官网的实例去了解HttpClient 的一些基本配置。

在此之前我先把我看过示例之后自己写的工具类分享出来:工具类HttpRequests,点击下载

欢迎下载使用,更希望自己动动手,写一下。


一、查看官网示例

在这里插入图片描述

这里我使用的版本是4.5。

示例思想:

在这里插入图片描述

示例源码(结合上面思想和代码注释):

public final static void main(String[] args) throws Exception {

        // Use custom message parser / writer to customize the way HTTP
        // messages are parsed from and written out to the data stream.
        /**通过用户消息解析器/写入器自定义解析http响应的数据流*/
        /**响应解析器*/
        HttpMessageParserFactory<HttpResponse> responseParserFactory = new DefaultHttpResponseParserFactory() {
            @Override
            public HttpMessageParser<HttpResponse> create(SessionInputBuffer buffer, MessageConstraints constraints) {
                LineParser lineParser = new BasicLineParser() {
                    @Override
                    public Header parseHeader(final CharArrayBuffer buffer) {
                        try {
                            return super.parseHeader(buffer);
                        } catch (ParseException ex) {
                            return new BasicHeader(buffer.toString(), null);
                        }
                    }
                };
                return new DefaultHttpResponseParser(
                        buffer, lineParser, DefaultHttpResponseFactory.INSTANCE, constraints) {

                    @Override
                    protected boolean reject(final CharArrayBuffer line, int count) {
                        // try to ignore all garbage preceding a status line infinitely
                        return false;
                    }

                };
            }

        };
        /**请求处理器*/
        HttpMessageWriterFactory<HttpRequest> requestWriterFactory = new DefaultHttpRequestWriterFactory();

        // Use a custom connection factory to customize the process of
        // initialization of outgoing HTTP connections. Beside standard connection
        // configuration parameters HTTP connection factory can define message
        // parser / writer routines to be employed by individual connections.
        /**Http连接(从三次握手到四次挥手叫做一个连接)管理工厂*/
        HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory = new ManagedHttpClientConnectionFactory(
                requestWriterFactory, responseParserFactory);

        // Client HTTP connection objects when fully initialized can be bound to
        // an arbitrary network socket. The process of network socket initialization,
        // its connection to a remote address and binding to a local one is controlled
        // by a connection socket factory.

        // SSL context for secure connections can be created either based on
        // system or application specific properties.
        /**配置默认HTTPS连接证书认证处理(这里可以有两种处理方式,配置证书给代码或者忽略,我的示例里边是使用忽略证书的方式),
         * 并且丢到Socket里边,http是应用层协议,Socket是在处于应用层和网络层的连接工具(5层模式中)。所以这里是Socket认证证书*/
        SSLContext sslcontext = SSLContexts.createSystemDefault();

        // Create a registry of custom connection socket factories for supported
        // protocol schemes.
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(sslcontext))
                .build();

        // Use custom DNS resolver to override the system DNS resolution.
        /**使用用户自定义DNS*/
        DnsResolver dnsResolver = new SystemDefaultDnsResolver() {

            @Override
            public InetAddress[] resolve(final String host) throws UnknownHostException {
                if (host.equalsIgnoreCase("myhost")) {
                    return new InetAddress[] { InetAddress.getByAddress(new byte[] {127, 0, 0, 1}) };
                } else {
                    return super.resolve(host);
                }
            }

        };

        // Create a connection manager with custom configuration.
        /**上面的DNS, 连接工厂, socke工厂通过连接管理池来统一管理*/
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
                socketFactoryRegistry, connFactory, dnsResolver);

        // Create socket configuration
        SocketConfig socketConfig = SocketConfig.custom()
                .setTcpNoDelay(true)
                .build();
        // Configure the connection manager to use socket configuration either
        // by default or for a specific host.
        connManager.setDefaultSocketConfig(socketConfig);/**配置默认socket配置*/
        connManager.setSocketConfig(new HttpHost("somehost", 80), socketConfig);/**配置特殊请求socket配置*/
        // Validate connections after 1 sec of inactivity
        connManager.setValidateAfterInactivity(1000); //连接池每秒检查一次连接是否活跃

        // Create message constraints
        /**自定义请求消息约束 具体什么约束查看字面意思就行*/
        MessageConstraints messageConstraints = MessageConstraints.custom()
                .setMaxHeaderCount(200)
                .setMaxLineLength(2000)
                .build();
        // Create connection configuration
        /**连接配置*/
        ConnectionConfig connectionConfig = ConnectionConfig.custom()
                .setMalformedInputAction(CodingErrorAction.IGNORE)
                .setUnmappableInputAction(CodingErrorAction.IGNORE)
                .setCharset(Consts.UTF_8)
                .setMessageConstraints(messageConstraints)
                .build();
        // Configure the connection manager to use connection configuration either
        // by default or for a specific host.
        connManager.setDefaultConnectionConfig(connectionConfig);
        connManager.setConnectionConfig(new HttpHost("somehost", 80), ConnectionConfig.DEFAULT);

        // Configure total max or per route limits for persistent connections
        // that can be kept in the pool or leased by the connection manager.
        /**连接管理池大小配置*/
        connManager.setMaxTotal(100);
        connManager.setDefaultMaxPerRoute(10);
        connManager.setMaxPerRoute(new HttpRoute(new HttpHost("somehost", 80)), 20);

        // Use custom cookie store if necessary.
        CookieStore cookieStore = new BasicCookieStore();
        // Use custom credentials provider if necessary.
        /**认证器(可以用于请求目标认证和poxy认证) 包含 host port 账号 密码*/
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(new AuthScope("127.0.0.1", 111), new UsernamePasswordCredentials("", ""));
        // Create global request configuration
        /**请求配置,这个是我们常用的*/
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setCookieSpec(CookieSpecs.DEFAULT)
                .setExpectContinueEnabled(true)
                .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)) //首选认证方式配置
                .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
                .build();

        // Create an HttpClient with the given custom dependencies and configuration.
        /**创建httpClient*/
        CloseableHttpClient httpclient = HttpClients.custom()
                .setConnectionManager(connManager)
                .setDefaultCookieStore(cookieStore)
                .setDefaultCredentialsProvider(credentialsProvider)
                .setProxy(new HttpHost("myproxy", 8080))//使用代理
                .setDefaultRequestConfig(defaultRequestConfig)
                .build();

        try {
            /**实现一次请求*/
            HttpGet httpget = new HttpGet("http://httpbin.org/get");
            // Request configuration can be overridden at the request level.
            // They will take precedence over the one set at the client level.
            RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
                    .setSocketTimeout(5000)
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000) //上方三条超时配置
                    .setProxy(new HttpHost("myotherproxy", 8080)) //使用代理
                    .build();
            httpget.setConfig(requestConfig);

            // Execution context can be customized locally.
            /**请求上下文--请求的所有东西都会放这里*/
            HttpClientContext context = HttpClientContext.create();
            // Contextual attributes set the local context level will take
            // precedence over those set at the client level.
            context.setCookieStore(cookieStore);
            context.setCredentialsProvider(credentialsProvider);

            System.out.println("executing request " + httpget.getURI());
            CloseableHttpResponse response = httpclient.execute(httpget, context);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                System.out.println(EntityUtils.toString(response.getEntity()));
                System.out.println("----------------------------------------");

                // Once the request has been executed the local context can
                // be used to examine updated state and various objects affected
                // by the request execution.

                // Last executed request
                context.getRequest();
                // Execution route
                context.getHttpRoute();
                // Target auth state
                context.getTargetAuthState();
                // Proxy auth state
                context.getProxyAuthState();
                // Cookie origin
                context.getCookieOrigin();
                // Cookie spec used
                context.getCookieSpec();
                // User security token
                context.getUserToken();

            } finally {
                response.close(); //管理响应的数据流
            }
        } finally {
            httpclient.close(); //关闭httpClient
        }
    }

二、自己实现的HttpRequest工具类HttpRequests

依赖:

<!--HttpClient 工具-->
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.10</version>
</dependency>
<!-- 用于上传文件或者文件流 -->
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpmime</artifactId>
  <version>4.5.8</version>
</dependency>

代码解释:

在这里插入图片描述在这里插入图片描述
如上两图,查看注释,一目了然。。。

源码链接在文章开头,欢迎下载!!!!!!!!!!!!!!!!!!!!!

三、工具类的使用

public static void main(String[] args) throws Exception {
        //普通get请求
        /*String result = HttpRequests.custom(HttpRequests.GET, "https://www.ip.cn/")
                .setUserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36")
                .build().request();
        System.out.println(result);*/

        //添加代理get请求
        /*String result = HttpRequests.custom(HttpRequests.GET, "https://www.ip.cn/")
                .setProxy("username::password@host:port")
                .setUserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36")
                .build().request();
        System.out.println(result);*/

        //post请求
        /*String body = "[]";
        String result = HttpRequests.custom(HttpRequests.POST, "http://localhost/admin")
                .setContentType("application/json")
                .setBody(body)
                .build().request();
        System.out.println(result);*/

        //文件上传
        String body = "{" +
                "\"address\": \"C:\\Users\\30045\\Desktop\\my doc\\timg.jpg\"," +
                "\"name\": \"uploadFile\"" +
                "}";
        String result = HttpRequests.custom(HttpRequests.FILE, "http://localhost/upload")
                .setBody(body)
                .build().request();
        System.out.println(result);
    }

欢迎留言讨论。。。。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值