5

I'd like to set some default values in the session in a SpringBoot application. Ideally, I was thinking to use a class annotated with @ControllerAdvice to set the default values. This is useful, especially because the code snippet must be executed for all the pages.

Is there a way to access the HttpSession in a class annotated with @ControllerAdvice?

mat_boy
  • 12,998
  • 22
  • 72
  • 116

2 Answers2

4

You can get the session from within your @ControllerAdvice, using:

Option 1:

 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

HttpSession session = requeset.getSession(true);//true will create if necessary

Option 2:

@Autowired(required=true)
private HttpServletRequest request;

Option 3:

@Context
private HttpServletRequest request;

Here is an example of how I have devined a Controller aspect that intercepts all controller endpoint methods:

@Component
@Aspect
class ControllerAdvice{

     @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
     void hasRequestMappingAnnotation() {}

     @Pointcut("execution(* your.base.package..*Controller.*(..))")
     void isMethodExecution() {}

   /**
    * Advice to be executed if this is a method being executed in a Controller class  within our package structure
    * that has the @RequestMapping annotation.
    * @param joinPoint
    * @throws Throwable
    */
    @Before("hasRequestMappingAnnotation() && isMethodExecution()")
    void beforeRequestMappedMethodExecution(JoinPoint joinPoint) {
        String method = joinPoint.getSignature().toShortString();
        System.out.println("Intercepted: " + method);

        //Now do whatever you need to
    }
}
pczeus
  • 7,709
  • 4
  • 36
  • 51
  • That's really nice. Anyway, `getRequest()` doesn't exists. Moreover, I see from [this](http://stackoverflow.com/a/1629239/1983997) answer that it should be used `currentRequestAttributes()` instead of `getRequestAttributes()` – mat_boy Apr 09 '16 at 18:14
  • Moreover, how should I annotate the method in the controlleradvice to make it able to be called when each controller is called? – mat_boy Apr 09 '16 at 18:19
  • getRequestAttributes and getCurrentRequestAttrributes perform the same function with the exception that getCurrentRequestAttributes: Exposes the previously bound RequestAttributes instance, if any. Falls back to the current JSF FacesContext, if any. – pczeus Apr 09 '16 at 18:20
  • Well..I use groovy, so it was slightly modified for my usecase. I have updated it to Java format. – pczeus Apr 09 '16 at 18:23
  • Can you explain further about your annotate in controller advice question? That's not related to the session, correct? Are you asking how to create the advice to intercept every controller endpoint method? – pczeus Apr 09 '16 at 18:27
  • yes, exactly! Usually in a controller advice I use `@ModelAttribute`, but in this case I don't know how to make the method called – mat_boy Apr 09 '16 at 18:31
  • I have updated the answer to show you how to catch all methods executed with `@RequestMapping`. If you need to, you could modify it to use `@ModelAttribute` – pczeus Apr 09 '16 at 18:36
0

I would recommend you to use Spring Interceptors rather then @ControllerAdvice. Later you can easily customize behaviour with Interceptor mappings.

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-handlermapping-interceptor

@ControllerAdvice really shines, when you want to handle some exceptions globally.

JSONStatham
  • 353
  • 4
  • 18