views:

73

answers:

3

I'm using IBM WebSphere as my servlet container. My application has several servlets and Java classes. My intent is to call one of those servlets directly from a Java class. Doing some research I figured out that is possible to use the RequestDispatcher interface to achieve this. But it is necessary to pass the objects ServletRequest and ServletResponse as arguments to the method forward(). There is some way to bypass this safely and "nicely"? By "nicely" I meant to say preserving good programming and design patterns.

+5  A: 

The only way to do this nicely is to decouple the desired logic from the servlets. This requirement is a sign that the servlets are too tight coupled with business/domain code logic which apparently needs to be used as well outside the webapplication context.

Refactor the original servlet code into reuseable Java class(es) and method(s) (which in turn does not use anything from the javax.servlet package) so that you can finally import and invoke it from both the servlet class and the "plain vanilla" Java class.

BalusC
+1  A: 

You could write a filter that stores the current request and response in static ThreadLocal, so that you can use them later from within the same request. You can then implement your own static method forward that uses them and dispatch to another page.

This is somehow the approach taken in JSF where FacesContext.getCurrentInstance can be accessed anytime.

But I wouldn't qualify that as an elegant design. Rather try to follow @BalusC advice and refactor your logic.

ewernli
@ewernli - re: _`FacesContext.getCurrentInstance` can be accessed anytime._ - this is because the `FacesServlet` (or similar controller) initializes it as a `ThreadLocal` variable before invoking the lifecycle. You will not get the same Faces context in another thread.
McDowell
@McDowell Sure. That's exactly what I describe in the first § with the filter and `ThreadLocal`. Is my answer unclear?
ewernli
@ewernli - no, my comment was foolish. I must have glanced over your answer and missed the blatantly obvious. I think I've tried to explain the ThreadLocal/FacesContext thing so many times I have an automatic response to the topic. Apologies!
McDowell
+2  A: 

It would help to get some more background as to why you are trying to do this. I am assuming you want to invoke some piece of business logic in the servlet. This is a sign that the application is poorly designed.

Are you familiar with MVC architecture? If your "model" code was loosely coupled, you would be able to call it directly.

dbyrne
That's the case, the application is really poorly designed, thus the cause of my struggling. But I can't refactor the business logic behind this servlet, at least not now. The servlet to be called was provided by another company to offer a interface to a proprietary legacy system.
Renan Vinícius Mozone
A bit decent IDE (Eclipse, Netbeans, IntelliJ, etc) can refactor code in a few clicks. You would be ready sooner than the time needed to post this question, waiting for answers and inventing a hack/workaround which ain't going to work.
BalusC
I fully understand and agree with you. But, unfortunately, there is some political issues that prevents me of doing any refactoring right now. I just don't want to call the servlet using HTTP inside the same application.
Renan Vinícius Mozone
Then I would give ewernli's idea a shot.
dbyrne
Honestly said, ewernli's idea is not feasible.
BalusC
I think we would all agree the time would be much better spent refactoring.
dbyrne