Two Laptop Bag*
The moose likes Servlets and the fly likes Plain Java Class needs access to ServletContext Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Servlets
Bookmark "Plain Java Class needs access to ServletContext" Watch "Plain Java Class needs access to ServletContext" New topic
Author

Plain Java Class needs access to ServletContext

Jim Borland
Greenhorn

Joined: Oct 26, 2009
Posts: 25
I have a plain Java class (POJO?) running inside a Tomcat application that needs access to ServletContext in order to get and set attributes. I've tried having the class extend HttpServlet but can't figure out how to make this work inside a POJO that utilizes its constructor for various chores. My next effort was to write a separate class, have it extend HttpServlet, and give it an init() method that uses -- getServletContext().getAttribute("keyname") -- to get attributes.

The question now is how to pass the object obtained from ServletContext back to the POJO? I did try writing a separate method in the HttpServlet extended class that will return an object, and it got through the compiler okay, but I can't figure out how to call this method from the POJO.

So, how does one obtain stuff from ServletContext when using a POJO? Thank you very much for your help with this question.
Siva Masilamani
Ranch Hand

Joined: Sep 19, 2008
Posts: 385
Get the servlet context object in any of the servlet class and then store it in any reference then pass that reference to the POJO class.

ServletContext context=getServletContext();

then pass this context referece to POJO class.


SCJP 6,SCWCD 5,SCBCD 5

Failure is not an option.
Jim Borland
Greenhorn

Joined: Oct 26, 2009
Posts: 25
I understand about storing it in a reference (in this case the reference is named "context"), but how do I pass this back to the POJO class? Doesn't the POJO need to call a method in the servlet class that has a return value?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61433
    
  67

Design Flaw Red Flag!

If your POJO class tries to extend servlet, or even know about the servlet context, it isn't much of a POJO, is it?

You should be passing data to and from the POJO using plain old Java types. Leave the servlet-y things to servlets.

In any case, this is nothing that's Tomcat-specific, so it's been moved to the Servlets forum.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Siva Masilamani
Ranch Hand

Joined: Sep 19, 2008
Posts: 385
Why don't you do it other way?

Let the servlet call the setter metod of the POJO and set the ServletContext in it.

Anyway as Bear said it is not idea to do this.
Jim Borland
Greenhorn

Joined: Oct 26, 2009
Posts: 25
Okay, maybe I'm demonstrating my ignorance here, but this isn't working right and I need help. Here's what I did:

(1) My new servlet class extends HttpServlet and begins with:

public void init(ServletConfig config) throws ServletException {
super.init(config);

Then I do the get and set attribute stuff and end up with an object that needs to be passed to POJO.

(2) My new servlet class has method: getObject() that returns the object.

(3) Code in POJO:

MyServletClass myServlet = new MyServletClass();
theNeededObject = myServlet.getObject();

(4) The application compiles okay and runs, but the things that are supposed to happen in my new servlet class aren't working.

Am I doing this correctly? If so, then my problem is somewhere else. I need to know if this is the correct way to pass an object from my servlet class to the POJO. Thank you.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18669
    
    8

No. Several people have already said "Don't extend HttpServlet". They were all correct. Here's a simple outline:



Then your servlet would create a new Helper object and call its doSomethingWith method, passing suitable parameters.

Probably you'll need something more complex than that for your helper class, but that's how you pass it a ServletContext.
Siva Masilamani
Ranch Hand

Joined: Sep 19, 2008
Posts: 385
It is not at all advisable to create Servlet instance manually.

It is the container's job.

You can do like this.

Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18669
    
    8

I'm not convinced that this so-called "POJO" class -- which I think of as a "Helper" class -- really needs to keep a permanent reference to the ServletContext. And in general objects shouldn't hold onto references if they don't actually need them. So just passing it a reference to the ServletContext when necessary (as in my example) might be better.

Or it might not, and yours might be better. We don't actually know anything about this helper class.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18669
    
    8

Looking at your (i.e. Jim Borland's) latest post I see I didn't quite understand it. Apparently the POJO class is trying to create an instance of the servlet and use that. No, that's wrong. It's backwards. The servlet should create an instance of the POJO class and use that.

I also notice that the original post said the POJO class was "running inside Tomcat". I didn't understand what that meant so I let it pass. But perhaps there is some relevant information about the life cycle of something there?
Jim Borland
Greenhorn

Joined: Oct 26, 2009
Posts: 25
I very much appreciate all your comments, and I've read each one carefully (over-and-over), but I still don't see the solution to my problem. I have a large legacy code application and there are MANY calls to my POJO throughout the application. The POJO is instantiated using "new" and has a constructor that performs several operations, so I can't convert it to an HttpServlet or anything like that. To repair a bug in the program I need to add functionality to this POJO so it can access the servlet container (my application uses Apache Tomcat as its container).

I just don't see how I can insert a servlet in this chain and have it create the instance of the POJO class. Is there any other way to access the container in order to use ServletContext to get and set attributes? Once again, thank you for your help with this.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18669
    
    8

Presumably these objects are created by something which does have access to the ServletContext? Like a servlet, for example? Then just add a method where the caller can pass a ServletContext object into the POJO object. Like the example which I posted earlier.

And forget about the idea of making it a servlet. Obviously it isn't a servlet, so there's no point in thinking of that.
Jim Borland
Greenhorn

Joined: Oct 26, 2009
Posts: 25
Having the caller pass a ServletContext object into the POJO object is a terrific idea, and would probably work in most cases, but I just counted and there are 152 classes that call my POJO and each of those Java files would need to be edited. I'm hoping to find something less laborious. Thanks for the feedback!
Darlan Moraes
Greenhorn

Joined: Jan 08, 2013
Posts: 7
A simple way to access ServletContext is just use a ServletContextListener.



And the class that have access to ServletContext...



I hope it is helpful...
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61433
    
  67

But then, of course, the class is no longer a POJO.
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2409
    
  28

I think you need to keep one important principle of MVC pattern in mind:- Your service layer should be independent of the controller and view.For the most part, your services shouldn't even know that they are executing inside a webapp. By making POJO have knowledge of ServletContext, you are adding a dependency in the wrong direction.

If your service layer needs access to a data that is available in your servlet context, then your controller should pass the data to the service layer, not the entire Servlet Context.
Darlan Moraes
Greenhorn

Joined: Jan 08, 2013
Posts: 7
Bear Bibeault wrote:But then, of course, the class is no longer a POJO.

The ServletContext is accessible by any location of the application.
But the solution appointed by Jayesh A Lalwani is the best way to solve this problem without adding a dependency.
Jayesh A Lalwani
Bartender

Joined: Jan 17, 2008
Posts: 2409
    
  28

One pattern that you can use is the Context pattern. It's not a pattern that I am terribly fond of, but it has it uses. I think the Context Pattern can be terribly misused. It's basically a way of introducing a global variable into a multi threaded application, and should definetly not be used for variables that are modified from many places. I think it is fine for cases where the global variable is being set from one place and used in many many places.


So, basically what the Context pattern is that you have a singleton that encapsulates a thread local variable. When your Servlet first gets the request, it initializes the Context and sets the thread local variable. After this, whoever needs to use the variable, can get it from the singleton. It's basically a thread safe global variable.

Again, I would not reccommend using this pattern for variables that change very often. And as far as possible, it's better to use pass parameters than to use global variables.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61433
    
  67

Darlan Moraes wrote:The ServletContext is accessible by any location of the application.

No, it should not be. As Jayesh pointed out, it should be limited to the controller layer.
 
Don't get me started about those stupid light bulbs.
 
subject: Plain Java Class needs access to ServletContext