Getting HTTP Status 400 – Bad Request in post request in rest assured - java

I'm trying to create a POST request in rest assured java but receiving HTTP Status 400 – Bad Request. Have tried below two approaches and the same API is working fine in postman. I'm using 4.1.2 rest assured in pom.xml
curl --location --request POST
'http://localhost:8080//api/v1/planning/trips?pageNumber=1&pageSize=40'
--header 'authority: http://localhost:8080'
--header 'authorization: Bearer e8c108d6-c380-4715-849b-b6eccd8d2045'
--header 'origin: http://localhost:8080'
--header 'referer: http://localhost:8080'
--header 'Content-Type: application/json;charset=UTF-8'
--data-raw '{ "endPlacementTimestamp": 1594994096206, "startPlacementTimestamp": 1593525296206 }'
Approach 1:
RestAssured.baseURI="http://localhost:8080";
RequestSpecification httpRequest = RestAssured.given();
httpRequest.header("authority","http://localhost:8080");
httpRequest.header("authorization","Bearer e8c108d6-c380-4715-849b-b6eccd8d2045");
httpRequest.header("Content-Type","application/json;charset=UTF-8");
httpRequest.header("origin","http://localhost:8080");
httpRequest.header("referer","http://localhost:8080");
JSONObject requestParams = new JSONObject();
requestParams.put("endPlacementTimestamp", "1594994096206");
requestParams.put("startPlacementTimestamp","1593525296206");
httpRequest.body(requestParams.toJSONString());
Response response = httpRequest.request(Method.POST,"planning/trips?pageNumber=1&pageSize=40");
int statusCode = response.getStatusCode();
// Assert.assertEquals(statusCode, "200");
// Retrieve the body of the Response
ResponseBody body = response.getBody();
Approach 2:
String body= "{\n" +
" \"endPlacementTimestamp\": 1594994096206,\n" +
" \"startPlacementTimestamp\": 1593525296206\n" +
"}";
RestAssured.baseURI="http://localhost:8080//api/v1/";
Response response = given()
.contentType("application/json")
.header("authorization","Bearer e8c108d6-c380-4715-849b-b6eccd8d2045")
.header("origin","http://localhost:8080")
.header("referer","http://localhost:8080")
.body(body)
.post("planning/trips?pageNumber=1&pageSize=40");[![enter image description here][1]][1]

Here's a simplified version of it, I have added a JSONObject here so you don't hardcode the payload in the body()
RestAssured.baseURI = "http://localhost:8080";
RequestSpecification requestSpec = new RequestSpecBuilder().addHeader("authority", "http://localhost:8080")
.addHeader("authorization", "Bearer e8c108d6-c380-4715-849b-b6eccd8d2045")
.addHeader("origin", "http://localhost:8080").addHeader("referer", "http://localhost:8080")
.addHeader("Content-Type", "application/json").build();
JSONObject payload = new JSONObject();
body.put("endPlacementTimestamp", 1594994096206L);
body.put("startPlacementTimestamp", 1593525296206L);
given().log().all().spec(requestSpec).queryParam("pageNumber", "1").queryParam("pageSize", "40").body(payload)
.post("/api/v1/planning/trips");

In approach1:
Put RestAssured.baseURI="http://localhost:8080//api/v1";
Last line .post("/planning/trips?pageNumber=1&pageSize=40");
Refer https://www.toolsqa.com/rest-assured/post-request-using-rest-assured/

Related

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.
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.

400 Bad Request using postman copied request code

I have taken the request code from
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String json = String.format("{'sex': %s,'age': %d,'evidence': []}", gender, age);
RequestBody body = RequestBody.create(mediaType, json);
Request request = new Request.Builder()
.url("https://api.infermedica.com/covid19/diagnosis")
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "*/*")
.addHeader("App-Id", "XXXXXX")
.addHeader("App-Key", "XXXXXXXXXXXXXXXXXXXXX")
.addHeader("User-Agent", "PostmanRuntime/7.19.0")
.addHeader("Accept", "*/*")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "58fbac21-182b-41e0-bceb-0905d0605858,cd9580e6-f262-4440-ba33-b85877dd087c")
.addHeader("Host", "api.infermedica.com")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("Content-Length", "56")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.build();
com.squareup.okhttp.Response response = client.newCall(request).execute();
I am attempting to make a post request. I have successfully run the request in postman. And I have copied the code from postman. But when I run the request in java I get a 400 Bad Request. And I dont know why because all of the headers and the body is exactly the same as in postman.
You are missing quotes for Sex in your input
Confirmed here https://developer.infermedica.com/docs/covid-19
curl "https://api.infermedica.com/covid19/diagnosis" \
-X "POST" \
-H "App-Id: XXXXXXXX" -H "App-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
-H "Content-Type: application/json" -d '{
"sex": "male",
"age": 30,
"evidence": []
}'

Getting 403 error during GET request from Java application

