Spring boot: Sending a JSON to a post request that uses a model as a param - spring

Lets say I have a predefined post mapping as such:
#PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> addVal(#RequestBody final valDetail newVal) {
//Do Stuff
}
and the valDetail object as follows:
#Data
#Component
#Entity
#Table(name = "val_portal")
public class valDetail {
#Id
#Column(name = "valcode")
private String valCode;
#Column(name = "valname")
private String valName;
}
How would I go about actually sending JSON values from a separate service to this /add endpoint so that they are properly received as a valDetail object?
Currently I tried this implementation but I keep getting a 415 response code.
JSONObject valDetail = new JSONObject();
valDetail.put("valCode",request.getAppCode().toLowerCase());
valDetail.put("valName", request.getProjectName());
String accessToken = this.jwtUtility.retrieveToken().get("access_token").toString();
HttpHeaders authHeaders = new HttpHeaders();
authHeaders.setBearerAuth(accessToken);
authHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(valDetail.toString(), authHeaders);
ResponseEntity<String> loginResponse = restTemplate.exchange(uri,
HttpMethod.POST,
entity,
String.class);

If you want to pass data as json you don't want to take Model try to use #ResponseBody annotation to transfer data through json.
#PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<String> addVal(#RequestBody final valDetail newVal) {
//Do Stuff
}

Related

call external api in spring boot

I am using get api for getting data from url but it give response in string format i want exact response or json response
`
#RestController
public class HelloController {
#GetMapping("/discover")
private String getApi(){
String url ="https://discover.search.hereapi.com/v1/discover?at=18.49093,73.8332&limit=2&q=restaurant&in=countryCode:IND&apiKey=hhV0nHGeHgrg5LACzw7dDJNe49bYCNvkCWxV94LlHno";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(url,String.class);
//Object[] result = restTemplate.getForObject(url, Object[].class);
//List<String> arr = new ArrayList<String>();
//arr.add(restTemplate.getForObject(url,String.class));
return result;
}
}
`
In this case, you get what you ask for, which is a String. If the string being returned is JSON, you can either use an ObjectMapper to deserialize it into an object that represents the response or have RestTemplate do it for you.
Assuming the response payload looks like this:
{
"name": "some name"
}
Then you'd create a class to represent the response (using lombok for getters and setters):
#Getter
#Setter
public class ApiResponse {
private String name;
}
Then you can either let RestTemplate do the work for you:
ApiResponse result = restTemplate.getForObject(url, ApiResponse.class);
Or, handle it yourself
String result = restTemplate.getForObject(url,String.class);
ApiResponse apiResponse = new ObjectMapper().readerFor(ApiResponse.class).readValue(result);

Trying to send a http post req in java

I am trying to send a http request but keep getting a error 500 or sometime media type error. Any sugestion and also an example from postman trying to do
Postman post Example
// Email model
private String module;
private String notificationGroupType;
private String notificationGroupCode;
private String notificationType;
private String inLineRecipients;
private String eventCode;
private HashMap<String, Object> metaData;
public EmailModel() {
this.module = "tset";
this.notificationGroupType ="test";
this.notificationGroupCode =test"tset";
this.notificationType = "EMAIL";
this.inLineRecipients ="[test]";
this.eventCode = "DEFAULT";
this.metaData = metaData;
}
//Controller code
private EmailModel em;
#RequestMapping(value = "test", method = RequestMethod.GET)
public void post() throws Exception {
String uri= "";
EmailModel em = new EmailModel();
EmailModel data =em;
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.headers("Content-Type", "application/json")
.uri(URI.create(uri))
.POST(HttpRequest.BodyPublishers.ofString(String.valueOf(data)))
.build();
HttpResponse<?> response = client.send(request, HttpResponse.BodyHandlers.discarding());
System.out.println(em);
System.out.println(response.statusCode());
}

Can i send a error-map along with a response object in response? What is the proper way?

