Spring RequestBody with either List<Object> or Object. Name for both are same "data"
EDIT
You can create DTOs for your inputs but receive the @RequestBody
as a JSON string and then parse it as a list or a single object request.
DTO for a request list:
public class InputDataList {
private List<Input> data;
// getters and setters
}
DTO for a single request object:
public class InputDataSingle {
private Input data;
// getters and setters
}
Then on your controller:
@PostMapping(path="/path")
public @ResponseBody String getSomething(@RequestBody String json){
// this is better done in a service but for simplicity, I write it in the controller
try {
InputDataSingle data = new ObjectMapper().readValue(json, InputDataSingle.class);
// If fails to parse as a single object, parse as a list
} catch (Exception) (
InputDataList data = new ObjectMapper().readValue(json, InputDataList.class);
}
// handle objects in the service layer
}
Is it possible to split request params in Spring controllers?
Yes, you can certainly do that, you're almost there.
@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<MyResponse> participants(@RequestParam("sort") List<String> sort) {
//...
}
You should now be able to call your service like this (if search is located at your root, otherwise adapt according to your situation):
curl "localhost:8080/search?sort=sortField1&sort=sortField2&sort=sortField3"
Hope this helps!
EDIT
Sorry, I have read your comments and what you need is clear to me now. I have created a workaround for you that is almost what you want I think.
So first a SortParams class:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SortParams {
private List<SortParam> sortParamList;
public SortParams(String commaSeparatedString) {
sortParamList = Arrays.stream(commaSeparatedString.split(","))
.map(p -> SortParam.valueOf(p))
.collect(Collectors.toList());
}
public List<SortParam> getSortParamList() {
return this.sortParamList;
}
public enum SortParam {
FOO, BAR, FOOBAR;
}
}
Then your controller could look like this:
@RequestMapping(value = "/search", method = RequestMethod.GET)
public ResponseEntity<List<SortParams.SortParam>> search(@RequestParam("sort") SortParams sort) {
return ResponseEntity.ok(sort.getSortParamList());
}
Now your SortParams object has a list of SortParam:
curl "localhost:8080/search?sort=FOO,BAR"
["FOO","BAR"]
Would something like this fit what you're looking for?
SpringBoot: Using @RequestParam and @RequestBody together
The problem was the content encoding of the incoming request. Changing the curl command to
curl -H "Content-Type: application/json" -d '{ "name": "Joe Bloggs" }' http://localhost:8080/test?debug=Y
Resulted in my output showing
debug=N
json={ "name": "Joe Bloggs" }
How to accept RequestBody of different class types dynamically
You could do this by passing the JSON as a String into your controller method and then mapping this to whichever object you expect to need:
@PostMapping(value = "/myservice/{type}")
public ResponseEntity<?> myServiceApi(@PathVariable String type,
@RequestBody String somereq) {
ObjectMapper mapper = new ObjectMapper();
if (<something that indicates SomeClass1>) {
SomeClass1 someClass1 = mapper.readValue(somereq, SomeClass1.class);
} else if (<something that indicates SomeClass2>) {
SomeClass2 someClass2 = mapper.readValue(somereq, SomeClass2.class);
}
}
Although to be honest if you really are expecting bodies with completely different structures my advice would be to just make separate API calls for these.
Do I need a separate object for every @RequestBody in Spring Boot
Create a new entity if you will persist or operate on it
If you need a custom view for existing entity (add/remove fields) DTO with custom serialization can be used
There maybe a case when you don't want to create DTO because you will not reuse it anywhere, but need some quick solution for custom response you can use Map<String, Object> - the key will be used for JSON field name, and Object is for the value, for example:
@RequestMapping(method = RequestMethod.POST)
public Map<String, Object> login(@RequestParam Integer p1) {
Map<String, Object> map = new HashMap<>();
map.put("p1", p1);
map.put("somethingElse", "456");
return map;
}
JSON response:
{
"p1": p1value,
"somethingElse": "456"
}
3rd case will suite you if you're not building too complex bodies with nested objects which should be customized based on some conditions. Use 2nd option in the opposite case.
@RequestBody, sending in List<String> in POST request
"tags": [{"Tag 1"}, {"Tag 2"}]
correspond to an array of object, not an array of String that should be represented like :
"tags": ["Tag 1", "Tag 2"]
Either change the client side to send an array of String : "tags": ["Tag 1", "Tag 2"]
.
Otherwise, change the client side and the backend side to declare a List that is parameterized with a custom class that will contain the String value.
Json to send :
"tags": [{"value": "Tag 1"}, {"value": "Tag 2"}]
mapping in the back end :
private List<MyObject> tags;
Where MyObject
could be declared :
public class MyObject{
private String value;
... // getter - setter
}
Related Topics
Get Current Week Start and End Date in Java - (Monday to Sunday)
Java Sorting a 2D Array Rows into Ascending and Columns into Descending Order
How to Replace a Placeholder in a String With a Simpledateformat Pattern
How to Mock Classes With Constructor Injection
How to Have Empty Requestparam Values Use the Defaultvalue
How to Return a Select Query from JPA Repository With Foreign Key Type
Get Requestbody and Responsebody At Handlerinterceptor
Netbeans Tomcat Build Failed - the Module Has Not Been Deployed
Java - Check If Jtextfield Is Empty or Not
Can We Use Multipart and @Requestbody Together in Spring
How to Get a List of All the Implementations of an Interface Programmatically in Java
How to Import Two Classes With the Same Name in Different Packages
Spring Rest Handling Empty Request Body (400 Bad Request)