400 (Bad Request) while sending json in Spring - 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!

Related

how to return only HTTP Status code, if we hit one pre-defined endpoint

When I hit
#FeignClient(name = "abc_abc", url = "${abc.host}")
public interface validateClient {
#PostMapping(path = "/api/abc/validate",
consumes = "application/json",
produces = "application/json")
**public <?> validateResponse**(#RequestHeader HttpHeaders htppHeaders, #RequestParam Map<String, Object> params,
#RequestBody String request);
}
in this example API: /api/abc/validate
i just want to return only HTTP status code
what is the return type of validateResponse method ? please some one plz suggest
Try use ResponseEntity without any "body", here an example.
#PostMapping(path = "/api/abc/validate",
consumes = "application/json",
produces = "application/json")
public ResponseEntity validateResponse(#RequestHeader HttpHeaders htppHeaders, #RequestParam Map<String, Object> params,
#RequestBody String request) {
return ResponseEntity.status(HttpStatus.FOUND).build();
}
You can choose from standard HttpStatus enum, or simply insert an integer for your custom needs

How do I enter path variable as UUID in postman request?

I have path variable parameter as a UUID, with path as id.
#RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = "application/json")
public ResponseEntity<T> getId(#PathVariable("id") final UUID id) {
}
when I add this as a String4df34f48-33ce-4da2-8eba-a682e2d1e698 or as String in brackets{4df34f48-33ce-4da2-8eba-a682e2d1e698} in my postman url, I get a 400 Bad Request error.
What can I do to add it here?
Thanks.
You need to have #PathVariable as part of the function itself:
#RequestMapping(method = RequestMethod.GET, path = "/{id}", produces = "application/json")
public ResponseEntity<UUID> getUID(#PathVariable("id") final UUID id) {
log.info("id is {}", id);
return new ResponseEntity<>(id, HttpStatus.OK);
}
That should then allow you to query it through Postman:
http://localhost:8080/4df34f48-33ce-4da2-8eba-a682e2d1e698

Spring get MediaType of received body

Following this answer I've set my method in controller this way:
#PostMapping(path = PathConstants.START_ACTION, consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<BaseResponse<ProcessInstance>> start(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params)
Now I need to behave differently according to my #RequestBody being of one MediaType or the other, so I need to know whether my params body is json o urlencoded. Is there a way to do this?
You can simply inject Content-Type header.
#PostMapping(path = "/{processDefinitionId}", consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> start(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params,
#RequestHeader("Content-Type") String contentType) {
if (contentType.startsWith(MediaType.APPLICATION_JSON_VALUE)) {
System.out.println("json");
} else {
// ...
}
return ResponseEntity.ok(params);
}
But I would suggest to split this method on two methods with different consumes values:
#PostMapping(path = "/v2/{processDefinitionId}", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> startV2Json(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params) {
return ResponseEntity.ok(params);
}
#PostMapping(path = "/v2/{processDefinitionId}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<String> startV2UrlEncoded(#PathVariable String processDefinitionId,
#RequestBody(required = false) String params) {
return ResponseEntity.ok(params);
}

I need to pass two #RequestBody parameters into my REST API POST method. How can I achieve this and can I do it using DefaultHttpClient?

My REST API method is:
#RequestMapping(value = "/api/test/summary", method = RequestMethod.POST)
postSummaryData(#RequestBody String one, #RequestBody String two) { ... }
#RequestMapping(value = "/api/test/summary/{one}/{two}", method = RequestMethod.POST) postSummaryData( #RequestParam String one, #RequestParam String two) {
}
Also you can try below:
#RequestMapping(value = "/api/test/summary", method = RequestMethod.POST) postSummaryData() {
RequestAttributes attr = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes)attr).getRequest();
// you can get param from this request
}

spring can't receive post param send by postman

And My Controller is like
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST,
produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestParam("companyId") Integer companyId) {
return companyManageService.deleteCompany(companyId);
}
But when I type code in chrome console using
$.post( "http://ltc_dev.leapstack.cn/gw/security/auth/company/delete", { companyId: 1 })
.done(function( data ) {
alert( data.success);
alert( data.message);
});
I got correct response, so.....
I'm not sure if it is a postman's bug, or I cofig the controller wrong
In your question, your controller method try to take companyId as request param. In postman you are sending companyId in request body. Like I said in comment you can send request param in url section directly like that: /auth/company/delete?companyId=2. Spring boot can detect companyId request parameter and assign it to method's companyId variable directly.
If you want to send companyId in request body (You said that in comment) you have to change your method's signature like below.
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST, produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestBody Map<String, Integer> map) {
return companyManageService.deleteCompany(map.get("companyId"));
}
Or:
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST, produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestBody CompanyDTO company) {
return companyManageService.deleteCompany(company.getCompanyId);
}
public class CompanyDTO {
private Integer companyId;
//getter setter
}
If you want to use request body and want to catch integer value directly in controller method's variable as integer your request body should be like:
{2}
And controller method should be like:
#RequestMapping(value = "/auth/company/delete", method = RequestMethod.POST, produces = {"application/json", "application/xml"})
#ResponseBody
public ResponseMessage deleteCompany(#RequestBody Integer companyId) {
return companyManageService.deleteCompany(companyId);
}

Resources