POST Request in WebClient in Spring Boot and Receive responce as JSONObject - java

I am trying to make API POST Request with WebClient in Spring Boot. But I cannot to make a request and receive response as JSONObject. With RestTemplate I did it, recently I started to learn WebClient. So that I got stuck.
Error Spring gives:
Error:(48, 28) java: incompatible types: no instance(s) of type variable(s) T exist so that reactor.core.publisher.Mono conforms to org.json.simple.JSONObject
Here is my source code:
Controller.java
JSONObject jsonObject = new JSONObject();
Turnover turnover = new Turnover();
JSONObject resp = webClientBuilder.build()
.post()
.uri("http://180.12.10.10:8080/turnover/")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.accept(MediaType.APPLICATION_JSON )
.body(Mono.just(turnover),Turnover.class)
.retrieve()
.bodyToMono(JSONObject.class);
Turnover.java
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class Turnover {
private String start_date;
private String end_date;
private String account;
public Turnover(){
setStart_date("01.01.2020");
setEnd_date("01.06.2020");
setAccount("20296");
}
}
Json I want to send
{
"start_date":"01.01.2020",
"end_date":"01.06.2020",
"account":"20296"
}
Response API Returns:
{
"status": 1,
"message": "success",
"data": [
{
"CODE_ACCOUNT": "20296",
"CREDIT": 60610187386.86,
"DEBIT": 60778253872.1
}
]
}
Any Help is appreciated!

Most likely the issue is that you're asking for a string back but assigning it to a JSONObject. The exception seems odd and I'd expect a compilation error with what you have but try this:
.bodyToMono(JSONObject.class)
.block();
And you'll need to fix the content type on the request to be MediaType.APPLICATION_JSON so that it passes your object as json.

Related

Method is not being detected when using the Custom class as input parameter type for the REST API service

I am developing a Web application using Vuejs/Nuxtjs which makes call to my Java Service using the Axios but during the call I get the error:
POST http://localhost:9001/generate 500 (Internal Server Error)
I am getting this error because my Java service type accepts the input parameter of Custom data type InputParameter. If I change to String then it works fine. So I would like to know what changes should I make to front-end call or to my Java Service so it can work with InputParameter type.
Following is the Vuejs call that I am making to Java service:
const headers = { 'Content-Type': 'application/json' }
this.$axios.post('/generate', { ...JSON.parse(inputParameter) }, { headers })
.then((response) => {
console.log(JSON.stringify(response.data))
})
.catch((error) => {
console.log(error)
})
Following is my Java service method which is NOT working with custom data type InputParameter, the call does not detect the method and execution does not go within the method:
#Path("/generate")
#Produces(MediaType.APPLICATION_JSON)
#APIResponses(value = {
#APIResponse(responseCode = "200", description = "returns list of JSON Objects"),
#APIResponse(responseCode = "500", description = "An internal Server Error occurred")
})
public String generate(final InputParameter inputParameter){
System.out.println(inputTemplate.toString());
return null;
}
If I change the above JAVA Service method input parameter data type to String then the method is detected and input is printed:
#Path("/generate")
#Produces(MediaType.APPLICATION_JSON)
#APIResponses(value = {
#APIResponse(responseCode = "200", description = "returns list of JSON Objects"),
#APIResponse(responseCode = "500", description = "An internal Server Error occurred")
})
public String generate(final String inputParameter){
System.out.println(inputTemplate);
return null;
}
I am not understanding whats wrong here. Can someone please help?
Things I have tried:
Adding #Consumes(MediaType.APPLICATION_JSON).
Changing the method to public String generate(#RequestBody final InputParameter inputParameter)
My InputParameter class looks something like this:
#Data
#AllArgsConstructor
#NoArgsConstructor
public class InputParameter {
private List<String> names;
private List<String> jobs;
}
My InputParameter which I am passing to Java Service looks something like this:
{
"names":[
"Batman",
"Superman",
"Ironman"
],
"jobs":[
"Fighting",
"Fyling",
"Teching"
]
}
Dear in the back end the api is accepting an object of type InputParameter. For solving the problem you have to create a class the same as InputParameter class and generate an object of that and send that object to the back end.
Let me know if you need more help!
Posting the answer can be helpful to someone else in the future. I tried some things but nothing worked and finally following worked for me:
#POST
#Path("/generate")
#Produces(MediaType.APPLICATION_JSON)
#APIResponses(value = {
#APIResponse(responseCode = "200", description = "returns list of JSON Objects"),
#APIResponse(responseCode = "500", description = "An internal Server Error occurred")
})
public String generate(final InputParameter inputParameter){
System.out.println(inputTemplate.toString());
return null;
}
There was also one small setting that I had to change related to Jackson ObjectMapper which is not relevant here because it's my project-specific that I missed in another class. Maybe that was the issue I was facing. Now everything is working as expected.

Quarkus service passing parameter other than String type results in error

I am developing an application using Vuejs which calls the Java service. This service is will take a parameter. If I pass the parameter as String then it would accept and continue with execution. However, this input corresponds to my Java Object Model type hence if I change the type to my Java Object type then I get the error:
Unable to obtain data, Error: Error: Request failed with status code 500
I would like to change the InputParameter type to my custom Java type can someone please tell me what I need to do for this?
Following is the working code with String type:
#POST
#Path("/generate")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#APIResponses(value = {
#APIResponse(responseCode = "200", description = "returns list of JSON Objects"),
#APIResponse(responseCode = "500", description = "An internal Server Error occurred")
})
public String generate(final String inputParameter){
System.out.println(inputTemplate);
return null;
}
The above code works fine and I am able to get the inputParameter printed, But I know that my inputParameter will always be my Custom java object type InputParameter so if I change the type then the execution won't detect the method and nothing is being printed and I get the error POST http://localhost:9001/generateTestData 500 (Internal Server Error):
#POST
#Path("/generate")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#APIResponses(value = {
#APIResponse(responseCode = "200", description = "returns list of JSON Objects"),
#APIResponse(responseCode = "500", description = "An internal Server Error occurred")
})
public String generate(final InputParameter inputParameter){
System.out.println(inputTemplate.toString());
return null;
}
Following is the call I am making in my vuejs application:
const headers = { 'Content-Type': 'application/json' }
this.$axios.post('/generate', { ...JSON.parse(inputParameter) }, { headers })
.then((response) => {
console.log(JSON.stringify(response.data))
})
.catch((error) => {
console.log(error)
})

