Karthik's Weblog

Taking Spring MVC @Controller method injection a step further

Posted in Java, Spring by karthik on February 3, 2010

Spring MVC @Controllers typically allow you to annotate your controller method parameters making it http agnostic and increasing the testability of the controllers at the same time. But sometimes you are required to repeat the parameter signature as shown below –

@Controller
class AccountController{
@RequestMapping("/create")
public String create(@RequestHeader(value="SM_USERDN")String smUserdn,
@CookieValue(value="smsession") String smSession,
@SessionParam(value="user_id") String userId
){
}
@RequestMapping("/update")
public String update(@RequestHeader(value="SM_USERDN")String smUserdn,
@CookieValue(value="smsession") String smSession,
@SessionParam(value="user_id") String userId
){

}
}

Controller methods ‘create’ & ‘update’ access the same set of servlet environment specific parameters.
I was wondering if it would help if we could move all those parameters to an annotated POJO as shown
below and reuse the POJO in the controller methods –

Note that the Spring MVC @Controller annotations that let you access request, cookie, header values
can be specified at the method parameter level only. I obviously wanted to reuse these annotations and found that to be a limitation only to realize later that I could make use of constructor injection style

public class MyEnv{
private final String smUserdn;
private final String smSession;
private final String userId;
@Autowired
public MyEnv(@RequestHeader(value="SM_USERDN") String smuserdn;
@CookieValue(value="smsession") String smSession,
@SessionParam(value="user_id") String userId
){

this.smuserdn = smuserdn;
this.smSession = smSession;
this.userid = userId;
}

}
@Controller
class AccountController{
@RequestMapping("/create")
public String create(@Composite MyEnv env){

}
@RequestMapping("/update")
public String update(@Composite MyEnv env){
}
}

You need the @Composite custom annotation to trigger this binding.
Do you guys see a need for something like this? I did implement this feature. But wanted to check if people find this useful at all.
thanks!

Tagged with: , ,