从自定义Spring的CommonsHttpInvokerRequestExecutor切换到HttpComponentsHttpInvokerRequestExecutor

时间:2014-12-05 13:53:34

标签: java spring authentication apache-httpclient-4.x apache-commons-httpclient

我们有一个Spring CommonsHttpInvokerRequestExecutor的自定义实现。现在,我们希望从httpclient 3.1升级到httpclient 4.3.3,所以我需要实现HttpComponentsHttpInvokerRequestExecutor

然而,API是如此不同,以至于我已经暂时停留在两点(我是httpclient的新手,3和4,但我使用API​​文档)。

有人知道如何改变这个:

public CustomCommonsHttpInvokerRequestExecutor() {
    super();
    // No retry.
    getHttpClient().getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0, false));
}

@Override
protected void executePostMethod(final HttpInvokerClientConfiguration config, final HttpClient httpClient, final PostMethod postMethod) throws IOException {
    HttpState state = ((CustomHttpInvokerClientConfiguration) config).getState();
    if (state.getCredentials(AuthScope.ANY) != null) {
        postMethod.setDoAuthentication(true);
        httpClient.getParams().setAuthenticationPreemptive(true);
        httpClient.getState().setCredentials(AuthScope.ANY, state.getCredentials(AuthScope.ANY));
    } else {
        httpClient.getParams().setAuthenticationPreemptive(false);
    }
    httpClient.executeMethod(null, postMethod, state);
}

到此:

public CustomHttpComponentsHttpInvokerRequestExecutor() {
    super();
    // FIXME default: no retry
    // HttpClient client = getHttpClient();
}

@Override
protected HttpResponse executeHttpPost(final HttpInvokerClientConfiguration config, final HttpClient httpClient,
        final HttpPost httpPost) throws IOException {
    // FIXME Implement
    // get credentials with AuthScope.ANY
    // if (not null) {
    // preemptive authentication
    // } else {
    // HTTP authentication preemptive is not supported by default
    // The else should not be needed
    // }

    return super.executeHttpPost(config, httpClient, httpPost);
}
  • 关于'no retry'有问题,我见过的大多数例子都假设HttpClient的实现并做了一个野蛮的演员,我会尽量避免。
  • 关于“抢占式身份验证”主题,因为它不再受原生支持,我已经搜索并找到了如何将其设置为始终处于活动状态的示例,但没有例如我自己的情况。

任何帮助或领导都非常感激。

1 个答案:

答案 0 :(得分:0)

所以,从更全球化的观点(How to update the settings of an HttpClient in httpclient 4.3+?)讨论问题之后,这就是我提出的问题(并未完全完成,但缺失的拦截器不应该那么难实现,多亏了Preemptive Basic authentication with Apache HttpClient 4)。

/* Copied from HttpComponentsHttpInvokerRequestExecutor */
private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100;
private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5;
private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);

public CustomHttpComponentsHttpInvokerRequestExecutor() {
    super(makeDefaultHttpClient());
    setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
}

private static HttpClient makeDefaultHttpClient() {
    // New non-deprecated ConnectionManager with same settings as super()
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
    connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
    connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);

    // HttpClient with ConnectionManager and no retry
    /*
     * TODO Add a request interceptor that will authenticate 
     * if credentials with AuthScope.ANY are provided.
     */
    HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
            .setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)).build();
    return httpClient;
}

@Override
protected HttpPost createHttpPost(final HttpInvokerClientConfiguration config) throws IOException {
    HttpPost httpPost = super.createHttpPost(config);

    // Set the timeout for this request if it exists.
    Integer timeout = ((CustomHttpInvokerClientConfiguration) config).getReadTimeout();
    if (timeout != null) {
        RequestConfig rConfig = RequestConfig.copy(httpPost.getConfig()).setSocketTimeout(timeout).build();
        httpPost.setConfig(rConfig);
    }

    return httpPost;
}

与往常一样,我会对你可能提出的任何反馈感兴趣。