2

There is a class :

@Configuration
@ComponentScan("com.ambre.pta")
@EnableTransactionManagement
@PropertySources({
    @PropertySource("classpath:fr/global.properties"),
    @PropertySource("classpath:fr/main.properties"),
    @PropertySource("classpath:fr/admin.properties"),
    @PropertySource("classpath:fr/referentiel.properties"),
    @PropertySource("classpath:fr/departement.properties"),
    @PropertySource("classpath:fr/exercice.properties"),
    @PropertySource("classpath:fr/defi.properties")
})
public class ApplicationContextConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer properties() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean(name = "viewResolver")
    public InternalResourceViewResolver getViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Bean(name = "dataSource")
    public DataSource getDataSource() {

        BasicDataSource bds = new BasicDataSource();

        bds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        bds.setUrl("jdbc:oracle:thin:@localhost:1521:xe");

        bds.setUsername("pta");
        bds.setPassword("pta");

        return bds;

    }

    @Autowired
    @Bean(name = "sessionFactory")
    public SessionFactory getSessionFactory(DataSource dataSource) {

        LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);

        sessionBuilder.scanPackages("com.ambre.pta.model");

        return sessionBuilder.buildSessionFactory();

    }

    @Autowired
    @Bean(name = "transactionManager")
    public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {

        HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);

        return transactionManager;

    }

    @Autowired
    @Bean(name = "utilisateurDao")
    public UtilisateurDAO getUtilisateurDao(SessionFactory sessionFactory) {
        return new UtilisateurDAOImpl(sessionFactory);
    }

}

We can get the request object within this class by this way :

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

So is there a way to get the session ( HttpSession ) object ?

pheromix
  • 18,213
  • 29
  • 88
  • 158
  • 2
    _"How to get the session object in general from within a class?"_ Don't do that. But if you insist: `request.getSession()` ... – a better oliver Dec 05 '16 at 14:23
  • request.getSession().setAttribute i set some attribute. On next url hit session.getAttribute become null. Any Idea – Deepak Oct 25 '17 at 11:37

2 Answers2

3

Using Controller classes

You can define HttpSession as an argument to your controller methods:

@RequestMapping("/my-path")
public String doStuff(HttpSession session) {
    // do stuff...
}

This is also the recommended way to access the HttpRequest, rather than going through RequestContextHolder, because it's easier to mock out the session for tests.

See the Spring MVC docs for more detail.

Without using controller classes

Another option is to use a @SessionScope bean and mutate it accordingly:

@Component
@SessionScope
public class MySessionScopedBean {
    String attribute;
}

public class MyOtherClass {
    @Autowired
    private MySessionScopedBean myBean;

    public void doStuff() {
        // myBean accesses a bean instance isolated in the user session
        myBean.attribute = "test";
    }

}
kewne
  • 2,208
  • 15
  • 11
  • but I have a special need to access session within a non-controller class ! – pheromix Dec 05 '16 at 14:23
  • What, specifically, do you need to get from the session? – kewne Dec 05 '16 at 14:28
  • 1
    Oops, accidentally posted. If you need to keep some sort of user session state, my advice would be to create a `@SessionScope` bean. This way, you can inject it into a non-controller bean. – kewne Dec 05 '16 at 14:31
  • I stored 2 attributes in the session after a successfull login. So I need to get these values in my config class. – pheromix Dec 05 '16 at 14:31
  • In that case, I think using session scoped beans and mutating them would be the way to go, since it's more readable than storing attributes directly in the session. Otherwise, I'd use a controller method that receives the session (or attribute in the session, which is also possible) and pass it into the component. – kewne Dec 05 '16 at 18:42
2

If you want to access the HttpSession outside a Controller method, there are two possible answers:

  1. Don't do it, it's evil.
  2. If you really really want to do it (and I have done it in the past, so who am I to blame you), then the easiest way is to write a class to hold the session, and an interceptor to set and unset it. But to make things easier, I will be working with HttpServletRequest objects, from which you can extract the session:

    public class RequestHolder {
    
        private static final ThreadLocal<HttpServletRequest> REQUEST =
                                 new ThreadLocal<>();
    
        public static HttpServletRequest getCurrentRequest() {
            return REQUEST.get();
        }
    
        public static HttpSession getCurrentSession() {
            HttpServletRequest request = REQUEST.get();
            return request == null ? null : request.getSession();
        }
    
        public static void setCurrentRequest(HttpServletRequest request) {
            REQUEST.set(request);
        }
    
        public static void unsetCurrentRequest() {
            REQUEST.remove();
        }
    
    }
    
    public class RequestHolderInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) {
            RequestHolder.setCurrentRequest(request);
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView mav) {
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e){
            RequestHolder.unsetCurrentRequest();
        }
    }
    
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
  • Could you please explain in a few words why is it evil? I read everywhere that it is so, but without any explanations. How Controller classes are different than other Components? – gdrt Jul 06 '18 at 12:35
  • @gdrt that's hard to explain, but in an MVC app, each layer should be specialized. The M should be business only, independent of the frontend technology calling it, whereas the V layer should deal with presentation only. – Sean Patrick Floyd Jul 06 '18 at 23:52