Spring controller parameter injection

Jan 1, 0001

For most applications that have some sort of login feature, you need the logged in user in your controllers or else where. If you are using an authorization/authentication framework they probably provide a nice way of doing this. If you are managing your sessions with spring there are probably different ways of doing this but for the sake of an example this is the scenario I’m going with. I want to pass the current user as a parameter to a controller method and have it populated with the current user by spring. This is done with a component that implement HandlerMethodArgumentResolver

@Component
public class CurrentPlayerParameterResolver implements HandlerMethodArgumentResolver {
    @Resource
    PlayerSessionRepository playerSessionRepository;
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(Player.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest req = webRequest.getNativeRequest(HttpServletRequest.class);
        Cookie[] cookies = req.getCookies();
        if(cookies == null) return null;
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(Const.COOKIE_SID)) {
                return playerSessionRepository.findBySessionId(cookie.getValue());
            }
        }
        return null;
    }
}

install the resolver

@Configuration
public class WebConfigurationAdapter extends WebMvcConfigurerAdapter {
    @Resource
    CurrentPlayerParameterResolver currentPlayerParameterResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(currentPlayerParameterResolver);
        super.addArgumentResolvers(argumentResolvers);
    }

}

and use it in your controllers

@GetMapping(value = "/galaxies")
public String galaxy(Map<String,Object> model, Player currentPlayer) {
//currentPlayer is populated
...
}