Search code examples
javajsonpostrequestjersey

Error on POST request with Jersey to API, works fine with POSTMAN


I developed an API RESTful service (backend) with Laravel 5, and I tested it with POSTMAN. There are several resources to get information with GET and POST requests, they work fine with POSTMAN. I started to test the API with a Java Client with Jersey. The GET methods work fine with code like this, and the response is a json, which I parse with Jackson.

Client client = ClientBuilder.newClient();
WebTarget webTarget = client.target(ClientUrl);
Invocation.Builder invocationBuilder = 
webTarget.request(MediaType.APPLICATION_FORM_URLENCODED_TYPE);
Response mResponse = invocationBuilder.get();

The next method I want to test is the login, with POST method. With POSTMAN I use in the header the key "Content-Type" + value "application/x-www-form-urlencoded" and in the body I send a Json with this information

{"email":"[email protected]", "password":"xxxxxxxxxx"}

To use the POST method with Jersey I use the next code

Client client = ClientBuilder.newClient();
Form mForm = new Form();
mForm.param("email", email);
mForm.param("password", password);

WebTarget target = client.target(Utils.URL_LOGIN);
//As stated in the documentation, the APPLICATION_FORM_URLENCODED = 
//"application/x-www-form-urlencoded"
Builder request = target.request(MediaType.APPLICATION_FORM_URLENCODED);
//I print the request to verify the request 
print(request.toString());
Response response =  request.post(Entity.form(mForm));
//I print the response to verify the response received and also the code 
print("Response: " + response.toString());
print("Code: " + response.getStatus());
String result = response.readEntity(String.class);
response.close();
print(result);

When I print the request.toString() I get this

org.glassfish.jersey.client.JerseyInvocation$Builder@65e579dc

When the response is printed

Response: InboundJaxrsResponse{context=ClientResponse{method=POST, uri=http://www.dance-world.com/api/login, status=200, reason=OK}}

The status received is 200, but when I print the response.readEntity I get the response that I use in the backend for thoses cases when the server doesn't receive information with the request.

{"code":400,"status":"error","message":"No data attached to the request"}

When I use POSTMAN and the result is 200, with success I receive the Token as a String.

I can't figure what's my error, because I'm following the code in documentation and with the book RESTful Java with JAX-RS 2.0


Solution

  • I found the reason. I developed the backend based on a course of Laravel, in that course the functions have the next definition

     public function getByCountry(Request $request) {
            //Recoger los datos por post
            $json = $request->input('json', null);
            $params = json_decode($json);
            $params_array = json_decode($json, true);
            ...
    }
    

    And the backend requires a x-www-urlencoded, in POSTMAN I was sending the request in that format (POST Request {x-www-urlencoded} with Postman). So, when I tried to make a POST request with JSON, using Jersey or Unirest the request haven't the required format, that's the reason I had the message configured for thoses cases when the backend doesn't receive information with te request. This is the POSTMAN request with raw Json and this is the response from the backend, which says that no data was received.

    The way I solved it to accept json for the requests was change the code in the backend with the next structure:

    public function TestForPost(Request $request) {
        //Verify if the $request is a json
        $input = $request->json()->all(); //read json in request
        if (!empty($input)) {
        ...
    }
    

    With this change I cand send a request with Json and the backend accepts it.