Kevin Duffey wrote:

> Hi all,
>
> Sorry to post this on the list, but I feel some of you who may have been
> following the discussion Craig, Daniel and I have been having might still
> like to follow along.
>
> So, I have the controller servlet working. A few questions have arised to a
> few posts I have seen you reply to.
>
> First, how do you use a Hashtable? If you already replied to this..my
> apologies. I found out my email program was on all weekend in a crashed
> state and I lost alot of email, nor could I get any, nor could I send. I
> recall you and Daniel both mentioning something about using a Hashtable as a
> lookup table (that could be loaded in from a database or a properties file,
> or xml file..whatever persistence desired) to figure out the action class to
> call?
>

I use a Hashtable for two different purposes:

* Map from the action name requested to the name of the
  Java class I want to execute for this Action name.  I usually
  configure this with servlet initialization parameters, but there's
  lots of choices.

* Map from the action name to the one and only existing
  instance of this action class.  I only create such an instance
  the first time this action is requested -- after that, I use the
  same one for all requests, to avoid the object creation
  overhead for at least this one object.

>
> Next, about the threading issues. I talked to one of our developers here, a
> pro with threading, and showed him my bit of code. He concurred with me that
> what I am doing "should" be thread safe. Basically, the ControllerServlet,
> by using the .newInstance() call, it creates a NEW action class for each
> request coming in. Because of this, fields of the class are ok to use on a
> per thread/request basis. You might have meant this in your explanation and
> I just wasn't clear. I did notice you also mentioned if the action class
> uses a bean, multiple requests "could" cause thread problems there if the
> bean contained instance fields as well. But again, the action class should
> normally create this bean...a new instance again, and place it in the
> REQUEST object. If this is the case, is there any reason to worry about
> threading issues?
>

If you create a new action instance for each request, then you can use instance
variables in that action.  The downside is that you are paying for that extra
object creation (and the ultimate garbage collection) every request.  This may not
cost enough to bother you, but it is a pretty easy optimization to design in from
the get-go.

One thing to note about multiple threads executing in the same action class at the
same time (I face this because I only create one instance) is that local variables
declared inside the perform() method ARE safe -- they are not shared because local
variables are allocated on the stack associated with each thread.  It's instance
variables where you run into grief.  As a practical matter, my perform methods
usually run 20-50 lines (all the "real" logic is done inside beans) so I've never
missed not being able to use instance variables in my actions.

One more cautionary note -- you still have to be aware of multithreading inside the
objects you store in a user's session.  It's entirely legitimate for multiple
requests from the same user to come in simultaneously -- think about a framed
presentation where more than one of the frames is accessing the user's session, or
where the user might have multiple browser windows open (which in most cases appear
to the server as being part of the same session).

>
> So, if in my action class, I do something like:
>
> public void perform(HttpServletRequest req)
> {
>   // do some logic
>   ...
>
>   // create bean
>   MyBean bean = new MyBean();
>   bean.setXXX(..);
>   bean.setYYY(..);
>   req.setAttribute("MyBean", bean);
>   setUrl("/forwardToThisPage.jsp");
> }
>
> Now, this is "close" to what I expect to have my action classes do. They
> figure out logic, create a new bean, populate it, set the forwarding url,
> and return back to the controller servlet, which then forwards to the proper
> JSP page depending on the setUrl() call in the action class or if an error
> occurs.
>

In my case, I pass the servlet, and the HttpServletResponse, as arguments to
perform() along with the request.  That means my action class can do the
RequestDispatcher.forward() thing for themselves -- the controller servlet doesn't
need any special "what do I do after the action method returns" stuff in it.  But
that's getting down to personal programming style.

>
> So, based on the above, isn't my bean thread-safe as well because its a NEW
> created object for each request?

More precisely, your action class is thread-safe because of this.

> I agree with Daniel in that everything
> should be put in the request scope.

Except for stuff you need to save past the end of this request -- that goes in the
session.

> When using Model 2, you already are
> forced to write the code that gets all the form parameters out of the
> request object when it comes in (part of the action class I
> believe..right?),

Yep.

> and thus, by populating the bean and putting it in the
> request, the JSP page will most likely use the bean at the request scope,
> fill in the values of another form (or possibly the same form if say an
> error occured and the page is being redisplayed) so that a subsequent
> request will contain those values where need be.
>

Yep.  Very common scenario -- just not the only one.

Just as an example, let's say you had a multi-page input form, because it was too
complex to get onto one page.  I would design a bean that represents the input
values for the entire multi-page form, and save it in the session as the user
navigates between the various pages with "Previous" and "Next" buttons.  When they
finally press SUBMIT, and after I process the completed form, the bean is removed
from the session because it's no longer needed.  (Note a sublte advantage of doing
this -- the business logic that actually processes the form does not know or care
that the actual UI was split across multiple pages or not; you can even change that
decision later without breaking the logic.  Another example of the benefit of
separating presentation logic from business logic.)

>
> Alrighty..thats it. Trying to keep these short. Hopefully my above
> explaination of why I think its thread-safe is accurate, but please
> elaborate on why it is/isn't good design/bad design, if its thread safe,
> etc. Also, if you could, is this basically what you are doing (and you too
> Daniel if you read this)? Keep in mind I am creating a simple (at this time)
> but definitely deployable working Model 2 layout that I should be able to
> use with other web applications, but that does indeed work with security,
> user-roles (whatever the heck these are), and does the job as you guys use
> it.
>
> Thanks so much for all of your emails. I know its taught me alot and
> enlightened me on a number of topics I was unclear about. I hope its doing
> the same for others reading this ongoing discussion.
>
> Take care.
>

No problem -- it's educational for all of us to explore these architectural
choices.

Craig

===========================================================================
To unsubscribe: mailto [EMAIL PROTECTED] with body: "signoff JSP-INTEREST".
Some relevant FAQs on JSP/Servlets can be found at:

 http://java.sun.com/products/jsp/faq.html
 http://www.esperanto.org.nz/jsp/jspfaq.html
 http://www.jguru.com/jguru/faq/faqpage.jsp?name=JSP
 http://www.jguru.com/jguru/faq/faqpage.jsp?name=Servlets

Reply via email to