Oblong
Oblong

Reputation: 21

How do you configure a Session-Scoped bean to be able to access information from the request and from other services?

In order for this session-scoped bean to work, it needs access to the Request object to allow it to determine the privileges of the logged-in user.

It also needs to be able to access the userService - another bean.

What does it need in order to gain access to these resources?

@Configuration
public class ExceptionResolverBuilder 
{
    @Bean @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public ExceptionResolver getExceptionResolver() 
    {

        ExceptionResolver er = new ExceptionResolver();

        User user = userService.getLoggedInUser(request);

        if(user.isAdmin())
        {
            sendEmail("Caught exception:" + exeption.getMessage());
        }
        else
        {
            writeLog("Caught exception:" + exeption.getMessage());              
        }

        return er;
    }

}

Upvotes: 2

Views: 1241

Answers (3)

sourcedelica
sourcedelica

Reputation: 24040

For a bean that is defined as a @Component you can autowire the HttpServletRequest like so:

@Component
@Scope("session")
public class Foo {
    @Autowired private HTTPServletRequest request;

    //
}

But since you are using @Bean you can't do this.

You can get the current request as follows:

    ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
    HttpServletRequest req = sra.getRequest();     

This uses thread-local under the covers.

If you are using Spring MVC that's all you need. If you are not using Spring MVC then you will need to register a RequestContextListener or RequestContextFilter in your web.xml.

Upvotes: 0

Stephen C
Stephen C

Reputation: 718708

In order for this session-scoped bean to work, it needs access to the Request object to allow it to determine the privileges of the logged-in user.

AFAIK, you can only get the current request if it has been passed as a parameter, or via a thread local.

If you are using SpringSecurity, you get the current request's authentication information by calling SecurityContext.getContext(). (This typically uses a thread local.) However, I'm not sure this will work because your method might be called at a point when the security context hasn't been set.

It also needs to be able to access the userService - another bean.

You need to arrange that this is provided by dependency injection.

Upvotes: 0

skaffman
skaffman

Reputation: 403441

Rather annoyingly, session-scoped beans don't get easy access to the request that initiated the session.

However, in your case you shouldn't need to. Assuming that your ExceptionResolver is an implementation of HandlerExceptionResolver, then there's no reason to put your logging logic into ExceptionResolverBuilder.getExceptionResolver(), since the resolver will get passed the current HttpServletRequest in the resolveException method.

Also consider using the @ExceptionResolver annotation, which makes life even easier, and also gets access to the current request.

Upvotes: 1

Related Questions