3

I have a simple @RestController service that takes query parameters, and spring automatically parses them to an bean:

@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/rest", method = RequestMethod.GET)
public MyDTO getGiataHotel(@Valid MyParams p) {
    Sysout(p.getId()); //prints "123"
}

public class MyParams {
    private int id;
    //private SubParams subs;
}

Query: .../rest?id=123

Now I'd like to structure the parameter object with nested classes. How can I achieve this?

public class SubParams {
   private String name;
   //some more
}

Ideally my query should be: Query: .../rest?id=123&name=test, and the "test" string should go into the SubParams bean.

Is that possible?

membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • `test` is a value. The parameter name is `name`. So, your SubParams has a field `name`? – Raffaele Sep 01 '15 at 08:57
  • As you see above, yes the class `SubParams` has a field `name`. – membersound Sep 01 '15 at 09:02
  • Is SubParams static? – Raffaele Sep 01 '15 at 09:14
  • Not now, but it could be if that helps. – membersound Sep 01 '15 at 09:43
  • It would help a lot because to instantiate an inner class you must have the reference to the outer instance. A nested class can be safely extracted in its own file. But is there a dependency between the two? I still have not understood what's your purpose and what are your constraints – Raffaele Sep 01 '15 at 10:04
  • I want spring to automatically move some of the get-query params automatically into the `SubParams`. I then could use eg `p.getSubParams()` to pass around only some fields that are grouped logically together. – membersound Sep 01 '15 at 11:13
  • Then why don't you simply code .getSubParams() yourself? Why do you need Spring binding fields? Just create a new object manually copy fields – Raffaele Sep 02 '15 at 06:46
  • Of course I could, but the question was: is spring capable of doing thisitselves? – membersound Sep 02 '15 at 07:04

3 Answers3

1

You have to register a Custom Covertor if you need to set to a inner class. The change would be following:

@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/rest", method = RequestMethod.GET)
public MyDTO getGiataHotel(@ModelAttribute("subParam") MyParams params, @Valid MyParams p) {
    //Do stuff
}

The subParam denotes that there is a converter registered for conversion.

public class MyParamsConverter implements Converter<String, MyParams> {

    @Override
    public MyParams convert(String name) {
        MyParams myParams = new MyParams();
        SubParams subParams = new SubParams();
        subParams.setName(name);
        myParams.setSubParams(subParams);
        return myParams;
    }

}
Karthik R
  • 5,523
  • 2
  • 18
  • 30
0

You can achieve this by using the @ModelAttribute annotation : http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-method-args (this is not in the Path parameters, but in the requestParams either get/post)

@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method =   RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {

     if (result.hasErrors()) {
         return "petForm";
     } 

     // ...       

}
Radu Toader
  • 1,521
  • 16
  • 23
0

maybe u should use RequestMethod.POST, like this

@RequestMapping(value = "/rest", method =   RequestMethod.POST)
public ModelAndView getGiataHotel(@ModelAttribute("subparams") SubParams subparams){
      SubParams sub=subparams;
      //do something...
}
JJ_Jacob
  • 186
  • 6