Java Server Side: send Http POST response - status only - java

Some third party is sending an Http Post request whenever something changes in their DB (e.g. when a contact has been updated, they send the contactID and 'contact_updated'). I have build a socket listener that catches those requests and is able to parse the information. However, I just can't get it to work to send back a response with the status '200 - OK'. Thus, the server on the client side keeps on trying (four times or so) to re-send the request.
Is there any, simple way to just send the response status without the need of adding external libs etc.?

It should be enough to send the string HTTP/1.1 200 OK back in your socket-listener.
If you have troubles, you can check out this answer, it shows how to use a HttpServer in Java just via plain JavaSE features.

Use
response.setStatus(HttpServletResponse.SC_OK);
to set the status code in your response header.
You may also set the content type.
response.setContentType("text/html;charset=UTF-8");

Related

Server sends "ping request" to client in a single URL using JAX-RS and RESTeasy

I would like to create a web application that is able to "ping" the client once the client has accessed certain URL (e.g. www.example.com/ping/hello) in order to get the round trip time between server and client. And by "ping" request i mean a simple request with a timestamp from server and client sends back response with its timestamp. I was hoping for this activity to be done with a single URL if possible.
The flow is something like this:
Client goes to the URL
Server sends the response to the client with its timestamp
Client then sends another response to server with new timestamp
Server finally concludes the connection with 200 OK
So far I've only been able to do the first and second steps but not sure how to ensure client to go to the same URL again without back to the first step.
My server code is something like this:
#GET
#Path("/helloping")
public Response getPingServerClient(#Context HttpServletRequest req) {
String result = Long.toString(System.currentTimeMillis());
return Response.status(200).entity(result).build();
//the code to receive the response from client containing timestamp
}
Is there a way to do that?
There are two client to server calls. You'll have to figure out a way to differentiate between these two calls.
I can think of 3 options for this purpose:
HTTP header
Query parameter in GET request
POST request with a marker to differentiate the two calls
The request/response flow will be something like this:
Client -> Server : Request
Server -> Client : Response with timestamp t1
Client -> Server : Request with timestamp t2 and the above mentioned marker
Server -> Client : Response 200
In this approach, you'll have to write custom code at both server and client side to handle the mentioned logic.
I'm not a fan of what you are proposing because you're basically forcing the client to setup up code to effectively become a server, itself. This is inconvenient for the client.
Instead, consider a ping-pong approach where the client first calls the server's ping endpoint, which returns the server's timestamp. As soon as the client obtains the server's ping response, the client is instructed to call a second pong method, which accepts the new timestamp.
It's easier and simpler to require the client to call web service methods than it is to force to client to become a pseudo server. Hence the recommendation.

How to stop Redirect and get response in AsyncHttpClient

I have a HTTP GET which returns status 200 with some response. This response it is given as a result of redirecting.
If I introduce asyncHttpClient.setEnableRedirects(false); in my code, then redirection stops and it comes in failure with status 302. But in my application, this status 302 and response associated with it is what I need.
I am searching online and trying to figure out, but I am new to Java so not able to understand how to achieve this.
What I want is, when server returns status 302, I want to trigger onSuccess and capture response. Thanks.
If I'm getting right what do you need then you could implement your own AsyncHandlers to react with a different AsyncHandler.State for 302 status code. ( https://github.com/AsyncHttpClient/async-http-client#using-custom-asynchandlers) or while creating the client stop to follow redirects like this:
asyncHttpClient(config().setFollowRedirect(false))
(it might be different from the approach you mentioned above.)
P.S. I'm using 2.5.2 version of the asynchttpclient lib.

IoT module GET request in Java

