Is it necessary to wrap in a backing object? I want to do this:
#RequestMapping(value = "/Test", method = RequestMethod.POST)
#ResponseBody
public boolean getTest(#RequestBody String str1, #RequestBody String str2) {}
And use a JSON like this:
{
"str1": "test one",
"str2": "two test"
}
But instead I have to use:
#RequestMapping(value = "/Test", method = RequestMethod.POST)
#ResponseBody
public boolean getTest(#RequestBody Holder holder) {}
And then use this JSON:
{
"holder": {
"str1": "test one",
"str2": "two test"
}
}
Is that correct? My other option would be to change the RequestMethod to GET and use #RequestParam in query string or use #PathVariable with either RequestMethod.
While it's true that #RequestBody must map to a single object, that object can be a Map, so this gets you a good way to what you are attempting to achieve (no need to write a one off backing object):
#RequestMapping(value = "/Test", method = RequestMethod.POST)
#ResponseBody
public boolean getTest(#RequestBody Map<String, String> json) {
//json.get("str1") == "test one"
}
You can also bind to Jackson's ObjectNode if you want a full JSON tree:
public boolean getTest(#RequestBody ObjectNode json) {
//json.get("str1").asText() == "test one"
You are correct, #RequestBody annotated parameter is expected to hold the entire body of the request and bind to one object, so you essentially will have to go with your options.
If you absolutely want your approach, there is a custom implementation that you can do though:
Say this is your json:
{
"str1": "test one",
"str2": "two test"
}
and you want to bind it to the two params here:
#RequestMapping(value = "/Test", method = RequestMethod.POST)
public boolean getTest(String str1, String str2)
First define a custom annotation, say #JsonArg, with the JSON path like path to the information that you want:
public boolean getTest(#JsonArg("/str1") String str1, #JsonArg("/str2") String str2)
Now write a Custom HandlerMethodArgumentResolver which uses the JsonPath defined above to resolve the actual argument:
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.jayway.jsonpath.JsonPath;
public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver{
private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
#Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JsonArg.class);
}
#Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String body = getRequestBody(webRequest);
String val = JsonPath.read(body, parameter.getMethodAnnotation(JsonArg.class).value());
return val;
}
private String getRequestBody(NativeWebRequest webRequest){
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
String jsonBody = (String) servletRequest.getAttribute(JSONBODYATTRIBUTE);
if (jsonBody==null){
try {
String body = IOUtils.toString(servletRequest.getInputStream());
servletRequest.setAttribute(JSONBODYATTRIBUTE, body);
return body;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return "";
}
}
Now just register this with Spring MVC. A bit involved, but this should work cleanly.
For passing multiple object, params, variable and so on. You can do it dynamically using ObjectNode from jackson library as your param. You can do it like this way:
#RequestMapping(value = "/Test", method = RequestMethod.POST)
#ResponseBody
public boolean getTest(#RequestBody ObjectNode objectNode) {
// And then you can call parameters from objectNode
String strOne = objectNode.get("str1").asText();
String strTwo = objectNode.get("str2").asText();
// When you using ObjectNode, you can pas other data such as:
// instance object, array list, nested object, etc.
}
I hope this help.
You can mix up the post argument by using body and path variable for simpler data types:
#RequestMapping(value = "new-trade/portfolio/{portfolioId}", method = RequestMethod.POST)
public ResponseEntity<List<String>> newTrade(#RequestBody Trade trade, #PathVariable long portfolioId) {
...
}
The easy solution is to create a payload class that has the str1 and the str2 as attributes:
#Getter
#Setter
public class ObjHolder{
String str1;
String str2;
}
And after you can pass
#RequestMapping(value = "/Test", method = RequestMethod.POST)
#ResponseBody
public boolean getTest(#RequestBody ObjHolder Str) {}
and the body of your request is:
{
"str1": "test one",
"str2": "two test"
}
#RequestParam is the HTTP GET or POST parameter sent by client, request mapping is a segment of URL which's variable:
http:/host/form_edit?param1=val1¶m2=val2
var1 & var2 are request params.
http:/host/form/{params}
{params} is a request mapping. you could call your service like : http:/host/form/user or http:/host/form/firm
where firm & user are used as Pathvariable.
Instead of using json, you can do simple thing.
$.post("${pageContext.servletContext.contextPath}/Test",
{
"str1": "test one",
"str2": "two test",
<other form data>
},
function(j)
{
<j is the string you will return from the controller function.>
});
Now in the controller you need to map the ajax request as below:
#RequestMapping(value="/Test", method=RequestMethod.POST)
#ResponseBody
public String calculateTestData(#RequestParam("str1") String str1, #RequestParam("str2") String str2, HttpServletRequest request, HttpServletResponse response){
<perform the task here and return the String result.>
return "xyz";
}
Hope this helps you.
I have adapted the solution of Biju:
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver{
private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
private ObjectMapper om = new ObjectMapper();
#Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JsonArg.class);
}
#Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String jsonBody = getRequestBody(webRequest);
JsonNode rootNode = om.readTree(jsonBody);
JsonNode node = rootNode.path(parameter.getParameterName());
return om.readValue(node.toString(), parameter.getParameterType());
}
private String getRequestBody(NativeWebRequest webRequest){
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
String jsonBody = (String) webRequest.getAttribute(JSONBODYATTRIBUTE, NativeWebRequest.SCOPE_REQUEST);
if (jsonBody==null){
try {
jsonBody = IOUtils.toString(servletRequest.getInputStream());
webRequest.setAttribute(JSONBODYATTRIBUTE, jsonBody, NativeWebRequest.SCOPE_REQUEST);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return jsonBody;
}
}
What's the different:
I'm using Jackson to convert json
I don't need a value in the annotation, you can read the name of the
parameter out of the MethodParameter
I also read the type of the parameter out of the Methodparameter => so the solution should be generic (i tested it with string and DTOs)
BR
Not sure where you add the json but if i do it like this with angular it works without the requestBody:
angluar:
const params: HttpParams = new HttpParams().set('str1','val1').set('str2', ;val2;);
return this.http.post<any>( this.urlMatch, params , { observe: 'response' } );
java:
#PostMapping(URL_MATCH)
public ResponseEntity<Void> match(Long str1, Long str2) {
log.debug("found: {} and {}", str1, str2);
}
You can also use a MultiValue Map to hold the requestBody in.
here is the example for it.
foosId -> pathVariable
user -> extracted from the Map of request Body
unlike the #RequestBody annotation when using a Map to hold the request body we need to annotate with #RequestParam
and send the user in the Json RequestBody
#RequestMapping(value = "v1/test/foos/{foosId}", method = RequestMethod.POST, headers = "Accept=application"
+ "/json",
consumes = MediaType.APPLICATION_JSON_UTF8_VALUE ,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
#ResponseBody
public String postFoos(#PathVariable final Map<String, String> pathParam,
#RequestParam final MultiValueMap<String, String> requestBody) {
return "Post some Foos " + pathParam.get("foosId") + " " + requestBody.get("user");
}
Use an inner class
#RestController
public class MyController {
#PutMapping("/do-thing")
public void updateFindings(#RequestBody Bodies.DoThing body) {
...
}
private static class Bodies {
public static class DoThing {
public String name;
public List<String> listOfThings;
}
}
}
request parameter exist for both GET and POST ,For Get it will get appended as query string to URL but for POST it is within Request Body
Good.
I suggest creating a Value Object (Vo) that contains the fields you need. The code is simpler, we do not change the functioning of Jackson and it is even easier to understand.
Regards!
You can achieve what you want by using #RequestParam. For this you should do the following:
Declare the RequestParams parameters that represent your objects and set the required option to false if you want to be able to send a null value.
On the frontend, stringify the objects that you want to send and include them as request parameters.
On the backend turn the JSON strings back into the objects they represent using Jackson ObjectMapper or something like that, and voila!
I know, its a bit of a hack but it works! ;)
you can also user #RequestBody Map<String, String> params,then use params.get("key") to get the value of parameter
If somebody is interested in the webflux solution, below is a reactive version, based on Biju answer.
Please note that there is one very small but synchronized chunk, needed to protect the body from being consumed more than once. If you prefer a fully non-blocking version, I suggest publishing the flux that obtains json on the same scheduler, to make checking and reading sequential.
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.web.reactive.BindingContext;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
#Slf4j
#RequiredArgsConstructor
public class JsonArgumentResolver implements HandlerMethodArgumentResolver {
private static final String ATTRIBUTE_KEY = "BODY_TOSTRING_RESOLVER";
private final ObjectMapper objectMapper;
#Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JsonArgument.class);
}
#Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
String fieldName = parameter.getParameterName();
Class<?> clz = parameter.getParameterType();
return getRequestBody(exchange).map(body -> {
try {
JsonNode jsonNode = objectMapper.readTree(body).get(fieldName);
String s = jsonNode.toString();
return objectMapper.readValue(s, clz);
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
});
}
private Mono<String> getRequestBody(ServerWebExchange exchange) {
Mono<String> bodyReceiver;
synchronized (exchange) {
bodyReceiver = exchange.getAttribute(ATTRIBUTE_KEY);
if (bodyReceiver == null) {
bodyReceiver = exchange.getRequest().getBody()
.map(this::convertToString)
.single()
.cache();
exchange.getAttributes().put(ATTRIBUTE_KEY, bodyReceiver);
}
}
return bodyReceiver;
}
private String convertToString(DataBuffer dataBuffer) {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
return new String(bytes, StandardCharsets.UTF_8);
}
}
I've JSON message coming in from rabbitmq and has the following format:
{
messageId: 123,
content: {
id: "P123456",
status: false,
error: {
description: "Something has gone wrong",
id: 'E400'
}
}
}
As you can see, the message has a few nested objects within them.
When this message comes in, I will serialise it using Jackson. Right now, however, I have to create multiple classes just for one single message.
In the example message above, I have to create 3 classes just for serialising and transforming it into a class MainMessage, like so:
public class MainMessage {
private int messageId;
private MessageContentObject content;
// getters/setters...
}
public class MessageContentObject {
private String id;
private boolean status;
private MessageErrorObject error;
// getters/setters...
}
public class MessageErrorObject {
private String description;
private string id;
// getters/setters...
}
This feels very cumbersome because in some of the messages, the nesting can be pretty deep and I will have to create a lot of classes just for the purpose of having the JSON payload transformed into the MainMessage class object. The MessageContentObject and MessageErrorObject are mostly redundant because I will never use the classes directly anywhere else in the code. I would still the values in them through MainMessage though, for example:
#RabbitListener
public void consumeMessage(MainMessage msg) {
System.out.println(msg.getContent().getError().getDescription());
}
I'm using Spring with Spring Boot.
Is this really the only way I can do when it comes to dealing with nested JSON payloads?
First, when the message comes in you Deserialize it.
Now, if you don't want to create the whole data structure to look like your incoming JSON, you can go for a Map like this
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Collections;
import java.util.Map;
public class Message {
private final Map<String, Object> details;
#JsonCreator // Deserialize the JSON using this creator
public Message(final Map<String, Object> details) {
super();
this.details = details;
}
#JsonAnyGetter // Serialize this class using the data from the map
public Map<String, Object> getDetails() {
return Collections.unmodifiableMap(details);
}
}
In this way, you won't need to change your Message class every time your incoming JSON changes.
However, this approach is useful only when you'll not be manipulating the data too much.
if you don't want to create the whole data structure or you only need a small portion of the response recieved at a time you can use Jackson JsonNode
import com.fasterxml.jackson.databind.JsonNode;
public class Message {
private JsonNode messageDetails;
/**
* Constructor used to transform your object into jsonNode.
*
* #param messageDetailsResponse
*/
public Message(Object messageDetailsResponse) {
this.messageDetails = JsonUtils.getNode(messageDetailsResponse);
}
//Simply create getters for accessing the data you want when you want it
public String getId() {
return messageDetails.findValue("messageId").asText();
}
//You can also use it later to map a portion of response to an model class
public Content getContent(){
return JsonUtils.fromJsonNode(messageDetails.get("content"),Content.class)
}
}
The Code for JsonUtils
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
#Slf4j
final public class JsonUtils {
/**
* The Object Mapper constant to deal with JSON to/from conversion activities.
*/
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public static JsonNode getNode(Object anyObject) {
try {
return OBJECT_MAPPER.readTree(OBJECT_MAPPER.writeValueAsBytes(anyObject));
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
public static <T> T fromJsonNode(final JsonNode node, final Class<T> clazz)
throws JsonProcessingException {
return OBJECT_MAPPER.treeToValue(node, clazz);
}
Some suggestions:
Consider using Lombok to reduce the code you need to write (getters setters etc.) - will make creating classes less of a problem.
Consider using static inner classes - will mean you need less files.
If you still prefer to not write your classes down, you can deserealise to a String and traverse it using Gson or similar libraries.
I am a begineer in java development but has previous experience on programming languages like PHP and Python. So little confused on how to proceed on spring boot with the development.
I am developing a rest API which has the following request
{
"key":"value",
"key1":"value1",
"platform_settings":[
{"key":"value"}
]
}
What I did
I created a RestController which accepts the http request and created a function for the resource
public Share share(#RequestBody final Share share) {
LOGGER.debug("This is the request", share);
return share; //
}
Question 1 : If it was any other programming language like PHP or Python, there will be helper function which will accept the json request and convert it to object which I can easily work on.
In python it is as simple as
import json
import requests
response = requests.get(...)
json_data = json.loads(response.text)
//can work on json_data anyway I want.
But in java, I will have to create a POJO class, or have jackson/JPA entity as dependency which will map the request to a Class (Which I should predefine with the requests).
Is there any better way I can do this? For every request I make, I will have to create a Class which the request can be mapped to and I will have to define the class
Entity
package com.payunow.socialsharemodule.models;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Share {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String key;
private String key1;
private Map<String,String> platform_settings;
public Share(String name, String description,Map<String,String> platform_settings) {
this.key = key;
this.key1 = key1;
this.platform_settings = platform_settings;
}
//for JPA
public Share() {}
public String getKey() {
return key;
}
public String getKey1() {
return key1;
}
public Map<String,String> getPlatform_settings() {
return platform_settings;
}
}
For every request I make, I will have to create a class defining all its variables inside. Is this the only way to do this?
You need to have Jackson dependecy for coversion of json to java object. But spring provides it by default, so you don't have to add it explicitly.
You don't need a JPA Entity. This is needed only when you want to store the recieved data into database.
Just to recieve the request you don't have to create a separate pojo class. Look at this code
#PostMapping("/json")
public JSONObject getGeneric(#RequestBody String stringToParse){
JSONParser parser = new JSONParser();
JSONObject json = null;
try {
json = (JSONObject) parser.parse(stringToParse);
} catch (ParseException e) {
e.printStackTrace();
}
return json;
}
As you can see here it takes a string as a request and converts it into a generic JSONObject. So basically you can pass any json to this endpoint.
You CanUse ObjectMapper class it has methods like convertValue and realValue..
I am trying to return {"status": its value}´in the case of routeD!=0 currently I am getting {"status":201,"routes":null} I would get the response in this form {"status":201} without "routes":null at the same time I dont want to lost the response of routeD==0 which is for example {"status":230,"routes":[1,9,3]}
I appeciate any help.
Receiver class:
#Path("/data")
public class Receiver {
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response storeData(Data data) {
Database db = new Database();
String macD = data.getMac();
int routeD = data.getRoute();
double latD = data.getLatitude();
double longD = data.getLongitude();
double speedD = data.getSpeed();
// Jackson class to wrapper the data in JSON string.
SDBean bean = new SDBean();
if (routeD != 0) {
bean.status = db.insertData(macD, routeD, latD, longD);
return Response.status(bean.status).entity(bean.toJson()).build();
} else {
bean.routes = db.detectRoute(latD, longD);
return Response.status(230).entity(bean.toJson()).build();
}
}
}
SDBean class:
public class SDBean {
public int status;
public ArrayList<Integer> routes;
public SDBean(){
status = 230;
}
public String toJson() {
ObjectMapper mapper = new ObjectMapper();
String json = null;
try {
json = mapper.writeValueAsString(this);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(json);
return json;
}
}
Just use #JsonInclude(JsonInclude.Include.NON_NULL)
Annotation used to indicate when value of the annotated property (when used for a field, method or constructor parameter), or all properties of the annotated class, is to be serialized. Without annotation property values are always included, but by using this annotation one can specify simple exclusion rules to reduce amount of properties to write out.
import com.fasterxml.jackson.annotation.JsonInclude;
[...]
#JsonInclude(JsonInclude.Include.NON_NULL)
public class SDBean {
I have
#RequestMapping(method = RequestMethod.GET)
#ResponseBody
SessionInfo register(UserProfile profileJson){
...
}
I pass profileJson this way:
http://server/url?profileJson={"email": "mymail#gmail.com"}
but my profileJson object has all null fields. What should I do to make spring parse my json?
The solution to this is so easy and simple it will practically make you laugh, but before I even get to it, let me first emphasize that no self-respecting Java developer would ever, and I mean EVER work with JSON without utilizing the Jackson high-performance JSON library.
Jackson is not only a work horse and a defacto JSON library for Java developers, but it also provides a whole suite of API calls that makes JSON integration with Java a piece of cake (you can download Jackson at http://jackson.codehaus.org/).
Now for the answer. Assuming that you have a UserProfile pojo that looks something like this:
public class UserProfile {
private String email;
// etc...
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
// more getters and setters...
}
...then your Spring MVC method to convert a GET parameter name "profileJson" with JSON value of {"email": "mymail#gmail.com"} would look like this in your controller:
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper; // this is your lifesaver right here
//.. your controller class, blah blah blah
#RequestMapping(value="/register", method = RequestMethod.GET)
public SessionInfo register(#RequestParam("profileJson") String profileJson)
throws JsonMappingException, JsonParseException, IOException {
// now simply convert your JSON string into your UserProfile POJO
// using Jackson's ObjectMapper.readValue() method, whose first
// parameter your JSON parameter as String, and the second
// parameter is the POJO class.
UserProfile profile =
new ObjectMapper().readValue(profileJson, UserProfile.class);
System.out.println(profile.getEmail());
// rest of your code goes here.
}
Bam! You're done. I would encourage you to look through the bulk of Jackson API because, as I said, it is a lifesaver. For example, are you returning JSON from your controller at all? If so, all you need to do is include JSON in your lib, and return your POJO and Jackson will AUTOMATICALLY convert it into JSON. You can't get much easier than that. Cheers! :-)
This could be done with a custom editor, that converts the JSON into a UserProfile object:
public class UserProfileEditor extends PropertyEditorSupport {
#Override
public void setAsText(String text) throws IllegalArgumentException {
ObjectMapper mapper = new ObjectMapper();
UserProfile value = null;
try {
value = new UserProfile();
JsonNode root = mapper.readTree(text);
value.setEmail(root.path("email").asText());
} catch (IOException e) {
// handle error
}
setValue(value);
}
}
This is for registering the editor in the controller class:
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(UserProfile.class, new UserProfileEditor());
}
And this is how to use the editor, to unmarshall the JSONP parameter:
#RequestMapping(value = "/jsonp", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
#ResponseBody
SessionInfo register(#RequestParam("profileJson") UserProfile profileJson){
...
}
You can create your own Converter and let Spring use it automatically where appropriate:
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
#Component
class JsonToUserProfileConverter implements Converter<String, UserProfile> {
private final ObjectMapper jsonMapper = new ObjectMapper();
public UserProfile convert(String source) {
return jsonMapper.readValue(source, UserProfile.class);
}
}
As you can see in the following controller method nothing special is needed:
#GetMapping
#ResponseBody
public SessionInfo register(#RequestParam UserProfile userProfile) {
...
}
Spring picks up the converter automatically if you're using component scanning and annotate the converter class with #Component.
Learn more about Spring Converter and type conversions in Spring MVC.
This does solve my immediate issue, but I'm still curious as to how you might pass in multiple JSON objects via an AJAX call.
The best way to do this is to have a wrapper object that contains the two (or multiple) objects you want to pass. You then construct your JSON object as an array of the two objects i.e.
[
{
"name" : "object1",
"prop1" : "foo",
"prop2" : "bar"
},
{
"name" : "object2",
"prop1" : "hello",
"prop2" : "world"
}
]
Then in your controller method you recieve the request body as a single object and extract the two contained objects. i.e:
#RequestMapping(value="/handlePost", method = RequestMethod.POST, consumes = { "application/json" })
public void doPost(#RequestBody WrapperObject wrapperObj) {
Object obj1 = wrapperObj.getObj1;
Object obj2 = wrapperObj.getObj2;
//Do what you want with the objects...
}
The wrapper object would look something like...
public class WrapperObject {
private Object obj1;
private Object obj2;
public Object getObj1() {
return obj1;
}
public void setObj1(Object obj1) {
this.obj1 = obj1;
}
public Object getObj2() {
return obj2;
}
public void setObj2(Object obj2) {
this.obj2 = obj2;
}
}
Just add #RequestBody annotation before this param