[JAVA] About disconnect () of HttpURLConnection

Introduction

Recently I was writing code like the following Sample.java at home.

Sample.java


HttpURLConnection urlconn = null;
PurchaseItemInfo itemInfo = null;
try {
    URL url = new URL([URL]);
    urlconn = (HttpURLConnection) url.openConnection();
    urlconn.setRequestMethod("GET");
    urlconn.setInstanceFollowRedirects(false);
    urlconn.connect();

    try (InputStreamReader inReader = new InputStreamReader(urlconn.getInputStream());
            BufferedReader reader = new BufferedReader(inReader);) {
        doSomething();
    }
} finally {
    urlconn.disconnect();
}

As I wrote this, I was looking into HttpURLConnection, but at the end I found both a sample that called disconnect () and a sample that didn't. Normally, if you open () some resource (FileInputStream or Connection) and then try-with-resources to AutoClose it, or explicitly close () it in the finally clause, it will occupy the resource until it becomes the target of GC. I thought it was a rule of thumb to always close (). I thought it was the same for HttpURLConnection, but I can't use try-with-resources because I haven't implemented the AutoCloseable interface (* Because you pointed out, [at the end of this article](https: // qiita) .com / taumax / items / 1e3b03771fe73adfaf95 # 20191111-% E3% 81% 94% E6% 8C% 87% E6% 91% 98% E3% 82% 92% E3% 81% 84% E3% 81% 9F% E3% 81% A0% E3% 81% 84% E3% 81% 9F% E3% 81% AE% E3% 81% A7% E4% BF% AE% E6% AD% A3) Maybe it's a little different? I started thinking, so I looked it up.

Difference between disconnect () of HttpURLConnection and close () of resource

HttpURLConnection (API specification) stated as follows.

Individual HttpURLConnection instances are used when making a single request, but the network connection to the HTTP server behind them can be transparently shared with other instances. Calling the close () method on the HttpURLConnection's InputStream or OutputStream after the request may free the network resources associated with that instance, but has no effect on the shared persistent connection. .. If you call the disconnect () method, the socket you were using could be closed if the persistent connection was idle at that time.

In addition to this, when I looked at the sites I wrote for reference, if I disconnect () HttpURLConnection, the socket may be closed even if it is idle with the KeepAlive setting. (HttpURLConnection is the default keepalive)

If you close () InputStream / OutputStream instead of disconnecting () HttpURLConnection, network resources will be released, but the socket will not be closed and will be reused. It seems that. If you are making a little thing by yourself like this time, you do not need to be aware of it, but if you have a system that repeatedly connects / disconnects because many people connect, you should be aware of it. If you do not code it, it may lead to the worst performance problem. I learned one thing.

reference

HttpURLConnection # disconnect and Keep-Alive -HttpURLConnection (API specification) -HttpURLConnection is the default keepaliveDo we need to call HttpURLConnection.disconnect ()?

2019/11/11 Corrected because you pointed out

In the "Introduction" of this article, "I thought it was the same for HttpURLConnection, but I can't use try-with-resources because I haven't implemented the AutoCloseable interface." You pointed out that part.

AutoCloseable is a Functional interface, so it can also be implemented in a lambda expression.

HttpURLConnection urlconn = (HttpURLConnection) url.openConnection(); try (AutoCloseable c = () -> urlconn.disconnect()) { doSomething(); }

Sure, AutoCloseable only has a close () method, so you can use a lambda expression. .. .. So you can also write:

Sample.java


URL url = new URL([URL]);
HttpURLConnection urlconn = (HttpURLConnection) url.openConnection();
urlconn.setRequestMethod("GET");
urlconn.setInstanceFollowRedirects(false);

PurchaseItemInfo itemInfo = null;
try (AutoCloseable c = () -> urlconn.disconnect();
        InputStreamReader inReader = new InputStreamReader(urlconn.getInputStream());
        BufferedReader reader = new BufferedReader(inReader);) {

    urlconn.connect();
    doSomething();
}

Thank you for pointing out. I learned a lot.

that's all.

Recommended Posts

About disconnect () of HttpURLConnection
About selection of OpenJDK
About DI of Spring ①
About DI of Spring ②
About form. ○○ of form_with
About @Accessors of Lombok
About the handling of Null
About an instance of java
About simple operation of Docker
About the description of Docker-compose.yml
About size comparison of compareTo
About types of code coverage
Memorandum of understanding about LOD.
About partial match of selector
About the basics of Android development
About fastqc of Biocontainers and Java
About Lambda, Stream, LocalDate of Java8
About error handling of comment function
[Rails] About implementation of like function
About binding of Spring AOP Annotation
About the role of the initialize method
About removeAll and retainAll of ArrayList
Think about the 7 rules of Optional
About =
About image upload of jsp (servlet)
About Disk Cache of Glide 4 series
[Ruby] Review about nesting of each
Explanation about Array object of Ruby
Summary about the introduction of Device
About the log level of java.util.logging.Logger
About the version of Docker's Node.js image
What is testing? ・ About the importance of testing
[Rails 6.0] About batch saving of multiple records
About the operation of next () and nextLine ()
About the initial display of Spring Framework
About the error message Invalid redeclaration of'***'
[Java beginner] About initialization of multidimensional array
[Basic knowledge of Java] About type conversion
About the treatment of BigDecimal (with reflection)
About the number of threads of Completable Future
About the mechanism of the Web and HTTP