Hey, I like your last hacky way. but I am just so worried if:
1) I can trust the thread.hashCode() as key?
2) If I guess it right, I think I need to remove the ac from the Map when
the thread exits perform(). Memory leak may cause if it fails to remove.
But I still love it. Do you have any running application that is using this
method?
Thanks Andrew!
Billy Ng
----- Original Message -----
From: "Andrew Hill" <[EMAIL PROTECTED]>
To: "Struts" <[EMAIL PROTECTED]>
Sent: Friday, July 04, 2003 3:49 AM
Subject: RE: extending Action problems
> Almost - but the getRequest(ac) is redundant - you would just call
> ac.getRequest() when you needed the request as youve passed in ac as a
> method parameter.
>
> You will note though that you still have to pass the ac parameter to any
> method that needs access to the stuff it wraps.
>
> ie:
> public ActionForward perform(ActionMapping mapping,
> ActionForm form,
> HttpServletRequest req,
> HttpServletResponse resp) {
>
> ActionContext ac = new ActionContext(mapping, form, req, resp);
> process(ac);
> etc..
> }
>
> private void process(ActionContext ac)
> {
> String bob = ac.getRequest().getParameter("bob");
> etc....
> }
>
> What you really really want to be able to do is:
> private void process()
> {
> String bob = getRequest().getParameter("bob");
> }
> isnt it? ;-)
>
> but as you saw already that simply wont work with a singleton Action -
only
> way you can deal with this is either passing one or more parameters to
> methods in Action that need them OR modifying the RequestProcessor to
return
> new instances of your Action for each request - that wouldnt need much
code
> to achieve, but if your cautious Id suggest you stick with a parameter
> passing methodology.
>
> Well, I suppose there is one way I can think of to do it without having to
> pass around the ac as a param - but its an evil hack and Im including it
> more for your amusement than for your education!
>
> <evil disclaimer="dont try this at home kids" tested="no">
> Put your ActionContext instance into the servlet context in perform()
keyed
> by the threads hashcode. Provide a method getActionContext() in your base
> action to retrieve it. Now you can get it from any method in your action
> just by calling getActionContext() without having to pass it around in a
> param.
> </evil>
>
> -----Original Message-----
> From: Billy Ng [mailto:[EMAIL PROTECTED]
> Sent: Friday, 4 July 2003 18:19
> To: Struts Users Mailing List; [EMAIL PROTECTED]
> Subject: Re: extending Action problems
>
>
> Sorry, Andrew! I am a little bit slow. Please review it if I understand
> what you told me with the following code.
>
> public abstract class ActionBase extends Action {
>
> protected abstract void process() throws Exception;
>
> public ActionForward perform(ActionMapping mapping,
> ActionForm form,
> HttpServletRequest req,
> HttpServletResponse resp) {
>
> ActionContext ac = new ActionContext(mapping, form, req, resp);
> process(ac);
> }
>
> public HttpServletRequest getRequest(ActionContext ac) {
> return ac.getRequest();
> }
>
> ........
> }
>
>
>
>
> ----- Original Message -----
> From: "Andrew Hill" <[EMAIL PROTECTED]>
> To: "Struts Users Mailing List" <[EMAIL PROTECTED]>
> Sent: Friday, July 04, 2003 2:42 AM
> Subject: RE: extending Action problems
>
>
> > Yes, this is a quite annoying feature of the singleton nature of Actions
> > (and given the efficiency of modern JVMs at instantiating and garbage
> > collecting there is jolly good argument for changing the
RequestProcessor
> to
> > instantiate new instances of Action for each request (and do feel free
to
> > try this at home kids!) - though Im getting off topic here).
> >
> > One way of dealing with this is to create a bean (or bean like object)
> that
> > has the getters and setters you need, and to pass this to any method in
> your
> > action that needs it. You instantiate the object at the start of
perform()
> > (or execute() method in struts1.1) and then pass the reference to
methods.
> >
> > In my app I have an object for this task which I named ActionContext -
> this
> > basically just wrapped a Hashmap into which I could insert/retrieve
stuff
> > with ActionContext.setAttribute, getAttribute, and I also has specific
> > getters for the perform signature objects you mentioned - ActionForm,
> > ActionMapping, HttpServletRequest and HttpServletResponse references -
> > (which are passed to its constructor) - so you still have to pass one
> > reference around as a parameter - but its a lot less typing than 4 - and
> its
> > a great place for putting other stuff as well that is internal to the
> action
> > (and for which you would rather not use the request attributes for
reasons
> > of scoping purity). And of course since the object is instantiated in
the
> > action and is only used in that thread and is garbage collected at the
> end,
> > it does not suffer the thread safety constraints you encountered.
> >
> > <btw>
> > If you want to store other stuff in it you may decide Hashmaps are a bit
> on
> > the heavy side - in which case you could have a superclass for your
> > 'ActionContext' that has getters for request,mapping,response,actionform
> and
> > instantiate classes (inner classes perhaps) in your Actions that add
> extra
> > properties specific to the needs of the action.
> > </btw>
> >
> > <drop-name celebrity="Ted Husted">
> > Actually I vaguely recall Ted mentioning in a reply to some post of mine
> > that he used a similar technique quite often - but it may have been
> someone
> > else so don't quote me on that!
> > </drop-name>
> >
> >
> > -----Original Message-----
> > From: Billy Ng [mailto:[EMAIL PROTECTED]
> > Sent: Friday, 4 July 2003 17:06
> > To: Struts Users Mailing List
> > Subject: extending Action problems
> >
> >
> > I make a mistake on extending the Action. I have the following code to
> set
> > the parameters in the perform() to the setters. At first, I wanted
> > whichever the classes that extends ActionBase can get the parameters by
> > simply calling the getters. However, the Action is a singleton, the
> > instance variables will be used by all actions. Anybody can give me
> > suggestion to make the getters to return the mapping, form, req, and
resp
> as
> > local variables?
> >
> > Thanks!
> >
> > public class ActionBase extends Action {
> >
> > private ActionMapping mapping;
> > private ActionForward actionForward;
> > private ActionForm form;
> > private HttpServletRequest req;
> > private HttpServletResponse resp;
> > private String view;
> >
> > protected void process() throws Exception {}
> >
> > public ActionForward perform(ActionMapping mapping,
> > ActionForm form,
> > HttpServletRequest req,
> > HttpServletResponse resp) {
> >
> > setActionMapping();
> > setActionForm(data);
> > setRequest(req);
> > setResponse(resp);
> > process();
> > }
> >
> > protected void setActionMapping(ActionMapping mapping) {
> > this.mapping = mapping;
> > }
> >
> > protected ActionMapping getActionMapping() {
> > return this.mapping;
> > }
> >
> > protected void setRequest(HttpServletRequest req) {
> > this.req = req;
> > }
> >
> > protected HttpServletRequest getRequest() {
> > return this.req;
> > }
> >
> > protected void setResponse(HttpServletResponse resp) {
> > this.resp = resp;
> > }
> >
> > protected HttpServletResponse getResponse() {
> > return this.resp;
> > }
> > }
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]