Is it necessary to read request data before calling the close method of response inside a http server in java?
I have a http server written by sun's http server. When I receive a http request, I just simply do the following steps:
write my text to response body
close the response
Does it matter to read the request body before closing the response?
Note that I have too many http requests on my server. (10000 call/sec.)
My benchmark says if request body does not have too much data, there is no big difference between two methods. I didn't get any timeout and other type of exceptions using both methods.
This is the time benchmark result for 1M request using 100 concurrent threads (10000 request per thread) on both methods:
Don't read request body: 210,581ms
Read request body: 206,599ms
Related
I'm new to Java and found a confusing behaviour related with RestTemplate.
It happened with an API returning large body (~5MB) over a quite slow network condition. The code is like below
ResponseEntity<MyEntity[]> result = restTemplate.exchange(url, HttpMethod.GET, entity, MyEntity[].class);
And also a ClientHttpRequestInterceptor is set to log before and after the request.
The confusing thing is that the after request log is logged only a while after remote server giving the response, and the HTTP Status code can be print in the log.
But the above statement took much more time to finally receive the data. Look inside the thread stack, it was reading data from socket.
I also look inside the resttemplate class and found:
response = request.execute();
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
It seems to extractData after the execute().
My doubt is:
How does the client side know the status code even before get all the data? It just extracts necessary fields from the top packets?
Since the server has already sent out the response, where the response data is stored during the process?
It stores the data that it receives from the underlying HTTP in memory.
Client side can know what's the status code because with HTTP you get the headers and status code first before the response body. But this doesn't matter with RestTemplate as it promises to give you an object of ResponseEntity in the end, which contains everything from the http response be it status codex headers or body.
RestTemplate is an abstraction over an HttpClient, most client's give you the option to implement callbacks for separate events like onHeadersReceived(), onStatusReceived() etc. But if you are using RestTemplate this means you don't require such fine grained control.
I am using Java servlets using Apache tomcat.
I've configured a threadpool and am dealing with each request.
My page is taking in many GET requests at the same time, I'm wondering if I can respond to the server after each get request before any of the logic happens?
So server gives me a request -> I respond with either 'good send another' or 'bad send another' before I start my queueing.
Any help would be much appreciated!
EDIT
Sorry that was terribly written :(
What I'm asking for is a way to send a Header to the client (in this case it's a server which sends me lots of requests). The response would just be 200 or error based on the information I get sent.
What my program is doing:
My servlet gets sent lots of GET requests from one client. (over 100,000) Which I am using tomcat to queue and put into a threadpool. It is then assigned to a worker thread which processes it and puts it into a database.
I've been told to do is send a request back to that server saying 'ok received it'. I think I can use a header response but I don't have the URL of that client (and the client can change for different campaigns). So was wondering what the best way would be to send that response.
After doing some more research I think what I'm looking for is ServletOutputStream.
response.setContentType("text/html");
ServletOutputStream output = response.getOutputStream();
output.flush();
output.close();
Using servlet output stream where do I set the <head><body> tag? and insert the header response afterwards.
The simple answer is "sure".
If these are get requests from a web page for a web page, include a refresh timer and send back some token that can be used to identify the difference between a first-time-request and an I-requested-earlier-are-you-done request. In this case the refresh timer can be set via a meta refresh tag.
If the get requests are part of a REST API then you can define "got it and I'm working" into the protocol. For instance, return a 202 to indicate "got it but not done" and return 200 to indicate "done". As with the html page, consider sending some token back with the 202 that identifies the pending request.
Is it possible to send HTTP POST request to a webserver and retrieve just headers of response or read just few bytes of the body, so the rest won't be downloaded at all (so it won't consume traffic)? If yes, how?
I know that there is a HEAD method for this, but I need to achieve it by POST method .. well, I am not sure if I need the POST method, I just need to post the data. Maybe if the webserver isn't secured well enough (it doesn't check what method it's used - it's just directly access the post data), is it possible to send "post data" by HEAD request?
There is no built-in HTTP mechanism for this, and HTTP HEAD requests do not allow content in the body. If however you are the one writing the server code then anything is possible.
If this is the case, I would suggest a URL parameter that triggers this behavior. For example:
POST /myURL - This would return the whole response
POST /myURL?body=minimal - Returns the reduced size response that you are looking for.
And you would have to code your server method to construct and return the appropriate response based on the URL parameter.
Is it possible to make GET & POST requests in Java or another language such that you don't care about what is returned?
As in just sending the requests but not wanting to receive any responses?
Whether you care about the response or not, it will be sent. The HTTP protocol specifications say that it must be.
If you don't care about the response, your client could just close the connection immediately after sending the request. But the chances are that you do want to know that the request was processed (i.e. the response status) even if you don't want to look at the contents of the response message.
So maybe you could send the request and request body, and read the response status and then close the connection without reading the response body. However, this has a downside. It means that you can't reuse the HTTP connection to make further requests. The next request to the same server has to open a new connection.
You could use anynchronous HTTP requests if you don't care about the responses (that way your worker thread will not have to wait for the response to come back). See http://www.javaworld.com/javaworld/jw-03-2008/jw-03-asynchhttp.html for some details on Asynchronous/Synchronous HTTP queries in Java. Then you can control if the anychronous thread does or does not handle the response (or any failure flagged on the communication) - as long as there were no TCP level failures on the request the connection will still be opened.
You can't control whether or not the server returns a response. Your code is free to ignore any response it receives.
It's pretty hard to not get responses because they're part of the HTTP protocol. but you can certainly ignore the responses.
I'm a newbie to http and Apache's HttpComponents API.
I need to process a streaming response of an http request using Apache's HttpComponents, while there may be additional http requests made on that connection. For example, a POST request is initially made to http://mystreams.net, which later follows with additional requests, while throughout I have to listen and process the streaming response. I need to hold the same initial connection I made.
How can I do that? I was able to create a simple HttpClient and do a simple HttpPost request and then process the response entity that is non-streaming, but how do I hold on to it when it continues to stream data and at the same time make new requests to the same address using the same context (ie cookies)?
Is your streaming data coming back as a single HTTP response? If so, you won't be able to receive other responses on that connection until it is done. But you could take the cookies from that response (while it is still streaming the entity to you) and use them to make other requests on another connection.
HttpEntity entity = httpclient.execute(httpget).getEntity();
InputStream is = entity.getContent()
when calling the stream, use a new Thread, and make subsequent requests in the main thread (or, better, in separate thread for reach)
Also check here