How to add a request body to spring mockmvc - spring

I have the following post endpoint:
#PostMapping(path = "/migration/sendStatements")
public void sendStatements(#RequestBody StatementsDTO StatementsDTO)
{....}
I would like to test this method. I am using Spring MVC and in my test class, I am using MockMVC.
When I try writing the method:
mockMvc.perform(post("/migration/sendStatements")); I don't get an option to add a request body. I want to add a request body to this endpoint. How do i do this?

Add request body using content method
String requestBody = "{.... }";
mockMvc.perform(post("/migration/sendStatements")
.content(requestBody));

Related

How can i explicitly check request content-type is matching with actual content in Spring boot?

I want to validate my request content-type is matching with my request body or not?
I am trying to implement the OWASP Rest security standard.
Which says :
13.2.5 Verify that REST services explicitly check the incoming Content-Type to be the expected one, such as application/XML or application/JSON.
In the below image the content type is JSON but the request is in XML.Still it's working fine.
My Controller code:-
#RestController
public class TestController {
#PostMapping(path="/hello",consumes = "application/json")
public Map<String,String> hello(Master ecm){
Map<String,String> m=new HashMap<>() ;
m.put("message", "hello!");
return m;
}
}
Spring annotations provide a specific attribute for that. It is called consumes.
Here is an example
#PostMapping(consumes = MediaType.SELECT_TYPE_HERE)
specific example
#PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)

Using Swagger(2.9.2) in GET operation in a SpringBoot #RestController that takes a #queryParam(optional parameter)

#ApiOperation(value = "Get list of Emp", response = ResponseEntity.class)
#GetMapping(path = "/getEmployees")
public ResponseEntity<Set<Employees>> getEmployees(#QueryParam("emp") String lastName) {}
**I have a GET operation in a SpringBoot #RestController that takes a query param. If I use Swagger UI, it throws an error that TypeError: Request has method 'GET' and cannot have a body. But if I change it to post it works considering the body is allowed in POST calls. How should I access query param in GET inside swagger? Not using curl. if I use Use Spring's RequestParam instead of Jersey QueryParam, it's no more optional, which I do not want **

Parsing JSON request body with Spring MVC

I am using Spring 4.1 framework for developing webservices. When I return a Java object as response, it is automatically converted to JSON and delivered to client, so I assume that JSON parser is in classpath and it is configured properly. However it fails to convert the request body from JSON into Java object and client is getting a HTTP response of 400.
Here is how the webservice looks like:
public class Details{
public Details(){
}
int code;
int area;
}
#RequestMapping(value = "/api/update/{phoneNumber}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> update(#PathVariable final String phoneNumber, #RequestBody Details details)
Here is how the request looks like:
Method: Post
Content-Type: application/json; charset=utf-8
Body: {"code":0,"area":12}
If I collect the request body as string and parse it manually then it works, so it gets the valid JSON but for some reason it is not parsing it automatically. I have no clue on how to fix it. Please help. Thanks in advance.
You have package-private properties in your Details class, so they are probably not recognised by json-converter.
You have several options:
define them as public (not recommended)
provide getters and setters
if you are using jackson, you can annotate them with #JsonProperty, leaving them package-private
Finally I got the reason for this. I was using inner classes which were not static. Making those static fixed the issue.

Spring MVC REST - Block access to Web Methods

I have this method in my Controller that returns a json string to the view
#RequestMapping(value = "/getDevs", method=RequestMethod.GET)
public#ResponseBody String getDevs() throws JsonProcessingException,RemoteException,ServiceException{
ObjectMapper om = new ObjectMapper();
return om.writeValueAsString(WSCall.getDevelopers());
}
I call the method URL using ajax. Everything works fine except I can obtain the json if I put the URL directly in the browser. Is there a way to block this?
I agree with the comments above, that it is not relevant from a security standpoint, but you could probably make use of the X-Requested-With: XMLHttpRequest header that is most likely set for your AJAX requests. I can at least confirm it for jQuery, which might be on your tool stack.
So you could add the headers parameter to your #RequestMapping annotation:
#RequestMapping(value = "/getDevs", method=RequestMethod.GET, headers = { "X-Requested-With=XMLHttpRequest" })
public#ResponseBody String getDevs() throws JsonProcessingException,RemoteException,ServiceException{
[...]
}

Alternative of #RequestBody

Is there an alternative way to obtain a reference to a request's body without using the approach with the annotation? I'm using GAE + Spring and everytime I use #RequestBody in the signatures of my controller methods, the server returns 415 Unsupported Media Type. All I'm trying to do is read a JSON encoded message on a Post method. Thanks.
You can take in a parameter of HttpServletRequest, and read the ServletInputStream using getInputStream() from there. The stream will contain the body of the request.
#Controller
public class MyController {
#RequestMapping("/test")
public String aTest(HttpServletRequest request) {
InputStream body = request.getInputStream();
//process request body
return myReturnVal;
}
}
Try this, on the RequestMapping configure the headers to accept application/json and be sure to configure a jackson message convertor for this type

Resources