попробуйте с ресурсами в методе, используемом другим - PullRequest
2 голосов
/ 28 февраля 2020

У меня есть следующий java код с попыткой использования ресурсов:

public static CloseableHttpResponse getHttpResponse()
    {
        try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
            try (CloseableHttpResponse response = client.execute(request)) {
                return response;
            }
        }
    }

в другом методе будет использоваться response, возвращаемый getHttpResponse:

public void test() {
        CloseableHttpResponse response = getHttpResponse();
        if (response) {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                // do something
            }
        }
    }

Looks как после CloseableHttpResponse response = getHttpResponse();, client и response уже закрыты, и я не могу объединить эти два метода в один, есть ли еще способы использовать попытку с ресурсами в другом методе?

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

Лучшим подходом является идиома Execute Around . Вместо getHttpResponse возвращается CloseableHttpResponse проход в лямбду (обычно) для выполнения. Затем ресурс может быть чисто закрыт в операторе try-with-resource.

/*** NICE ***/
// Function instead of Consumer would allow the method to return a value.
private void httpResponse(
    Consumer<CloseableHttpResponse> op
) /* throws IOException */ {
    try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
        try (CloseableHttpResponse response = client.execute(request)) {
            if (response != null) { // Really?
                op.accept(response);
            }
        }
    }
}

Используется как:

    httpResponse(response -> {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK) {
            // do something
        }
    });

Хакерской альтернативой является включение оператора try в getHttpResponse закрывается только в условиях ошибки.

/*** HACKY ***/
private CloseableHttpResponse httpResponse() /* throws IOException */ {
    boolean success = false;
    CloseableHttpClient client = HttpClientBuilder.create().build();
    try {
        CloseableHttpResponse response = client.execute(request);
        try {
            success = true;
            return response;
        } finally {
            if (!success) {
                response.close();
            }
        }
    } finally {
        if (!success) {
            client.close();
        }
    }
}
0 голосов
/ 28 февраля 2020

client будет закрыто, как только программа выйдет из области попытки с ресурсами. Можете ли вы попробовать создать попытку с использованием ресурсов метода getHttpResponse? Например:

public static CloseableHttpResponse getHttpResponse() {
    try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
        CloseableHttpResponse response = client.execute(request)
        return response;
    }
}

И затем вы можете переписать свой метод тестирования () следующим образом:

public void test() {
    try(CloseableHttpResponse response = getHttpResponse()) {
        if (response) {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                // do something
            }
        }
    }
}
...