Spring RestTemplate exchange DELETE with body jdk 1.8 - java

I'm trying to do a HTTP DELETE request with body with Spring RestTemplate via exchange method but I always get a 400 Bad Request like this question. With JavaScript and other tools it is posible to make this API call with DELETE.
I know java <1.8 doesent support DELETE with body, but with 1.8 it should be able: see here. I'm using spring-web-4.2.6.RELEASE with jdk 1.8 so I think there must be a way.
My code:
public DealResponse closePosition(DealCloseRequest dealCloseRequest) {
try {
ObjectMapper mapper = new ObjectMapper();
//Object to JSON in String
String jsonInString = mapper.writeValueAsString(dealCloseRequest);
HttpEntity<String> entity = new HttpEntity<String>(jsonInString, this.headers);
//execute request
ResponseEntity<DealResponse> response = restTemplate.exchange("https://" + this.domain + "/gateway/deal/positions/otc", HttpMethod.DELETE, entity, DealResponse.class);
//return filled DealResponse object
return response.getBody();
} catch (JsonProcessingException e) {
this.logger.warn("could not close Position because: "+e);
return null;
}
}
Error message:
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
Does anyone know a way to do this with spring restTemplate?

HTTP DELETE request with body works fine with rest template for Spring 4.2 release. There could be some issue with request body you are sending to your service. Can you check "jsonInString" if it is forming correct json payload.Check the headers as well for "application/json" type. You can verify your service using Postman by sending DELETE request.

Related

400 HTTP method POST is not supported by this URL

I am currently working on renewing youtrack api methods in the project since old youtrack api has been deprecated, and when I'm trying to send requsts such as:
https://youtrack.my.ru/api/admin/customFieldSettings/bundles/version/
https://youtrack.my.ru/api/issues?query=sampletext
and I am getting
400 HTTP method POST is not supported by this URL
Thr problem is not in the requsts itself, because i tryed using the same requests with the same bodies and headers via postman and it worked perfectly, so i assume it is something with my java restTemplate config, you can se samples of me sending requests below:
ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, versionsEntity, String.class);
logger.debug("Adding new version response status is {}", response.getStatusCode());
return response.getStatusCode() == HttpStatus.CREATED;
And this is how I add body to the requst (the body is the versionBundle object):
versionsEntity = new HttpEntity<>(new ObjectMapper().writeValueAsString(versionBundle), entity.getHeaders());
You can also see that youtrack api itself is perfectly ok with me using POST requst to update a bundle here: https://www.jetbrains.com/help/youtrack/devportal/operations-api-admin-customFieldSettings-bundles-version.html#update-VersionBundle-method
Any help is appreciated!
Somehow problem was resolved by creating new RestTemplate with autowired templateFactory, before i was autowiring RestTemplate, if someone can explain me why is this helped it would be great

how to create client TGT with java cxf

I'm new to the java rest CXF client. I will make various requests to a remote server, but first I need to create a Ticket Granting Ticket (TGT). I looked through various sources but I could not find a solution. The server requests that I will create a TGT are as follows:
Content-Type: text as parameter, application / x-www-form-urlencoded as value
username
password
I create TGT when I make this request with the example URL like below using Postman. (URL is example). But in the code below, I'm sending the request, but the response is null. Could you help me with the solution?
The example URL that I make a request with POST method using Postman: https://test.service.com/v1/tickets?format=text&username=user&password=pass
List<Object> providers = new ArrayList<Object>();
providers.add(new JacksonJsonProvider());
WebClient client = WebClient.create("https://test.service.com/v1/tickets?format=text&username=user&password=pass", providers);
Response response = client.getResponse();
You need to do a POST, yet you did not specify what your payload looks like?
Your RequestDTO and ResponseDTO have to have getters/setters.
An example of using JAX-RS 2.0 Client.
Client client = ClientBuilder.newBuilder().register(new JacksonJsonProvider()).build();
WebTarget target = client.target("https://test.service.com/v1/tickets");
target.queryParam("format", "text");
target.queryParam("username", "username");
target.queryParam("password", "password");
Response response = target.request().accept(MediaType.APPLICATION_FORM_URLENCODED).post(Entity.entity(yourPostDTO,
MediaType.APPLICATION_JSON));
YourResponseDTO responseDTO = response.readEntity(YourResponseDTO.class);
int status = response.getStatus();
Also something else that can help is if you copy the POST request from POSTMAN as cURL request. It might help to see the differences between your request and POSTMAN. Perhaps extra/different headers are added by postman?
Documentation: https://cxf.apache.org/docs/jax-rs-client-api.html#JAX-RSClientAPI-JAX-RS2.0andCXFspecificAPI
Similar Stackoverflow: Is there a way to configure the ClientBuilder POST request that would enable it to receive both a return code AND a JSON object?

Spring Rest Template - Post Request String Body to azure gives 500 error

