【问题标题】:How do I do HTTP Purge from Java?如何从 Java 中执行 HTTP 清除?
【发布时间】:2012-10-08 14:30:39
【问题描述】:

我正在尝试使用 HttpUrlConnection 执行 PURGE,如下所示:

private void callVarnish(URL url) {
    HttpURLConnection conn = null;

    try {
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod(PURGE_METHOD);
        conn.setDoOutput(true);
        conn.setInstanceFollowRedirects(true);
        conn.setRequestProperty("Host", "www.somehost.com");
        conn.connect();
        System.out.print(conn.getResponseCode() + " " + conn.getResponseMessage());
     }
     catch (Exception e) {
         log.error("Could not call varnish: " + e);
     } finally {
         if (conn != null) {
             conn.disconnect();
         }
     }
}

但我得到了:

08:56:31,813 ERROR [VarnishHandler] Could not call varnish: java.net.ProtocolException: Invalid HTTP method: PURGE

使用 curl 没有问题:

curl -I -X PURGE -H "主机:www.somehost.com" someurl

HTTP/1.1 404 Not in cache.
Server: Varnish
Content-Type: text/html; charset=utf-8
Retry-After: 5
Content-Length: 401
Accept-Ranges: bytes
Date: Thu, 18 Oct 2012 06:40:19 GMT
X-Varnish: 1611365598
Age: 0
Via: 1.1 varnish
Connection: close
X-Cache: MISS

那么我该怎么做呢?我需要从 Java 卷曲还是有其他可以使用的库?

【问题讨论】:

    标签: java httpurlconnection varnish http-method


    【解决方案1】:

    您可以使用 Apache 的 HttpClient 库:http://hc.apache.org/httpcomponents-client-ga/

    您可以使用BasicHttpRequest 或实现您自己的扩展HttpRequestBase 的HttpPurge 类。

    您可以在此处找到快速入门指南:http://hc.apache.org/httpcomponents-client-ga/quickstart.html

    例子:

    DefaultHttpClient httpclient = new DefaultHttpClient();
    BasicHttpRequest httpPurge = new BasicHttpRequest("PURGE", "www.somehost.com") 
    HttpResponse response = httpclient.execute(httpPurge);
    

    【讨论】:

    • 谢谢!我最终在 apache.commons.httpclient 中扩展了 HttpMethodBase
    • HttpMethodBase 是 Commons HttpClient 项目的一部分,它实际上被标记为“生命终结”。在此处查看更多信息hc.apache.org/httpclient-3.x。如果你想保持最新,你应该使用 HttpComponents HttpClient: hc.apache.org/httpcomponents-client-ga/index.html
    • 好的,我明白了!我已经实现了 httpcomponents。
    • 有什么方法可以扩展原生 HttpUrlConnection 等来支持 PURGE 请求?我们走在 Java 中为自定义“HTTP 客户端”包装原生 HTTP 支持的路线,而不是使用像 Apache 这样的第 3 方库。最好保持这种状态而不是不得不转移,尽管我们可以作为最后的手段这样做。
    【解决方案2】:

    使用 org.apache.httpcomponents 4.2.1:

    类:

    import org.apache.http.client.methods.HttpRequestBase;
    
    import java.net.URI;
    
    public class HttpPurge extends HttpRequestBase {
    
        public final static String METHOD_NAME = "PURGE";
    
        public HttpPurge() {
            super();
        }
    
        @Override
        public String getMethod() {
            return METHOD_NAME;  //To change body of implemented methods use File | Settings | File Templates.
        }
    
        public HttpPurge(final String uri) {
            super();
            setURI(URI.create(uri));
        }
    
        public String getName() {
            return "PURGE";
        }
    }
    

    电话:

    import org.apache.http.Header;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.message.BasicHeader;
    import org.apache.http.util.EntityUtils;
    import test.HttpPurge
    
    private void callVarnish(URL url) {
    
            DefaultHttpClient httpclient = new DefaultHttpClient();
            HttpPurge httpPurge = new HttpPurge(url.toString());
            Header header = new BasicHeader("Host", "www.somewhere.se");
            httpPurge.setHeader(header);
            try {
                HttpResponse response = httpclient.execute(httpPurge);
                System.out.print("-------------------------------------");
                System.out.println(response.getStatusLine());
                System.out.print("-------------------------------------");
                HttpEntity entity = response.getEntity();
                // If the response does not enclose an entity, there is no need
                // to worry about connection release
                if (entity != null) {
                    // do something useful with the response body
                    // and ensure it is fully consumed
                    EntityUtils.consume(entity);
                }
            } catch (IOException ex) {
    
                // In case of an IOException the connection will be released
                // back to the connection manager automatically
            } catch (RuntimeException ex) {
    
                // In case of an unexpected exception you may want to abort
                // the HTTP request in order to shut down the underlying
                // connection and release it back to the connection manager.
                httpPurge.abort();
            }
    }
    

    使用已弃用的 org.apache.commons.httpclient.HttpMethodBase:

    类:

    import org.apache.commons.httpclient.HttpMethodBase;
    
    public class PurgeMethod extends HttpMethodBase {
    
        public PurgeMethod() {
            super();
            setFollowRedirects(true);
        }
    
        public PurgeMethod(String url) {
            super(url);
            setFollowRedirects(true);
        }
    
        public String getName() {
            return "PURGE";
        }
    }
    

    电话:

    import org.apache.commons.httpclient.Header;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpMethod;
    
    private void callVarnish(URL url) {
        HttpClient client = new HttpClient();
        HttpMethod method = new PurgeMethod(url.toString());
    
    try {
        int status = 0;
        status = client.executeMethod(method);
    
        log.debug(status);
    } catch (Exception e) {
        // something
    } finally {
        method.releaseConnection();
    }
    

    }

    【讨论】:

      【解决方案3】:

      使用 HttpComponents,API 发生了变化。当前版本的 uldall 答案如下:

      HttpHost host = new HttpHost(hostname, port);
      HttpClient httpclient = HttpClientBuilder.create().build();
      BasicHttpRequest purgeRequest = new BasicHttpRequest("PURGE", "/some/url");
      HttpResponse response = httpclient.execute(host, purgeRequest);
      

      【讨论】:

        猜你喜欢
        • 2013-12-11
        • 2015-07-12
        • 2010-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        • 1970-01-01
        • 2012-11-15
        相关资源
        最近更新 更多