I'm trying to read a JSON response from a RESTful webserver running on an IoT module (Advantech WISE-4012). According to the documentation, any GET request should be made in this form
GET /ai_value/slot_0/ch_0
Any Java implementation of GET requests (Java libraries, Apache etc.), anyway, append to the end of the request the protocol signature HTTP/1.1. E.g:
GET http://192.168.0.14/ai_value/slot_0/ch_0 HTTP/1.1
Because of this (probably) i'm getting Error 400 (Bad request) on every client i tried so far. The only working method i've discovered was sending a simple request through the address bar on Google Chrome browser (sometimes i get a response, sometimes a get a bad request error either). How can i write a java implementation of a GET request plain and simple as described by the documentation? How can i test a custom GET request without HTTP/1.1 at the end? Every chrome extension i tried (Advanced REST Client, Postman) add the protocol version at the end, so i haven't had the chance to verify if that's why i'm getting a bad request error.
EDIT:
This is the response header from Advanced REST client
Connection: close
Content-Type: application/json
Server: WISE-4000/8.1.0020
While the source message is the following one:
GET /ai_value/slot_0/ch_0 HTTP/1.1
HOST: 192.168.0.14
The only mismatch between the documentation is the HTTP/1.1 signature as mentioned before. Adding the "accept: application/json" makes no difference either
After a bit of digging into the documentation, it looks like the default timeout (i.e. 720 seconds) is the one causing an issue. There doesn't seem to be any way to work it around (ideally, the system should reset the time after a successful request and we should only get 400 - or 403 ideally after 720 seconds of inactivity).
A couple of points I would like to recommend to the API developers for WISE-4012 (if they are in touch with you):
Add brief documentation for authentication and timeout (probably, more response codes and error messages with each error response)
Enable OAuth for API Access
As far as current implentation is conerned, I guess you need to do a basic auth and pass username/password with every request, Or add Authentication header with every API request to get successful response without any 400s.
Check if this helps.
HttpClient httpClient = HttpClients.createDefault();
URI reqUri = new URI(<uri>);
RequestBuilder requestBuilder = RequestBuilder.create("GET");
requestBuilder.setUri(reqUri);
requestBuilder.setHeader(<headerKey>, <headerValue>);
requestBuilder.setEntity(<entity_data>);
HttpUriRequest httpRequest = requestBuilder.build();
httpResponse = httpClient.execute(httpRequest);

An easy way to detect the end of http response (raw socket, java)?

I want to retrieve the server's response as is, with all headers. The first thing that comes to mind is to use raw sockets. As I have learned from the search, there are 3 ways to indicate the end of response:
(1) closing the connection;
(2) examining Content-Length;
(3) getting all chunks in the case of Transfer-Encoding: Chunked.
There is also
(4) the timeout method: assume that the timeout means end of data, but the latter is not really reliable.
I want a general-case solution and do not want to
add a Connection: close line to the request itself.
In addition, it is recommended to use an existing library rather than re-invent the wheel.
Question:
How do I use an existing package, preferably, something already present in Android, to detect the end of HTTP response while having access (without interference) to the raw data stream?
UPD: forgot to mention that the HTTP request is given to me as a sequence of bytes. Yes, it is for testing.
PS
relevant reading:
End of an HTTP Response
Detect the end of an HTTP Request in Java
Detect end of HTTP request body
How HTTP Server inform its clients that the response has ended
Proper handling of chuncked Http Response within Socket
Detect the end of a HTTP packet
Android socket & HTTP response headers
Java HTTP GET response waits until timeout
I suggest to use a the Apache HTTP client package (http://hc.apache.org/httpclient-3.x/ ) so you don't need to implement all the finicky details of the HTTP protocol.
The Apache Http Client will give you access to the headers and their content, which may be enough for you.
If you really need access to the actual character sequence sent by the server (e.g. for debugging purposes), you could then intercept the communication by replacing the connection socket factory with your own to create "intercepting" sockets which store all data transferred in a buffer where your code can access it later on. See http://hc.apache.org/httpcomponents-client-4.3.x/tutorial/html/connmgmt.html#d5e418

Printing the contents of a Restlet web service request

I am implementing a Restful web service using Restlet - I have not found a way to print the content of the HTTP request. I need to check the content of the http request, to get something like this:
POST http://localhost:8080/students
<Student>
<name>Tony<name/>
<age>19<age/>
<Student/>
I am send a custom object the server resource using the following code
ClientResource c = new CLientResource(url);
c.post(student, Student.Class);
I tried to get the HTTP request also with wireshark , I did not find any http requests, I only found TCP connections.
Anybody knows how to print the content of the http request either on client or server side?
You can use the following on the client side :
clientResource.getResponseEntity().getText();
From the javadoc :
Converts the representation to a string value. Be careful when using
this method as the conversion of large content to a string fully
stored in memory can result in OutOfMemoryErrors being thrown.
By the way, HTTP requests are TCP connections.

Categories