For example to read data from a website we do:

HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();

The method that executes the HTTP request, returns a response, then we turn the response into an entity, then we turn the entity into a input stream, then you got to use two more objects, a buffer reader and a string builder,to turn that is into a string. It just seems like a lot of repetitive code. Why can't HttpResponse have a method that returns an InputStream, or better yet a String?

P.S. I'm not necessarily saying that Java is wrong, I want to find out what the reason behind it is, if any.

closed as not constructive by gnat, user40980, Kilian Foth, Bart van Ingen Schenau, Giorgio Apr 24 '13 at 10:54

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Wow. I'd expect to see that degree of complexity in an HTTP server, but on an HTTP client, you're right. There really should be two methods, which return a string and a stream, for textual and non-textual data respectively. – Mason Wheeler Apr 19 '13 at 1:13
  • 2
    why not a string I can understand: avoiding hogging the ram and crashing when a large page gets loaded up (especially on android) – ratchet freak Apr 19 '13 at 1:30
  • Could you please explain this more? why does returning a string hog ram? – Siavash Apr 19 '13 at 1:57
  • 4
    A mandatory link: steve-yegge.blogspot.co.uk/2006/03/… – SK-logic Apr 19 '13 at 8:42
  • 3
    because if you have a page that holds the entire oeuvre of shakespeare in text form. then before you can return a string of it you have to download the entire thing and wrap it in a single char array – ratchet freak Apr 19 '13 at 9:21

Its simply good OO design, having separate objects at a fairly fine grained level.

HttpResponse encapsulates the entire response. It is composed of a status, headers and entity objects. These objects further encapsulate more fine grained details, for example the entity consists of information about the encoding type, length, encoding and a stream of the content itself.

This design avoids having a HttpResponse god object which does everything, end up being huge and loses its reusability.

  • 9
    This answer dwells in a philosophical realm of "good OO design" principles that is completely disconnected from any real-world concerns of usability. In other words, you hit the nail on the head. This is exactly why Java did it. – user82096 Apr 19 '13 at 10:33
  • 1
    That may be so, but (see my earlier comment) there is no reason not to provide a simpler wrapper on top of the verbose API. – tdammers Apr 19 '13 at 10:54
  • 4
    @tdammers, I agree. I am not objecting to OO design principles per se. The problem is putting the cart before the horse. The goal should be to make good software, and OO design is a tool to achieve that goal. To me, the problem with Java is that it makes "good OO design" the goal, in the belief that good software will just happen as a side effect. As an inevitable result, real-world concerns like usability and ease of coding get neglected. – user82096 Apr 19 '13 at 11:23
  • 1
    @dan1111 I'd say it's not even that good of an OO design. Just a verbose, full-of-minutiae design. On the other hand, if this was indeed good OO design, then it'd be a good argument for rejecting OO... – Andres F. Apr 19 '13 at 12:50
  • OK I understand the unwrapping of the http layers. But what about the string building part. if we have a pointer to a place in memory where a sequence of characters exist. cant we just create a string pointer and set it to this location? This is what we would do ic C. – Siavash Apr 19 '13 at 18:45

Yes, you're right - in general Java requires a lot of ceremony for surprisingly simple situations*. The obvious advantage is that you see each step of the way to your goal, so you have more control. Network communications are done by wrapping messages inside envelopes, so you are exposed to this layering -- your library already hides many layers for you, but keeps the HTTP layers (the header and the entity) visible.

If you can make simplifying assumptions about the sequence of operations you must perform (for example, you don't want to inspect HttpResponse's status code), then you should just abstract it away into a helper method that does what you want, and call that instead.

In fact, there is an Apache HTTP client library that does just this. Take a look at this Stackoverflow question for a two-line example of going from URL to the text stream. (I suspect you may already be using this library, but I'm not sure.)

* Coming from Python and Perl, building a HashMap in Java is really verbose. Luckily Google Guava simplifies the notation.

  • 5
    +1 And the dis-advantage of seeing each step of the way to your goal, is that you have much more code to read and more points where you can make mistakes. – MarkJ Apr 19 '13 at 7:31
  • 2
    Java was created in a world where you wanted to see all of the steps, often you needed that fine gained control over your networking (or any other aspect of dealing with I/O). – Martijn Verburg Apr 19 '13 at 7:59
  • Where is the ceremony here: is = new URL(httpPost).openStream()? – Rogério Apr 19 '13 at 16:41
  • OK I understand the unwrapping of the http layers. But what about the string building part. if we have a pointer to a place in memory where a sequence of characters exist. cant we just create a string pointer and set it to this location? This is what we would do ic C. Again I'm a newb to java and I'm trying to figure out what I'm missing here. – Siavash Apr 19 '13 at 18:48
  • @Siavash you are missing my answer :P – Esailija Apr 19 '13 at 19:21

Java was created in a world where you wanted to see all of the steps, often you needed that fine gained control over your networking (or any other aspect of dealing with I/O).

I personally think it's not at all bad that developers are at least aware that such complexity exists, I find too many devs blindly accept that "Magic happens" and then can't debug/investigate a problem. Yeah, yeah, get off my lawn I know.

Clearly the world has moved on, and simpler abstractions can and should be used as by default. Apache's HttpClient is the defacto lib to use for this in Java and you can also use languages such as JRuby, Jython, Groovy, Scala, Clojure all on the JVM to do this sort of work more concisely.

  • 2
    Fine control is needed sometimes, but most languages give you fine control if you want it, as well as simpler ways. I don't think there has ever been a time when everyone thought "we need three layers of abstraction to access a web page". And while I agree that it is important for developers to know about complexity, that is totally irrelevant to language design decisions (I hope). Things should always be designed as simply as they can be. No one should be saying "Let's keep this interface really complicated so that coding will be more of a learning experience. It builds character." – user82096 Apr 19 '13 at 10:21
  • 2
    I was coding in 1995 (and earlier) and I know I didn't want to see all the steps every single time I performed I/O. Especially on a platform which specifically used a VM to abstract away all differences between different execution environments. Bah humbug, get off my lawn... :) – MarkJ Apr 19 '13 at 11:19
  • 1
    @dan1111 +1 to your comment. I agree and your "it builds character" made me laugh! – Andres F. Apr 19 '13 at 12:47

The level of control offered does no harm, you can always build abstraction on top of it that fits your requirements. It would be bad if no control or not enough control was offered at all.

If you just wanted the response as a string directly, you could do this:

String result = httpClient.execute(httpPost, new BasicResponseHandler());

This isn't example specific, you can usually either find a library or search documentation to do something in a relatively simple way if you find the defaults and lack of control acceptable.

  • 1
    +1 for pointing out that there is an easy one-liner (I'm assuming you're correct, haven't checked the docs). It's analogous to JQuery's $.ajax() versus $.getJSON(). – kdgregory Apr 19 '13 at 11:57
  • @kdgregory yeah I tested it statically. Docs for BasicResponseHandler and HttpClient.execute in case you're interested. – Esailija Apr 19 '13 at 12:01

I think it's a combination of a few things.

  • to be able to unit test properly you have to be able to inject your dependencies into the unit under test
  • Java does not have first class functions so objects are the only way to inject dependencies
  • Java's philosophy is for code to be mostly plain boring java that everyone can understand
  • 3
    Just because you have many units doesn't mean you can't have abstractions on top of them to bundle super-common situations into more compact constructs. – tdammers Apr 19 '13 at 10:53

Not the answer you're looking for? Browse other questions tagged or ask your own question.