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.
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.
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.
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.
Related
So i have a sort of design question:
I have a jsp, and a controller that fetched the data for that jsp. Some of that data come from service classes.
I know that mvc pattern tells me to use the controller to call the service class and pass that info to my view (jsp).
Why can't I call the service class from my jsp directly?
You can, and that's what developers sometimes do. But you shouldn't.
MVC is about interchangeability and separation of concerns. If you call your service from JSP, you create a tight coupling, to parameters and return types, for example.
Moreover, usually, systems are not developed singlehandedly. Let's say you have getAllAdmins() method in your service, which you use for internal logic. Do you really want another developer to use it directly in JSP, and by mistake display all your admins? Probably not.
You can. You can even put everything in one class and maybe it will work. But why? Doing like that ruin all flexibility.
You think only about little example, but you should think what advantages it gives to big applications.
Read this.
This question already has answers here:
Design Patterns web based applications [closed]
(5 answers)
Closed 6 years ago.
I'm coding my first servlet (academic purpose) and I not have clear what is the proper way to do the interface with HTML client.
If the client requests are of many type, like "I want a coffee", "I want a pizza" etc, (actually I think I'll need only login and data send/request) however, how the servlet must handle these? considering that a servlet have only one get/post method.
A) one servlet (serverAddr/myApp/myServlet) that check with a parameter which request is received and call the proper function (with a switch. Don't sound good).
B) a servlet with specific purpose for each request, like "doCoffee" (serverAddr/myApp/coffee), "doPizza" (serverAddr/myApp/pizza) etc.
In this case, I have many servlet that form the web application.
I hope have explained my question, thanks.
You are right : the two solutions (a doGet() methods which handles multiple use cases and as many servlets as usecases) are not good design in a general way.
That's why, since very long time, Java EE applications don't use massively directly their own HttpServlet implementation but use Java EE UI frameworks which allow to have a flexible design in the web controllers.
Behind, a HttpServlet provided by the framework is used but we don't need to worry about it because it's ready to be used. One of their main goal is handling all boilerplate, complex and repetitive code to allow developers to have a flexible way of designing their web applications.
For example, JSF 1 (which is not very recent) allow to use JSF backingbean to map a JSP view to a almost classic Object Java and not a rigid servlet with just a single doGet() method to handle our needs.
In this backingbean, you can add any methods as in a classic java class and you call these methods from your JSP in a Java classic way : myBean.myMethod().
Most of Java EE UI frameworks (SpringMVC, GWT, Struts 2, etc...) allow to do that.
So I am pretty new in Java and I'm trying to get started with web applications using JSP and servlets. I've came across this CRUD web app guide A simple CRUD Tutorial Using Java Servlet / JSP. The thing is, I don't understand why they have to create the StudentDAO interface. I know this would be easy as pie to understand for most of you that's why I'm asking here. All I want is an answer if StudentDAO interface is really needed since we only declare the methods there, and override all of them in a class called studentDAOImplementation anyway.
I know I should read some more about Java interfaces but I was hoping to get explanation on why interface is needed in this example.
This does not really have a simple answer. The sketch of the answer would be - because you want to be independent of how your application actually stores/retrieves the data in the database. The interface provides the functional specification of what the DAO (Data Access Object) should be able to do - it is up to the specific implementation to actually do it. For example, for testing purposes, you might want to setup a stub DAO that does not really use the database, but instead gives you prefabricated objects. In a real-world complex application, you might want to vary the DAO depending on what database engine is really used and so on and so on. So generally, this is an instance of decoupling the functional specification from the implementation.
I am working on workflow management system.
Have one separate java class which contains logic method. One of this is:
public static in get_nxt_stg(int current_stg,int action)
{
}
and define static variable cur_stg and nxt_stg. used in servlet. call this method.
When multiple users log in and do some action these variables get not proper value. It seems like it is shared between all user requests.
What is best way to use variable in servlet, which is remain specific for that request?
You should not use static in such a way. If you need to share state, consider using the singleton pattern; but try to avoid static. Unwise use of "static" can turn into a nightmare (for example regarding unit testing).
In addition: it seems that you are a beginner with the Java language. But creating servlets is definitely a "advanced" java topic. I really recommend you to start learning more about Java as preparation for working on servlets. Otherwise the user of your server might have many unpleasant experiences ...
What you are doing is wrong. You should use Servlets only for the purpose of reading request parameters and sending responses. What you are trying to do, should be implemented in the Business layer of your application and if you have it implemented with EJBs, then your problem can easily be solved with an Stateful EJB.
on my GAE app, I have a servlet that performs an XSLT transformation. I used to run it as frontent, but sometimes it took too much time to finish. So I'm now running this on the backend.
This is what I did:
1/ create a file 'backends.xml' defining a dynamic public backend named 'xslt'
2/ prepend 'xslt' to the domain when calling the servlet:
http://xslt.[appname].appspot.com/getCoordinates?[params]
This works!
The typical behaviour of the app is that a series of calls to this 'getCoordinates' servlet will be made. Each request will trigger the 'doGet' method of this 'getCoordinates' servlet, which does the initialization of the Saxon processor, xsltCompiler, xsltExecutable and xsltTransformer, but all of these objects could be reused across subsequent requests!
My question: how should I program to separate this initialization code into a handler for the backend initialization request to '_ah/start'?
If I just create another servlet 'startXslt' that answers the request to '_ah/start' and initialize all the generic objects within this servlet's 'doGet' method, how will I be able to use the objects from within the 'getCoordinates' servlet's 'doGet' method?
(I'm not very experienced with java servlet programming, so I reckon this may be more like a general question on java servlet programming, and not GAE-specific, or is it?)
Yes, it's general questions, and there is really a hundreds of ways of doing that. Btw, most projects are based on some framework, and it depends on it. If you're startd with plain raw servlets - i strongly recommend you to take a look at other options. For GAE there is Gaelyk. Or Spring MVC as most populart (is it?) general usage framework.
Btw, if you need an solution right now, I can recommend one of the following:
init in init() method (it will be called on app startup)
store it at class static field, and init in static {} block (called at class initialization, shared between instances)
make an singleton for this transformers (you can init it once, at first call)
Using a backend is a good idea, since you could control that only a single instance would be used and re-used when addressing the backend.
In this way, all servlets would be executed within the same JVM instance, and you could therefore have a shared object by using a Singleton pattern as suggested by splix on the other answer.
As I understand it, your question pertains on how you could hook on the backend initialization to initialize your own objects. If that is the case, you could implement a ServletContextListener and put your code on the contextInitialized(ServletContextEvent) method.
This method would be invoked once every time a new instance is created, be it at the front end or at the back end.