aspose file tools*
The moose likes Servlets and the fly likes ServletContext, again Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "ServletContext, again" Watch "ServletContext, again" New topic
Author

ServletContext, again

Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Ok, it's time to figure out my ServletContext issue, so I am going to be posting quite a bit of my code to try and find out what the heck is going on. So here goes the code first, then I will kind of explain what the problem is:
web.xml

ControllerServlet.java

Action.java

LoginView.java

index.jsp


Ok, when I access the LoginView via my index.jsp action/login I get the following error:

LoginView.java:15 is the line I commented in bold in the code above. It is where I am trying to get the Properties object back out of the ServletContext. So the problem is that all my "Actions" are not using the same ServletContext.
Can anyone shed some light on as to why this is happening? Is it because I am instantiating all my Action classes in the init method of my Controller Servlet? I don't know. Any help is appreciated.
Thanks.


GenRocket - Experts at Building Test Data
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
That looks pretty straightforward.
Remember that servlets are usually instantiated by the container, not by client code. You are creating servlet instances, but never calling init(...) to set the context. So, of course, when you try and retrieve the context, it's still null. My worry is that you are never calling any of the other "lifecycle" methods, either.
I can't see any real reason for your actions to be servlets at all, though, if all you are doing is creating them and calling methods in your own code. I reckon your action class should just be a regular abstract class with a ServletContext protected member, a ServletContext constructor parameter, and an abstract process(HttpRequest, HttpResponse method). You never call the doGet and doPost methods, so you don't need them.
Does that make any sense?


Read about me at frankcarver.me ~ Raspberry Alpha Omega ~ Frank's Punchbarrel Blog
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Originally posted by Frank Carver:
That looks pretty straightforward.
Remember that servlets are usually instantiated by the container, not by client code. You are creating servlet instances, but never calling init(...) to set the context. So, of course, when you try and retrieve the context, it's still null. My worry is that you are never calling any of the other "lifecycle" methods, either.
I can't see any real reason for your actions to be servlets at all, though, if all you are doing is creating them and calling methods in your own code. I reckon your action class should just be a regular abstract class with a ServletContext protected member, a ServletContext constructor parameter, and an abstract process(HttpRequest, HttpResponse method). You never call the doGet and doPost methods, so you don't need them.
Does that make any sense?

I actually wondered about this. I don't see any reason for my Actions to be servlet either, but I still need to be able to gain access to the ServletContext so that is what I need to do now.
So in my abstract Action class constructor, where do I get the ServletContext from so that it is the same one for all my actions and not a new one? I guess I am confused a bit about:

I reckon your action class should just be a regular abstract class with a ServletContext protected member, a ServletContext constructor parameter,...

Thanks Frank.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Ok, I solved my problem, and I would like it if someone would look at this and see if they think it is sloppy or worth keeping.
My new Action.java class is:

The only thing I had to do differently in my ControllerServlet.java class was add the following BOLD code:

That way, all my Action classes have an instance of the ControllerServlet allowing me to access the ServletContext.
Chad McGowan
Ranch Hand

Joined: May 10, 2001
Posts: 265
I would just pass the ServletContext when calling the processRequest method. That way you don't have to loop through your actions to set the variable. Why not have your processRequest use this signature:

Another solution:
I had this issue before, where I needed to access the servletContext from an action class. Unfortunately, I was modifiying an existing application, using an Action interface that only accepted HttpServletRequest and HttpServletResponse.
I got around this by having the controller add the servletContext to the request, before invoking the execute() method in the Action. That way you can stick with the basic request, response method parameters.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

[/qb]<hr></blockquote>
That was my very first work around, and the only reason I didn't like that was it was 1 more thing that was being passed around. It works the same though either way. Thanks for the suggestion.
I wonder though if that wouldn't be better in the long run. What if I had 1000 actions. How long would it take for that loop to run then? Granted it would only have to do it at startup, but... Hmmmmm...something to think about.
[ December 30, 2003: Message edited by: Gregg Bolinger ]
Chad McGowan
Ranch Hand

Joined: May 10, 2001
Posts: 265
Another thing to think about is what do you really need from the servletContext? Is it just a Map that is loaded by the servlet? If so, why not just let the controller stick the Map onto each request before forwading on to the action?
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
Gregg, all of your code seems a bit overcomplicated to me. What I meant by the remark about the constructor parameter was something like:

Then in the ControllerServlet:

That way you don't need any iterators or other extra code. Or have I missed what you are trying to do?
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Originally posted by Frank Carver:
Gregg, all of your code seems a bit overcomplicated to me. What I meant by the remark about the constructor parameter was something like:

Then in the ControllerServlet:

That way you don't need any iterators or other extra code. Or have I missed what you are trying to do?

Ahaaa, that looks more like it. I think I will try this route. Thanks Frank. I looked at your code and then was kind of "duh....".
:roll:
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