I'm able call 4-5 rest apis, prior to coming to this block of code. But I'm not able to execute this block of code.
I am using spring 4.0.4 core, mvc jars.
I am trying to call a azure ucwa web service using rest template, its a post method with string as body. I m getting a 500 internal error. I have searched all over internet and yet did not find solution, Please guide me. Thank you.
link : https://learn.microsoft.com/en-us/skype-sdk/ucwa/sendanim
step 9
RestTemplate restTemplate = new RestTemplate();
System.out.println(" jsonLinksObj : 4a "+jsonLinksObj);
org.json.JSONObject jsonSendMessageObj = jsonLinksObj.getJSONObject("sendMessage");
String sendMsgFullUrl = poolUrl.concat(jsonSendMessageObj.getString("href")).concat("?OperationContext=4322131");
headers.clear();
headers.setContentType(MediaType.TEXT_PLAIN);
headers.set("Authorization", "Bearer " + jwtToken);
String body = "My Send Message Here";
HttpEntity<Object> entityJsonSendMsg4 = new HttpEntity<Object>(body, headers);
ResponseEntity<Object> sbSendMsgObj = null;
try{
sbSendMsgObj = restTemplate.exchange(
new URI(sendMsgFullUrl),
HttpMethod.POST,
entityJsonSendMsg4,
Object.class);
} catch(Exception e){
e.printStackTrace();
}
WARN : org.springframework.web.client.RestTemplate - POST request for "https://webpoolpnqin102.infra.lync.com/ucwa/oauth/v1/applications/102086376449/communication/conversations/46db8085-8ad0-4186-a4f0-9a521b256b9b/messaging/messages?OperationContext=4322131" resulted in 500 (Internal Server Error); invoking error handler
org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:589)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:547)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:518)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:463)
at com.test.example.employee.test.EmployeeTest.sendMessage(EmployeeTest.java:266)
at com.test.example.employee.test.EmployeeTest.main(EmployeeTest.java:337)
Exception in thread "main" java.lang.NullPointerException
at com.test.example.employee.test.EmployeeTest.sendMessage(EmployeeTest.java:331)
at com.test.example.employee.test.EmployeeTest.main(EmployeeTest.java:337)
It is hard to say what is the reason behind the 500 you got in response - you probably have to debug it yourself but it should not be very hard.
Since you created RestTemplate using default constructor you have got a deafault error handling. Run your application in debug mode and place a breakpoint in DefaultResponseErrorHandler::handleError. There you get the access to response represented by ClientHttpResponse class and can actually look into body you got back.
When you know the reason behind the error you can correct the request accordingly.
I have clean and build the project. And run the code again. Its working fine, anybody want to send string in body, can use the above rest template code. Thank you.

JUnit for REST: Cannot POST data

I want to write a JUnit class for a REST endpoint.
This is my REST method. It works fine.
#POST
#Path("create")
#Produces(APPLICATION_JSON)
public String create(#QueryParam("parentId") String parentId, #QueryParam("name") String name) {
//do sth.
return "{\"status\": \"SUCCESS\"}";
}
Now my JUnit test looks like that, which doesn't work, because I don't know how to POST my data in the right way:
#Test
public void testCreate() {
Client client = ClientBuilder.newClient();
WebTarget wt = client.target(REST_MENU_URL + "create");
String queryParams = "parentId=1&name=NEW_JUnit_NEW";
// In the line below, I want to POST my query parameters, but I do it wrong
Response response = wt.request().post(Entity.entity(queryParams, APPLICATION_JSON), Response.class);
// The response has a 500, because the query parameters are all NULL!
assertEquals("Http code should be 200", 200, response.getStatus());
}
So how do I have to change the line with the 'Response' to make it work?
The problem is, that the query parameters (parentId and name) don't get transmitted (response = wt.request().post(...)).
I tried to POST form parameters too, but no success here either. Just like that:
Form form =new Form().param("parentId", "4").param("name", "NEW_JUnit_NEW");
Response response = wt.request().post(Entity.entity(form, APPLICATION_JSON), Response.class);
Thanks,
Bernhard
Check out the Jersey Client documentation, in particular section 5.3.4 on targeting resources.
Query parameters form a part of the URI of the resource, they're not part of the body of the document posted to the resource. You're seeing null in your resource because you're not filling in the query parameters in the URI, you're posting them as the body. You need to tell Jersey to put them in the URI...
WebTarget wt = client.target(REST_MENU_URL + "create").queryParam("parentId", 1).queryParam("name", "NEW_JUnit_NEW");
You'll also need to ensure that your POST request sets the Accept header to allow application/json (by calling the accept(...) method after calling request()) and you're going to need to construct some kind of Entity to pass to the post(...) method - the problem here is that your resource is not consuming the entity body but the client API expects you to send something - this is a code smell which suggests your API is not particularly ReSTful. You can probably get away with some kind of empty body constructed from an empty string. It should look a bit like this...
Response response = wt.request().accept(MediaType.APPLICATION_JSON).post(Entity.text(""))
Alternatively, you could look into converting your API so that it accepts a JSON document and move the query parameters into that document.

How to post raw json text in Jersey Client HTTP POST request?

I want to make an HTTP POST request, which requires parameters must be passed as raw JSON text, but I don't know how to do in with Jersey client.
Here is the API specs (works well in Postman Rest Client): (please look at the screenshot from my Postman, the URL, parameter in body, and 2 headers are Content-Type: application/json & Accept: application/json)
And here is what I've tried with Jersey:
JsonObject parameters = new JsonObject();
parameters.addProperty("centerId", centerId);
parameters.addProperty("studentId", studentId);
if (fromDate != null) {
parameters.addProperty("fromDate", fromDate);
}
if (toDate != null) {
parameters.addProperty("toDate", toDate);
}
Object response = client.target("http://localhost:8080/rest").path("student/calendar")
.request(MediaType.APPLICATION_JSON).post(Entity.json(parameters), String.class);
but nothing worked. Can anyone suggest what is the correct way to deal with Jersey in this case? Thank you.
Use an InputStream for your entity construction, it should work
String payload = "{\"schoolId\":1,\"studentId\":1,\"fromDate\":\"1454259600000\",\"toDate\":\"1456765200000\"}";
client.target("<targetURI>")
.request(MediaType.APPLICATION_JSON)
.post(Entity.entity(
new ByteArrayInputStream(payload.getBytes()),
MediaType.APPLICATION_JSON
));
But in the end, Entity.json(payload) should also work.

Categories