I have a spring rest end point which accepts a user object and returns another userobject as response. My controller method looks like:
#PostMapping
public UserResponse createUser(#RequestBody UserDetailsRequestModel userDetails)
throws Exception {
UserRest userResponse= new UserRest();
ModelMapper modelMapper = new ModelMapper();
UserDto userDto = modelMapper.map(userDetails, UserDto.class);
userDto.setRoles(new HashSet<>(Arrays.asList(Roles.ROLE_USER.name())));
UserDto createdUser = userService.createUser(userDto);
returnValue = modelMapper.map(createdUser, UserResponse.class);
return userResponse;
}
My userResponse class looks like
public class UserRest {
private String userId;
private String firstName;
private String lastName;
private String email;
....getters and setters
And this flow is working fine. But now I need to add validation to createUser method (JSR 303) to check if incoming JSON fields are ok. For this I am trying to add below code in my controller
#PostMapping
public UserResponse createUser(#Valid #RequestBody UserDetailsRequestModel userDetails, BindingResult result){
if(result.hasErrors()){
Map<String, String> errorMap = new HashMap<>();
for(FieldError error: result.getFieldErrors()){
errorMap.put(error.getField(), error.getDefaultMessage());
}
**return new ResponseEntity<Map<String, String>>(errorMap, HttpStatus.BAD_REQUEST);**
}
UserRest userResponse= new UserRest();
ModelMapper modelMapper = new ModelMapper();
UserDto userDto = modelMapper.map(userDetails, UserDto.class);
userDto.setRoles(new HashSet<>(Arrays.asList(Roles.ROLE_USER.name())));
UserDto createdUser = userService.createUser(userDto);
returnValue = modelMapper.map(createdUser, UserResponse.class);
return **userResponse**;
The obvious problem in my code is that I can't convert from ResponseEntity<Map<String,String>> to UserResponse object.
Is there a proper way of doing this ? so that I can send errors(if any) or the UserResponse object if there are no errors within the same controller method?
Return a type of ResponseEntity<?>
#PostMapping
public ResponseEntity<?> createUser(#Valid #RequestBody UserDetailsRequestModel userDetails, BindingResult result){
if(result.hasErrors()){
...
return ResponseEntity.badRequest().body(errorMap);
}
...
return ResponseEntity.ok(userRequest);
}
You can return an HttpEntity<?> generic object from a controller method accepting both response type.
You have to wrap the UserResponse response around a ResponseEntity object

JSON to CSV API with Spring RestTemplate

I want to hit a JSON to CSV API after grabbing a JSON from my own API. The JSON to CSV API requires email and JSON passed in a POST request. Now I am able to store JSON locally but, how do I pass in both the email and JSON in the request and how do I handle the CSV from the response?
Controller
#PostMapping("/generateExcel")
public String getEmployeeCsv(#RequestBody String email) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
String json = restTemplate.exchange("http://localhost:8080/SwaggerTest/employees", HttpMethod.GET, entity, String.class).getBody();
entity = new HttpEntity<String>(json, email, headers);
return restTemplate.exchange("https://json-csv.com/api/getcsv", HttpMethod.POST, entity, String.class).getBody();
}
Update:
I created a EmployeeCsvParams class with email and json String fields as suggested by #Adrien but I still need to handle the CSV from the response.
#PostMapping("/generateExcel")
public String getEmployeeCsv(#RequestBody String email) {
HttpHeaders headers = new HttpHeaders();
EmployeeCsvParams params = new EmployeeCsvParams();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
String json = restTemplate.exchange("http://localhost:8080/SwaggerTest/employees", HttpMethod.GET, entity, String.class).getBody();
params.setEmail(email);
params.setJson(json);
HttpEntity<EmployeeCsvParams> entity2 = new HttpEntity<EmployeeCsvParams>(params, headers);
return restTemplate.exchange("https://json-csv.com/api/getcsv", HttpMethod.POST, entity2, String.class).getBody();
}
From spring docs #RequestBody "You can use the #RequestBody annotation to have the request body read and deserialized into an Object through an HttpMessageConverter. ..."
So i assume you can create the object bellow and use it as argument in your endpoint.
public class EmployeeCsvParams {
/* Fields */
private String email;
private String json;
/* Getters and Setters */
public String getEmail() { return this.email; }
public void setEmail(String email) { this.email = email; }
public String getJson() { return this.json; }
public void setJson(String json) { this.json = json; }
}
#PostMapping("/generateExcel")
public String getEmployeeCsv(#RequestBody EmployeeCsvParams employeeCsvParams)
{
/* ... */
}

400 (Bad Request) while sending json in Spring

I'm trying to send json string to Spring controller, i'm getting 400 - bad request as response
i'm using Spring 4.0.3
This is my controller
#Controller
public class Customer{
#RequestMapping(value = "/apis/test", method = RequestMethod.GET, produces = "application/json")
public #ResponseBody String test(HttpServletRequest params) throws JsonIOException {
String json = params.getParameter("json");
JsonParser jObj = new JsonParser();
JsonArray jsonObj = (JsonArray ) jObj.parse(json);
for(int i = 0; i < jsonObj.size(); i++) {
JsonObject jsonObject = jsonObj.get(i).getAsJsonObject();
System.out.println(jsonObject.get("name").getAsString());
}
return json;
}
}
Please help me to solve this
#RequestMapping(value = "/apis/test", method = RequestMethod.GET, produces = "application/json")
The above means this is a HTTP GET method which does not normally accept data. You should be using a HTTP POST method eg:
#RequestMapping(value = "/apis/test", method = RequestMethod.POST, consumes = "application/json")
public #ResponseBody String test(#RequestParam final String param1, #RequestParam final String param2, #RequestBody final String body) throws JsonIOException {
then you can execute POST /apis/test?param1=one&param2=two and adding strings in the RequestBody of the request
I hope this helps!

Resources