So Frank, what do I need to do in my classes that extend Action? Don't they have to have the same constructor as the Action class as well?
Ken Robinson
Ranch Hand

Joined: Dec 23, 2003
Posts: 101
If you don't mind me asking, why are you writing all of this code to call an Action based on a URL? Your Action class looks exactly like a Servlet with the processRequest having the Req/Res pair and you have had to write an init like method.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Originally posted by Kenneth Robinson:
If you don't mind me asking, why are you writing all of this code to call an Action based on a URL? Your Action class looks exactly like a Servlet with the processRequest having the Req/Res pair and you have had to write an init like method.

Hey, it's my anti-struts buddy. Well, while I don't agree with STRUTS 100% I was under the impression using a Front Controller was good MVC Model 2 design. Using straight Servlets would be easier, but I am trying to do things "correctly". Have I been mis-informed on the Front Controller issue?
Ken Robinson
Ranch Hand

Joined: Dec 23, 2003
Posts: 101
If what you are trying to do is map a URL to a thing (Action), that is exactly what you get with servlets and the J2EE/war spec.
Althought it is never really advertised as a Front Controller or MVC type of 'framework', if you think about how a web container works in the J2EE world, it already takes a URL and determines which Servlet to utilize. It's 'out of the box' FC and MVC.
For Front Controller, the container is the controller that does common work (Request, Response, Context) and forwards to the correct resource (Servlet/JSP).
For MVC, use Servlets as your controller (logic only, no display) and JSP as your View (display only, no logic). Use the ServletRequest (or HttpServletRequest) and the Session and ServletContext objects as the three ways to communicate data between the Controller and View.
The main difference between STRUTS' Action and a Servlet's doGet/doPost is that STURTS Action method signature also contains an ActionForm and ActionMapping. If you don't need those, just use a Servlet.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Originally posted by Kenneth Robinson:
If what you are trying to do is map a URL to a thing (Action), that is exactly what you get with servlets and the J2EE/war spec.
Althought it is never really advertised as a Front Controller or MVC type of 'framework', if you think about how a web container works in the J2EE world, it already takes a URL and determines which Servlet to utilize. It's 'out of the box' FC and MVC.
For Front Controller, the container is the controller that does common work (Request, Response, Context) and forwards to the correct resource (Servlet/JSP).
For MVC, use Servlets as your controller (logic only, no display) and JSP as your View (display only, no logic). Use the ServletRequest (or HttpServletRequest) and the Session and ServletContext objects as the three ways to communicate data between the Controller and View.
The main difference between STRUTS' Action and a Servlet's doGet/doPost is that STURTS Action method signature also contains an ActionForm and ActionMapping. If you don't need those, just use a Servlet.

I know what you are saying. But there IS a Front Controller Pattern that Sun recognizes and it documented in the J2EE specs. So instead of having 10 servlets, you have one servlet that forwards to "helper classes". Granted, the only thing this does is centralize a bit of configuration, but it is a valid design pattern and not specific to any 1 framework. You might want to get involved in a thread I started here.
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
So Frank, what do I need to do in my classes that extend Action? Don't they have to have the same constructor as the Action class as well?
Yup. That was the "exercise for the reader"
Ken Robinson
Ranch Hand

Joined: Dec 23, 2003
Posts: 101
I guess I just disagree that Servlet's should be controllers that hand off to other non servlet classes.
When I first read Java Servlet Programming, one of the big deals about servlets was the automatic ability of the container to create one class that lived for the life of the app and handled all request for that URL. It seems that back then this was a great idea and now it is somehow regarded as wrong. I always hear the phrase 'why reinvent the wheel', but that seems like what many servlet front controllers do when it comes to mapping the 'helper classes' to a URL. I've just always believed that the Servlet was the helper class and that the determination of what servlet to call, the creation of the ServletRequest/ServletResponse pair and so on was the job of the web container, acting as the controller.
Most complex applications utilize an other layer to do the majority of the work anyway (EJBs, Business Objects, DAOs, etc...). The web portion of an app should only be a bridge to the real app.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Originally posted by Kenneth Robinson:
I guess I just disagree that Servlet's should be controllers that hand off to other non servlet classes.
When I first read Java Servlet Programming, one of the big deals about servlets was the automatic ability of the container to create one class that lived for the life of the app and handled all request for that URL. It seems that back then this was a great idea and now it is somehow regarded as wrong. I always hear the phrase 'why reinvent the wheel', but that seems like what many servlet front controllers do when it comes to mapping the 'helper classes' to a URL. I've just always believed that the Servlet was the helper class and that the determination of what servlet to call, the creation of the ServletRequest/ServletResponse pair and so on was the job of the web container, acting as the controller.
Most complex applications utilize an other layer to do the majority of the work anyway (EJBs, Business Objects, DAOs, etc...). The web portion of an app should only be a bridge to the real app.

That's interesting. Worth looking into..
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: ServletContext, again