Spring Boot using Json as request parameters instead of an entity/model

11,236

Solution 1

In that case you can use Map class to read input json, like

@PostMapping("/create")
public Object create(@RequestBody Map<String, ?> input) {
     sout(input.get("param1")) // cast to String, int, ..
}

Solution 2

I actually figured out a more straightforward solution.

Apparently this works:

@PostMapping("/endpoint")
public Object endpoint(@RequestBody MyWebRequestObject request) {
    String value1 = request.getValue_1();
    String value2 = request.getValue_2();
}

The json payload is this:

{
   "value_1" : "hello",
   "value_2" : "world"
}

This works if MyRequestObject is mapped like the json request object like so. Example:

public class MyWebRequestObject {
   String value_1;
   String value_2
}

Unmapped values are ignored. Spring is smart like that.

I know this is right back where I started but since we introduced a service layer for the rest control to interact with, it made sense to create our own request model object (DTOs) that is separate from the persistence model.

Share:
11,236

Related videos on Youtube

Chad
Author by

Chad

Java Programmer for 15 years. PHP Developer for 7 years. Javascript Developer On and off through the years. Recently delving into DenoJs and Javascript-based Microservices. I wasn't a corporate slave when doing PHP. Went on to be a drone and long commuter as a Java Dev. I am agnostic to technology or at least I try to be. I believe that every technology out there is a tool that must be understood before it can be used.

Updated on June 04, 2022

Comments

  • Chad
    Chad almost 2 years

    Our company is planning to switch our microservice technology to Spring Boot. As an initiative I did some advanced reading and noting down its potential impact and syntax equivalents. I also started porting the smallest service we had as a side project.

    One issue that blocked my progress was trying to convert our Json request/response exchange to Spring Boot.

    Here's an example of the code: (This is Nutz framework for those who don't recognize this)

    @POST
    @At // These two lines are equivalent to @PostMapping("/create")
    @AdaptBy(type=JsonAdapter.class)
    public Object create(@Param("param_1") String param1, @Param("param_2) int param2) {
        MyModel1 myModel1 = new MyModel1(param1);
        MyModel2 myModel2 = new MyModel2(param2);
        myRepository1.create(myMode12);
        myRepository2.create(myModel2);
        return new MyJsonResponse();
    }
    

    On PostMan or any other REST client I simply pass POST:

    {
        "param_1" : "test",
        "param_2" : 1
    }
    

    I got as far as doing this in Spring Boot:

    @PostMapping("/create")
    public Object create(@RequestParam("param_1") String param1, @RequestParam("param_2) int param2) {
        MyModel1 myModel1 = new MyModel1(param1);
        MyModel2 myModel2 = new MyModel2(param2);
        myRepository1.create(myMode12);
        myRepository2.create(myModel2);
        return new MyJsonResponse();
    } 
    

    I am not sure how to do something similar as JsonAdapter here. Spring doesn't recognize the data I passed.

    I tried this but based on the examples it expects the Json paramters to be of an Entity's form.

    @RequestMapping(path="/wallet", consumes="application/json", produces="application/json")
    

    But I only got it to work if I do something like this:

    public Object (@RequestBody MyModel1 model1) {}
    

    My issue with this is that MyModel1 may not necessarily contain the fields/parameters that my json data has.

    The very useful thing about Nutz is that if I removed JsonAdapter it behaves like a regular form request endpoint in spring.

    I couldn't find an answer here in Stack or if possible I'm calling it differently than what existing spring devs call it.

    Our bosses expect us (unrealistically) to implement these changes without forcing front-end developers to adjust to these changes. (Autonomy and all that jazz). If this is unavoidable what would be the sensible explanation for this?

  • Chad
    Chad about 6 years
    My goal is to AVOID using a model in the method parameters (I want native data types). The JsonIgnore parameter is if I don't want to use a field. My problem is the method signature might contain parameters that model doesn't have.
  • HanByul Lee
    HanByul Lee about 6 years
    I'm sorry for my misunderstanding. I think the only thing you can do without @RequestBody MyModel1 is to write all required parameters with @RequestParam. However, can't you achieve your goal by using a class properly implements Converter?
  • Chad
    Chad about 6 years
    I’m actually fine if what I am expecting from spring can’t be done. It’s just that I have to have a good reason to tell my bosses why not. ;)
  • HanByul Lee
    HanByul Lee about 6 years
    I see. You have already known a good reason by experiencing those, don't you? Actually I don't know about Nutz and exact logic performed by JsonAdapter, but @RequestParam can bind one parameter and @RequestBody can bind all parameters along with spring framework. I'm afraid of doing no help. Good luck!
  • Chad
    Chad about 6 years
    I"m going to give this a shot now.
  • Chad
    Chad about 6 years
    I confirm this works as I wanted. Thanks for this. I'll continue exploring possibilities with this. One last thing though. What else can I do with the RequestBody aside from Map?