1

Let's assume there's a following Java-file, Foo.java:

public class Foo {
     private String first;
     private String second;
     private String third;

     public Foo(){
     }
     public Foo(String first, String second, String third){
          this.first = first;
          this.second = second;
          this.third = third;
     }
     public String getFirst(){
          return first;
     }
     public String getSecond(){
          return second;
     }
     public String getThird(){
          return third;
     }
     public void setFirst(String first){
          this.first = first;
     }
     public void setSecond(String second){
          this.second = second;
     }
     public void setThird(String third){
          this.third = third;
     }
}

Then there's another file, RESTcontroller.java:

import Bar;
import Foo;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/rest")
public class RESTController {
    @RequestMapping(path = "/getFoo", method = RequestMethod.GET)
    public void getFoo(Foo foo, HttpServletResponse response) {
        Bar bar = Bar.getBar(foo)
        ...
    }
}

Then in third file, http.js the 'getFoo' endpoint is called:

class Http {
    getFoo(url, first, third) {
        return `${url}getFoo?first=${first}&third=${third}`;
    }
}

So, the question is, how the query parameters are used to construct the Foo parameter, when the second parameter needed in the Foo-constructor is missing? Which of the two constructors is used and at which point? Does this have something to do with Spring-framework? The example codes here are a version of code that has been proven to function.

3
  • Did you try putting a breakpoint in the constructors and see which one gets hit? This would also answer all of your other questions. Since you could see what it was being called with to answer the 'how query parameters are used'. And the stack trace would tell you whether it was spring doing it or not. Commented Oct 8, 2019 at 10:08
  • Spring framework does not care about the non-default constructors at this kind of scenario. It always uses the default constructor to create the object and then uses the setter methods to set the provided values. Commented Oct 8, 2019 at 10:09
  • I'm in a situation whre it's really difficult to test the code, especially locally (impossible). I'm more interested in the theory behind this Spring REST syntax, and how the query parameters are used to construct the Foo-parameter and where? There's no Spring annotations other than RestController and RequestMapping. Commented Oct 8, 2019 at 10:17

5 Answers 5

2

It all have to do with Spring (or more precisely the Spring hidden configuration magic).

The org.springframework.web.method.support.HandlerMethodArgumentResolver resolved run-time implementation is the component responsible of transforming request parameters into an object, a process called parameter mapping.

In the described example, what the resolver will use is the no-arg constructor along with the setters holding the received parameters names, i.e., setFirst and setThird

The 3 arg constructor is never called, and all your POJO needs to implement is a standard no-argument constructor and setters and getters for the instance variables.

Sign up to request clarification or add additional context in comments.

Comments

0

You got the rest thing wrong - using GET rest method is not used to construct an object, but to simply retrieve it from the service/db.

In this case, the query params that can be used are such that will decide which objects to return (by its id or other parameters). You do not need to pass the foo object to the method, as GET usually don't have a request body

So the get method will look something like:

// all items
@RequestMapping(path = "/foo", method = RequestMethod.GET)
public List<Foo> getFoos() {
    return fooService.getAll();
}

// single item
@RequestMapping(path = "/foo/{id}", method = RequestMethod.GET)
public Foo getFoos(@PathParam String id) {
    return fooService.getByid(id);
}

for constructing new objects, you should use POST method, and it is better to pass the new object as a json in the request's body. it will be passed to the controller method as an parameter:

@RequestMapping(path = "/foo", method = RequestMethod.POST)
public Foo createFoo(@RequestBody Foo foo) {
    return fooService.save(foo);
}

And one last thing, the convention when using REST is to use the same path, i.e. /foo, and the rest method will determine if it's create (POST), update (PUT) or get (GET). You don't need to call your path /getFoo

3 Comments

The Foo argument is a search object based on the query parameters received. This is a perfectly sensible pattern.
@user2478398 - get method returning void is not sensible pattern in rest
The method has the HttpServletResponse as an argument. He could be writing whatever headers/body he wants to it. It's not the best way to do it, but just because the method's void doesn't mean it's not returning data.
0

The constructor being used is the default one (no args). And yes, Spring is setting the values of your fields.

Comments

0

I don't understand exactly what you mean, but I understand that RequestBody is the default.

@RequestBody Foo foo same thing. For Example,

  • @PathVariable => `${SERVER_URL}getFoo?10
  • @RequestParam => `${SERVER_URL}getFoo?id=10

Comments

0

If the second parameter is missing, the value of second parameter is null. The 3 arg constructor is also called, but the second parameter is set null when call the constructor.@tmarwen

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.