0

There is a web application that I am working on currently and it has to be extended to expose web services. In the current project - when the application context is loaded at startup - database queries are made and static data like role names is set as variables at the session level. Like this:

private void loadRoles(ServletContext acontext) {
    ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(acontext);
    IMyDataService myDataService = (IMyDataService ) appContext.getBean("myDataService");
    List<Roles> rolesList = myDataService.listRoles();
    acontext.setAttribute(MyAppConstants.ROLES, rolesList);
}

This value stored in the session attribute is used as follows in other places of the application:

public boolean checkAccess(HttpServletRequest arequest) {
   HttpSession session = arequest.getSession();
   List<Role> roles = (List<Roles>)session.getServletContext().getAttribute(MyAppConstants.ROLES);
   .....
}

If I want to enhance the application to expose web services - my understanding is that I will no longer be having a ServletSession or HttpServletRequest available with me. So I want to move this static data from session variables to another place so that they are available in the context.

Is there a way in which I can achieve this? I tried getting rid of storing data in session variables all together, but could not do that because there are just too many references. Is there a better approach?

user811433
  • 3,999
  • 13
  • 53
  • 76
  • In your example, the data is store in the application scope (appContext), not in the session scope. It is kind of confusing... – Jean-Philippe Bond Apr 29 '14 at 19:59
  • @Jean-PhilippeBond - I edited the code to add method signature. The "acontext" to which the list of roles is added is a ServletContext. In other places in the application where this list is used, the session is taken from the application context and then the value is used. – user811433 Apr 29 '14 at 20:13
  • edited the question with further details – user811433 Apr 29 '14 at 20:17

2 Answers2

2

There is a difference between the session and the servlet context. I think that you are confuse because you are using the session object to get the servlet context. Your data is clearly set in the servlet context in this example. Even if you are using web services, you will have a servlet context provided by the servlet container.

Now I don't know which technologies you are using, but there's many other ways to make static data available to all your web services. For example, using a cache mechanism might be a better solution for data that is stored in the database...

More info :

A Servlet Session is a very different thing from a Servlet Context.

An HttpSession is a mechanism used to simulate and maintain a continuous user Session between a Web Browser and Web Application, largely managed by the Servlet Container. The HTTP protocol is stateless, it is essentially a request-response scheme, so Servlet Sessions are maintained by passing a unique HTTP cookie value for each request, or by dynamically including an identifier in Servlet URLs, known as URL-rewriting.

A ServletContext object represents the overall configuration of the Servlet Container and has several methods to get configuration parameters, exchange data amongst Servlets, forward requests and load resources. The Servlet Context is usually obtained indirectly through the ServletConfig object, passed to a Servlet's init(ServletConfig) method, or from the Servlet getServletConfig() method.

Javadoc definition for ServletContext :

Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.

There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog and possibly installed via a .war file.)

EDIT

To get the ServletContext object in a Spring application, use the @Autowired annotation. Note that the object should be managed by the Spring container, it will be the case if you are using controllers for you REST services.

@Autowired
ServletContext servletContext;

Here an example :

@Controller
@RequestMapping("/foo")
public class RESTController {

    @Autowired
    ServletContext servletContext;

    @ResponseBody
    @RequestMapping(value="/bar", method = RequestMethod.GET)
    public List<Roles> getRoles() {
        return servletContext.getAttribute(MyAppConstants.ROLES);
    }
}
Jean-Philippe Bond
  • 10,089
  • 3
  • 34
  • 60
  • thanks for the info. I have one question though. There are places where the roles list is actually being used - like the checkAccess() Method above. These methods are currently being called from JSPs and so the HttpSession is retrieved from HttpServletRequest. Then session.getServletContext() gives the ServletContext. In the case of web services - I will not have the HttpServletRequest and so in turn will not have the HttpSession to get the ServletContext. So the values stored in the ServletContext are lost out to me. Is there a way in which I can get them out of the application context? – user811433 Apr 29 '14 at 20:51
  • trying to build RESTful web services with Spring MVC. The current web application is spring+hibernate based. So after some trails Spring MVC looked best suited – user811433 Apr 29 '14 at 20:55
  • So the equivalent web service method to the above web application - checkAccess() method would look something like this: @Autowired ServletContext servletContext; public boolean checkAccess() { List roles = (List)servletContext.getAttribute(MyAppConstants.ROLES); ..... } Is this understanding correct? – user811433 Apr 29 '14 at 21:05
  • is there an alternative to @Autowired? Current web application does not use annotations. So, if I have to end up not using annotations - is there a way to get the ServletContext? – user811433 Apr 29 '14 at 21:09
  • 1
    Yeah, you can use beans that are ServletConfigAware, check this question for more information : http://stackoverflow.com/q/14459210/732771. I can't really go further since obviously I do not know your application... – Jean-Philippe Bond Apr 29 '14 at 21:14
0

Refactor your code by removing MyAppConstants.ROLES and by relying on Spring DI. There are much better ways to store static data than putting them in HTTP session or servlet context... (ex. create a list bean, use cache abstraction, use FactoryBean etc.).

Arek
  • 3,106
  • 3
  • 23
  • 32