How to handle Request with JSON and Multipart File in spring boot

I am trying to create a REST API in the format which will accept request data with both JSON and MultipartFile type.
THis is my request which will be in following format in POSTMAN:
My POJO classes are as follows:
Class:Organisation
public class Organisation
{
priavet int org_id;
private MultipartFile organisationRegistrationDocument;
private Teachers[]
// getters and setters
}
Class: Teachers
class Teachers{
private String teacherId;
private MultipartFile teacherPhoto;
// getters and setters
}
My controller Class is as follows:
#RequestMapping(value="/test",method=RequestMethod.POST,headers = {"content-type=multipart/mixed","content-type=multipart/form-data"})
private ResponseEntity<Object> testUpload(#RequestBody Organisation org) {
return null;
}
Error Thrown from POSTMAN:
{
"timestamp": "2018-10-03T07:38:30.439+0000",
"status": 400,
"error": "Bad Request",
"message": "Required request part 'org' is not present",
"path": "/test"
}
So anyone can kindly guide me what can I am doing wrong due to which I am not able to achieve the desired result to process request of the above form?

consume Rest api with two different responses

I am trying to consume api with two different responses. when providing proper input and headers, it gives one json object. That is working fine with code given below.
but when one of the inputs or headers are missing then api is returning other json which states error details while hitting through Postman but same is not getting achieved by client code. It throws exception but api should return json with error details.
first I tried with postForobject(), then changed to exchange() assuming postForObject returning object and api is not getting expected object format. so tried with String.clas instead of particular class
what can be done to get two different json object by hitting same url?
when success:
{
"contacts": [
{
"input": "98########",
"status": "valid"
}
]
}
when input or header missing:
"errors": [
{
"code": 1###,
"title": "Access denied",
"details": "invalid deatils"
}
]
below is my code:
public static void main(String[] args) throws Exception {
RestTemplate restTemplate = new RestTemplate();
String check_Contact_Async = "https://port/contacts/";
sslByPass();
//headers = setHeaders();
contactsDTO = getInput();
final HttpEntity<ContactsDTO> entity = new HttpEntity<ContactsDTO>(contactsDTO, headers);
try {
//WsResponse res = restTemplate.postForObject(check_Contact_Async, entity, WsResponse.class);
ResponseEntity<String> responseEntity = restTemplate.exchange(
check_Contact_Async, HttpMethod.POST, entity,
String.class);
System.out.println(responseEntity);
} catch (Exception exception) {
System.out.println(exception);
}
}
Exception in thread "main" org.springframework.web.client.HttpClientErrorException: 401 Unauthorized
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:667)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:620)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:498)
at com.websystique.springmvc.apitest.Example.main(Example.java:120)
any clue will be helpful
Thanks

how to retrieve a part of JSON HTTP response as POJO

I am currently working on a project where i need to make a rest call to an external API and parse the JSON response to a POJO and return back the POJO as JSON for another rest request. I am able to parse the JSON response, but my requirement is to parse only one particular node from it. How can i achieve this? I am using Spring Boot and Spring Rest Template to make the external rest call. Please help!!!
#RestController
public class ProductsController {
private static final Logger LOGGER = LoggerFactory.getLogger(ProductsController.class);
#RequestMapping(value = "/myRetail/product/{id}", method = RequestMethod.GET, produces = {
MediaType.APPLICATION_JSON_UTF8_VALUE, MediaType.APPLICATION_XML_VALUE })
#ResponseBody
public Item getSchedule(#Valid Payload payload) {
String URL = "<External API>";
LOGGER.info("payload:{}", payload);
Item response = new Item();
RestTemplate restTemplate = new RestTemplate();
Item item = restTemplate.getForObject(URL, Item.class);
LOGGER.info("Response:{}", item.toString());
return response;
}
}
JSONResponse (This is a part of whole i receive)
{
"ParentNode": {
"childNode": {
"att": "13860428",
"subchildNode 1": {
"att1": false,
"att2": false,
"att3": true,
"att4": false
},
"att4": "058-34-0436",
"att5": "025192110306",
"subchildenode2": {
"att6": "hello",
"att7": ["how are you", "fine", "notbad"],
"is_required": "yes"
},
............
}
Required JSONpart from the above whole response:
"subchildenode2": {
"att6": "hello",
"att7": ["how are you", "fine", "notbad"],
"is_required": "yes"
}
Use the org.json library. With this library you can parse the payload to a JSONObject and navigate to your required subpart of the document.
So you have to get the payload as a JSON-String and parse it to the JSONObject from the library. After that you can navigate to your required subpart of the document and extract the value and then parse it to your required Java POJO.
Have look at: How to parse JSON
Just map the path to the needed object:
{
"ParentNode": {
"childNode": {
"subchildenode2": {
"att6": "hello",
"att7": ["how are you", "fine", "notbad"],
"is_required": "yes"
}
}
}
And then simply:
Response responseObject= new Gson().fromJson(json, Response.class);
SubChildNode2 att6 = responseObject.getParentNode().getChildNode().getSubChildNode2();

Categories

Resources