Bug: Required request body is missing - java

I'm trying spring framework.
I have RestController and function:
#RequestMapping(value="/changePass", method=RequestMethod.POST)
public Message changePassword(#RequestBody String id, #RequestBody String oldPass,
#RequestBody String newPass){
int index = Integer.parseInt(id);
System.out.println(id+" "+oldPass+" "+newPass);
return userService.changePassword(index, oldPass, newPass);
}
and code angularJS
$scope.changePass = function(){//changePass
$scope.data = {
id: $scope.userId,
oldPass:$scope.currentPassword,
newPass:$scope.newPassword
}
$http.post("http://localhost:8080/user/changePass/", $scope.data).
success(function(data, status, headers, config){
if(date.state){
$scope.msg="Change password seccussful!";
} else {
$scope.msg=date.msg;
}
})
.error(function(data, status, headers, config){
$scope.msg="TOO FAIL";
});
}
and when i run it.
Error Message :
Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.csc.mfs.messages.Message com.csc.mfs.controller.UserController.changePassword(java.lang.String,java.lang.String,java.lang.String)
Help me fix it, pls...

Issue is in this code.
#RequestBody String id, #RequestBody String oldPass,
#RequestBody String newPass
You cannot have multiple #RequestBody in same method,as it can bind to a
single object only (the body can be consumed only once).
APPROACH 1:
Remedy to that issue create one object that will capture all the relevant data, and than create the objects you have in the arguments.
One way for you is to have them all embedded in a single JSON as below
{id:"123", oldPass:"abc", newPass:"xyz"}
And have your controller as single parameter as below
public Message changePassword(#RequestBody String jsonStr){
JSONObject jObject = new JSONObject(jsonStr);
.......
}
APPROACH 2:
Create a custom implementation of your own for ArgumentResolver

You can't have request body for the GET method. If you want to pass username and password as part of request body then change RequestMethod type to POST/PUT.
If you want to use GET only then you will have to pass username and password as either path variables or request/query parameters - which is not best practice.
I would recommend changing RequestMethod and pass username & password as request body.

Related

Restful Webservice string response

I have an endpoint where it supposes to sends a string as a response. My question is do I need to use to response Entity to send string response or just return the string to the consumer?
#GetMapping(value = "/word")
public String getWord() {
String response = "webservice";
return response;
}
Second approach:
#GetMapping(value = "/word", produces ={MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<String> getWord() {
String response = "webservice";
return new ResponseEntity<>(response, HttpStatus.OK);
}
What is the correct approach to send just a string or use response entity?
What is the correct approach to send just a string or use response entity?
The Spring MVC documentation lists a number of types that can be returned from controller methods.
As I previously answered here and here, ResponseEntity<T> represents the entire HTTP response. Besides the body, its API allows you to set headers and a status code to the response.
Returning just a bean instance or a string is fine but doesn't give you much flexibility: In the future, if you need to add a header to the response or modify the status code, for example, you need to change the method return type.

How to validate Java API #HeaderParam before execution of method

I have this endpoint method:
#RequestMapping(value = "/update")
public ResponseEntity(Response) update(
#ApiParam(required=true) #Valid #RequestBody Request request,
#RequestHeader #HeaderParam("key") String key
){
//execution of code here
return null;
}
I'm currently validating the Request Body using a custom JSON Deserializer.
Is there anyway that I could validate the Header Param "key" similar to the way I would validate a Request Body using a JSON Deserializer?
Maybe something like this that would execute before the "//execution of code here":
#Override
public String deserialize(String key){
if(!key.equals("ABC")){
throw new Exception("key is wrong");
}
return key;
}
Thank you!

Java Spring MVC - Send JSON request body error

I am trying to send a JSON string as a request to my application. This is my code:
#RequestMapping(
value = "/mylink/upload",
method = RequestMethod.POST,
consumes ="application/json",
produces = "application/json")
public
#ResponseBody
List<Upload> upload(
#RequestParam(value = "hdfsLocation") String hdfsLocation
) throws Exception {
return S3HdfsTransfer.uploadFromHDFS(hdfsLocation);
}
I am trying to send a request with Postman. The method I use is POST, the header contains: Accept "application/json",Content-Type "application/json", the request body is the following:
{
"hdfsLocation" : "hdfs://145.160.10.10:8020"
}
This is the response I get. If I put the parameter in the URL, it works.
{
"httpStatus": 500,
"appErrorId": 0,
"message": "Required String parameter 'hdfsLocation' is not present",
"trackingId": "8c6d45fd-2da5-47ea-a213-3d4ea5764681"
}
Any idea what I am doing wrong?
Thanks,
Serban
Looks like you have confused #RequestBody with #RequestParam. Do either of following :
Pass the request param as a request param(not as a body). Like, (encoded)
http://example.com?hdfsLocation=http%3A%2F%2Fexample.com%3FhdfsLocation%3Dhdfs%3A%2F%2F145.160.10.10%3A8020
Replace the #RequestParam with #RequestBody. If you are sending a body, don't send it along with request param. Those are two different things.
I guess you over looked :)
Shouldn't it be #RequestBody instead of #RequestParam?
Also, even after using #RequestBody, the whole of the JSON string:
{
"hdfsLocation" : "hdfs://145.160.10.10:8020"
}
will be the value of String hdfsLocation and not just the hdfs url. Hence, you'll have to JSON parse that JSON by yourself to get just the hdfs url.

How to ignore JSON processing for a request in Spring MVC?

I have a request handler for which I would like to skip json processing and retrieve the request body as a string. Eg -
#RequestMapping(value = "/webhook", method = RequestMethod.POST)
public void webHook(#RequestBody String body) {
}
However, the above method definition doesnt work as Spring forcibly tries to parse the posted string as json and thus throws an exception.
How do i tell spring to skip json processing for this request?
use like this it'll work.
#RequestMapping(value = "/webhook", method = RequestMethod.POST)
public void webHook(HttpServletRequest request) {
String body = IOUtils.toString( request.getInputStream());
// do stuff
}
Not using #RequestBody is key here. When spring sees #RequestBody it tries to map the entire body as object.

Consume a String sent via PUT method

I'm developing REST services using Jersey. In a PUT method, I want to consume a String, and then use it in another method.
Something like: I enter a String in the "Content" field (of TEST REST WEB SERVICES page) and then I use that String in a logout method:
#PUT
#Path("logout")
#Produces({"application/json", "text/plain"})
#Consumes(**xxxxx**)
public String logout(**xxxxx**) throws Exception
{
String reponse = null;
reponse = new UserManager().logout(**xxxxx**);
return reponse;
}
So, I want to know what to put in the ** xxxxx ** fields.
Thanks!
Just use a String argument. The JAX-RS runtime will marshall the request body into it.
#PUT
#Path("logout")
#Produces({"application/json", "text/plain"})
public String logout(String data) throws Exception {
String response = null;
reponse = new UserManager().logout(data);
return response;
}
You should define #Consumes to be whatever content type(s) you want to allow the client to be able to send, or leave it out altogether to accept any content type.

Categories

Resources