In a webapplication using servlets, I guess it's a poor idea to "logic-classes" (helping the servlets with database access, queries etc.) to have static variables and methods. I mean, if 10 users are using the same program, every servlet is instansiated in the webcontainer for each client, but they are still sharing the static methods and variables of the logic below. I assume it should be instances of logic classes in each servlet.. Can anybody just give me hint in what direction to think in developing a webapp like this!?
Steffe
Kiran Kumar
Ranch Hand
Joined: May 18, 2001
Posts: 107
posted
0
u can check out apache foundation's STRUTS Framework. go through the user guide which will tell u how to create a single controller servlet which will control all access to the application and how to write classes which can be called within the servlet. the classes should be written to be thread-safe. u can design ur own architecture after u get a basic understanding of how struts work. u can create a single servlet which will parse an xml file which contains all the configurations for all the service requests of the application and then keep calling the specified worker classes which will actually have the processing logic. hope this helps
Thanks<br /> <br />Kiran <br /> <br />SCEA, SCJP 1.4,<br /> <br />"First they ignore u, then they laugh at u, then they fight u, <br />then u will win<br /> <br />Mahatma Gandhi"
Stefan Elfvinge
Ranch Hand
Joined: Oct 29, 2001
Posts: 52
posted
0
Thanks! I still wonder, though... ...do I really have to bother about threadsafety if I instansiate these "logic-classes" within the servlets themselves? An example in my app: I have this HTTPServlet to present a dynamic HTML-form(doGet). doPost() updates a database with the response-parameters. The logic I'm refering to are various classes that access the database, perform SQL statements, etc. /webapptrainee
Toby Davis
Ranch Hand
Joined: Apr 09, 2002
Posts: 65
posted
0
Each client calling your doGet and doPost methods are in separate threads. However, ALL threads will have the ability to manipulate your class (non-local) variables... and this can cause problems. For example, one variable's value may be in the process of being changed when it's interrupted by another thread, while a third thread is trying to access the variable's value. What would that value be at that time? You COULD synchronize doGet(), doPost()... but it takes a huge overhead and gets messy, depending on what you have coded in those methods. Synchronized blocks just for the pieces making the database calls would be another way... (someone correct me if I'm wrong on all this, my ego isn't that big I recommend that you look at the MVC architecture in reference to writing a web app using an RDBMS as a back-end. You can find more information about it at many sources, including the J2EE Blueprints. http://java.sun.com/blueprints/patterns/j2ee_patterns/model_view_controller/index.html Surprisingly, the chapters on the Model 2 Framework in "Advanced JavaServer Pages" by Geary was a good start in MVC, in my opinion. This assumes you know how to write Java servlets and am familiar with JSP. Struts is another implementation on MVC, but I've yet to delve into that to give any opinion on it. Hope this helped a bit.
SCJP2 (1.4)
Stefan Elfvinge
Ranch Hand
Joined: Oct 29, 2001
Posts: 52
posted
0
Thanks, but I'm still a little confused! Do you mean static when you write (non-local)?? What gets so messy and overhead to synchronize the doGet, doPost- methods???..don't understand...but I assume you don't mean actually writing the keyword???!!! Is it JVM that's gonna have to deal with the messy & overhead part??? /gettingthere
Steve Granton
Ranch Hand
Joined: Jan 13, 2002
Posts: 200
posted
0
Hello, Generally there is only one instance of a servlet to service requests in different threads. However, you call mark a servlet as being Single threaded using the javax.servlet.SingleThreadModel interface. Containers may follow one of the following approaches to ensure that each servlet instance is invoked in a separate thread: Instance Pooling - a number of instances of the servlet are maintained in a pool and allocated to a request as the container receives it. Request Serialization - requests are queued and wait for service Note, that the SingeThreadModel is resource intensive. I hope this helps. Cheers, Steve
Thanks, but I'm still a little confused! Do you mean static when you write (non-local)?? Both static and instance variables are shared between threads. Local variables ( inside methods ) are thread-safe
Michael
SCJP2
Stefan Elfvinge
Ranch Hand
Joined: Oct 29, 2001
Posts: 52
posted
0
Thanks, everybody! I'm getting there...but just one other thing. What if I override init(), like this: private Product p = null; public synchronized void init() throws ServletException { p = new Product(); } public synchronized void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); out = res.getWriter(); out.println("<html><head><title>Welcome to CASEMAN</title>"+ "<LINK REL=stylesheet HREF=\"/css/Caseman.css\""+ " TYPE=\"text/css\"></head><body bgcolor=#f5f5f5><center>"+ "<h1>Welcome to Caseman</h1>"+ "<table width=600 border=0 CELLPADDING=0 CELLSPACING=3 CLASS=\"Rub\">"+ "<tr><td colspan=2><hr></td></tr><tr><td width=300 align=right>Select Country or Product:</td>"+ "<td width=300 align=left><FORM action=\"/caseman/list\"><SELECT NAME=product>"); Enumeration enum = p.getAllProducts().keys(); while(enum.hasMoreElements()) { String productId = (String)enum.nextElement(); String pname = (String)p.getAllProducts().get(productId); int pid = Integer.parseInt(productId); out.println("<option value =\""+ pid +"\">"+ pname +"</option>"); } out.println("<option value =\"0\">"+"All Cases"+"</option>"+ "</select><input type=submit value=Go!></td><tr><td colspan=2><hr></td></FORM></CENTER></body></html>"); out.close(); } } Wouldn't this be threadsafe???
Toby Davis
Ranch Hand
Joined: Apr 09, 2002
Posts: 65
posted
0
Don't sychronize the servlet's overriden methods, just use sychronize blocks within the methods. Example within your doGet():
Your Enumeriaton object was instantiated as a local (within the doGet() method) so it doesnt' have to be sychronized. It seems that your Product member is the only one that's a non-local. Say, if you add additional code to your doGet() method that is not accessing non-local variables, it won't fall under unneccessary sychronization. Reduces the overhead. Someone correct me here if I'm wrong here, please. ---
Stefan Elfvinge
Ranch Hand
Joined: Oct 29, 2001
Posts: 52
posted
0
Thanks! I thought synchronized only could be used in method signatures. Another question: The init() is only invoked when I refresh the page? Is the "first" page generated from some cache, or what's the deal here??? By the way, my PrintWriter is non-local, is that a thread-problem issue as well?
Toby Davis
Ranch Hand
Joined: Apr 09, 2002
Posts: 65
posted
0
Originally posted by Stefan Elfvinge: By the way, my PrintWriter is non-local, is that a thread-problem issue as well?
Create it within your doGet(), don't make it a non-local. --- [ April 19, 2002: Message edited by: Toby Davis ]