Search code examples
javaspring-bootresttemplate

Java - 422 Unprocessable Entity using RestTemplate


I have two services, Am trying to send a GET request from Service A, To make Service B send a Post request to Redmine Server.

Am getting 422 Unprocessable Entity: "{"errors":["Name cannot be blank","Identifier cannot be blank"]}"

And here is what I have already tried :

String url = "http://localhost:3001/projects.json"; //Redmine local server
RestTemplate restTemplate = new RestTemplate();
JSONObject object = new JSONObject();   //Json object that will need to be sent to redmine
object.put("name", "dummyName");        // Should look like this
object.put("identifier", "dummyId");    // {"project":{"identifier":"dummyId","name":"dummyName"}}
JSONObject body = new JSONObject();     
body.put("project", object);            
String plainCreds = "user:bitnami1"; // default basic auth encoding
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds); 
headers.add("Content-Type", "application/json");
RequestEntity<JSONObject> requestEntity = RequestEntity
                .post(new URI(url))
                .accept(MediaType.APPLICATION_JSON)
                .headers(headers)
                .body(body);
ResponseEntity<String> r = restTemplate.exchange(requestEntity, String.class);

This way am getting the same error, 422 Unprocessable Entity: "{"errors":["Name cannot be blank", "Identifier cannot be blank"]}" And when I try to log.info the Request Entity to check it look ok

<POST http://localhost:3001/projects.json,{"project":{"identifier":"dummyId","name":"dummyName"}},[Accept:"application/json", Authorization:"Basic dXNlcjpiaXRuYW1pMQ==", Content-Type:"application/json"]>

Then I've Tried with entity , As the following

String url = "http://localhost:3001/projects.json"; //Redmine local server
RestTemplate restTemplate = new RestTemplate();
JSONObject object = new JSONObject();   //Json object that will need to be sent to redmine
object.put("name", "dummyName");        // Should look like this
object.put("identifier", "dummyId");    // {"project":{"identifier":"dummyId","name":"dummyName"}}
JSONObject body = new JSONObject();     
body.put("project", object);            
String plainCreds = "user:bitnami1"; // default basic auth encoding
byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds); 
headers.add("Content-Type", "application/json");
HttpEntity<Object> entity = new HttpEntity<Object>(body, headers);
ResponseEntity<String> result = restTemplate.exchange("http://localhost:3001/projects.json",
                HttpMethod.POST,
                entity,
                String.class);

The same result as earlier, When I log.info for entity-body I get the following

<{"project":{"identifier":"dummyId","name":"dummyName"}},[Authorization:"Basic dXNlcjpiaXRuYW1pMQ==", Content-Type:"application/json"]>

Tried To use NetCat to capture what is being sent, In both ways am not getting any body with restTemplate.exchange.

While debugging, It seems that the error came from RestTemplate.doExecute And I cant get why.

----Edit----

Am trying to connect to Redmine API to create new Project, More info can be found here And this is the curl command that successfully create new project

curl --location --request POST 'localhost:3001/projects.json' \
--header 'Authorization: Basic dXNlcjpiaXRuYW1pMQ==' \
--header 'Content-Type: application/json' \
--data-raw '{"project":{"identifier":"dummyId","name":"dummyName"}}'

What I am trying to do, Is to send a request From service A to my Service B so this request will be forwarded to redmine server. For simplicity, I hard-coded the information in the code above (service B) just to make sure I can map this curl request, But it's not working.

Is there any suggested solution for this situation? Maybe an alternative approach ? Any suggestion would help.


Solution

  • Since your method would accept an object node as an input so you can do something like this:

    String url = "http://localhost:3001/projects.json"; 
     RestTemplate restTemplate = new RestTemplate();
    

    Then you can set an HttpEntity like this:

    HttpEntity<ObjectNode> entity = new HttpEntity<>(node, headers);
    

    Then call exchange:

    ResponseEntity<String> result = restTemplate.exchange("http://localhost:3001/projects.json",
                HttpMethod.POST,
                entity,
                String.class);
    

    I guess this will make your life easier.