I am trying to do a GET request with JAVA client using RestTemplate library, resulting in following error:
Exception in thread "main" org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden
When I am trying to hit the same URL by command line it is working fine. Posting the cURL command and Java code snippet here.
cURL :
curl -X GET -H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json" https://xxxx-xxxx-xxxx {"key":"value"}
JAVA snippet :
String URL="https://xyz";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//setting up the required headers
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("Authorization", "Bearer "+accessToken);
HttpEntity<String> entity = new HttpEntity<String>("body",headers);
//get request
ResponseEntity<String> responseEntity = restTemplate.exchange(URL, HttpMethod.GET, entity, String.class);
P.S - Is the issue because of the URL being a HTTPS one instead of HTTP ?
Add the user agent header, try and let us know if it works.
String URL="https://xyz";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
//setting up the required headers
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
//settting user agent
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
headers.set("Authorization", "Bearer "+accessToken);
HttpEntity<String> entity = new HttpEntity<String>("body",headers);
//get request
ResponseEntity<String> responseEntity = restTemplate.exchange(URL, HttpMethod.GET, entity, String.class);

Spring Boot multipart content type HTTP Request using RestTemplate

I am trying to emulate this request using RestTemplate in Spring Boot
curl -X POST
'https://my.craftar.net/api/v0/image/?api_key=123456789abcdefghijk123456789abcdefghijk'
-F "item=/api/v0/item/4fe672886ec142f6ab6d72d54acf046f/"
-F "file=#back_cover.png"
Here's my code:
MultiValueMap<String, Object> params= new LinkedMultiValueMap<>();
params.add("item", "/api/v0/item/4fe672886ec142f6ab6d72d54acf046f/");
final String filename=file.getOriginalFilename();
Resource contentsAsResource = new ByteArrayResource(file.getBytes()){
#Override
public String getFilename(){
return filename;
}
};
HttpHeaders imageHeaders = new HttpHeaders();
imageHeaders.setContentType(MediaType.IMAGE_PNG);
HttpEntity<Resource> imageEntity = new HttpEntity<Resource>(contentsAsResource, imageHeaders);
params.add("file", imageEntity);
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.ALL));
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String,Object>> requestEntity =new HttpEntity<>(params,headers);
try {
ResponseEntity<String> responseEntity = restTemplate.exchange(url,HttpMethod.POST, requestEntity, String.class);
return responseEntity.getBody();
} catch (final HttpClientErrorException httpClientErrorException) {
return httpClientErrorException.getResponseBodyAsString();
} catch (Exception exception) {
return exception.getMessage();
}
The above request throws a HttpClientErrorException and this what the response body looks like
{"error": {"message": "Expected multipart/form-data; boundary=<..> content but got multipart/form-data;boundary=x6G0xWVxdZX4n8pYNU8ihGAnCg4Twj3DgMARYDs.", "code": "WRONG_CONTENT_TYPE"}}
I have also tried using FileSystemResource, but it throws the same exception. The problem probably lies in formatting the data in multipart content-type.
If it can help, this is the code template generated by Postman on a successful request using Okhttp.
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
RequestBody body = RequestBody.create(mediaType,
"------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
Content-Disposition: form-data; name=\"item\"\r\n\r\n/api/v0/item/3d8dcdd1daa54bcfafd8d1c6a58249b5/\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
Content-Disposition: form-data; name=\"file\"; filename=\"times_logo.png\"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");
Request request = new Request.Builder()
.url("https://my.craftar.net/api/v0/image/?api_key=c6d4750c7368806fab27294fba8d0f93d48e1e11")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("cache-control", "no-cache")
.addHeader("Postman-Token", "cf09a989-338e-4d68-8968-b30a43384e5f")
.build();
Response response = client.newCall(request).execute();
just add the Resource to params instead of creating a HttpEntity
params.add("file", contentsAsResource);

HTTP post/API request works when sent from CURL on bash, fails from Apache http

I'm trying to use apache http components to interface with the Spotify api. The request I'm trying to send is detailed here under #1. When I send this request from bash using curl
curl -H "Authorization: Basic SOMETOKEN" -d grant_type=client_credentials https://accounts.spotify.com/api/token
I get back a token like the website describes
However the following java code, which as far as I can tell executes the same request, gives back a 400 error
Code
String encoded = "SOMETOKEN";
CloseableHttpResponse response = null;
try {
CloseableHttpClient client = HttpClients.createDefault();
URI auth = new URIBuilder()
.setScheme("https")
.setHost("accounts.spotify.com")
.setPath("/api/token")
.setParameter("grant_type", "client_credentials")
.build();
HttpPost post = new HttpPost(auth);
Header header = new BasicHeader("Authorization", "Basic " + encoded);
post.setHeader(header);
try {
response = client.execute(post);
response.getEntity().writeTo(System.out);
}
finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
}
Error
{"error":"server_error","error_description":"Unexpected status: 400"}
The URI that the code prints is looks like this
https://accounts.spotify.com/api/token?grant_type=client_credentials
And the header looks like this
Authorization: Basic SOMETOKEN
Am I not constructing the request correctly? Or am I missing something else?
Use form url-encoding for the data in the body with the content-type application/x-www-form-urlencoded :
CloseableHttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost("https://accounts.spotify.com/api/token");
post.setHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
post.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
StringEntity data = new StringEntity("grant_type=client_credentials");
post.setEntity(data);
HttpResponse response = client.execute(post);

Categories