Seems reasonable, however for me the problem here is that if you put getDevice() in a base class with common functionality then for every device type that may be returned you will have to create a copy of the jsp and this may need maintenance in time (or assuming it is the same jsp then maybe Ant could do copy it as part of the build). Whilst you could override getDevice in actions where you know the views are common (e.g. the same value is returned), your action (controller layer) would now contain code related to the view layer which for me is not ideal.

For example a doLogin action should do just that - log in a user, so either the user is logged in (return success) or there was a problem (return input). Once this has been tested it can be stored in cvs and left well alone, perhaps reused in multiple projects etc. Likewise being able to reuse exisiting actions without having to introduce a base class or modify them to implement an interface is preferred.

What I'm looking for is a solution where the actions are device unaware and it is up to the view and view mapping layer to sort this out. Where possible I'd like to reuse the same view (and path to it) and only handle cases where there is actually a different view for some devices.

Greg Lindholm wrote:
I've got the same situation and plan on handling by making the the
result location dynamic by adding a ${device} to the path.

   <action name="login" class="mypackage.LoginAction">
       <result name="success">/${device}/index.jsp</result>
   </action>

In my actions I will have a getDevice() which will return a string
(e.g. "iPhone" or "blackberry" etc.) based on the User-Agent or
x-wap-profile.  I will use an interceptor that reads the user-agent
etc and determines the device type and injects that into my actions.


On Fri, Jan 29, 2010 at 5:57 AM, Marcus Bond <mar...@marcusbond.me.uk> wrote:
Thanks for the info Andy, the interceptor seems an appropriate thing
although it does mean there are multiple mappings in struts.xml. This seems
at least a way that allows a site to grow in terms of new views without
impacting upon the application code or exisiting views.

Thinking about it this could be made generic with a little design such that
this result modification could be defined in (yet) another xml file, all it
would really need in my case (as there are not any security checks to do and
it is just a mapping) is to know for each action / result pair an
alternative result to return.

New class (say UserAgentResultListener) and a config file something along
the lines of that shown below, perhaps allowing use of regular expressions
for user agents..

<result-intercept action="myaction">
  <result value="success">
     <alternative>
         <user-agent>*blackberry*</user-agent>
         <result>success_blackberry</result>
    </alternative>
     <alternative>
         <user-agent>mobile6*</user-agent>
         <result>success_windowsmobile</result>
    </alternative>
     <alternative>
         <user-agent>foo</user-agent>
         <result>bar</result>
    </alternative>
  </result>
</result-intercept>

I can imagine others have had to do something similar in terms of delivering
different views to the same action depending upon user agent so it would be
good to get some community involvement.. I'd happily code it up.

Marcus

Andrew Sykes wrote:
There are  couple of ways I can think of to do this, but they're ugly:
- JSP level logic to render the page differently - dont want it, I'd
rather individual jsp's for each supported device (or family) as this
allows developers who are working on targeting a site to a specific
device to concentrate on that device.
- Tiles template level logic - again not ideal as I would like to be
able to use specific templates for device types.

As you rightly say, this is a maintenance nightmare.


Better but not perfect would be some sort of post action result
modifying interceptor such that in the struts.xml I could define a
number of different result mappings such as success, success_winmob,
success_blackberry_storm and have the result string that has been
returned from the action (success) modified by some sort of interceptor
(e.g. appending the suffix prior to struts mapping it off to a view)  -
the filter itself could be configured as to whether or not to alter
result strings based on the action and the user device. - Is it possible
to modify the result string post action but prior to struts resolving
the mapping? And if so would I have access to the the name of the action?


You can attach PreResultListeners[1] onto interceptor & action stack
executions. These execute after an action is executed, but before the
result is rendered. At this point, you are free to reach in and fiddle
with the action's returned result code. You can get the action's name if
you require, and manipulate the action in any way - it can be fetched from
the ActionInvocation.

I've used this feature in the past to perform a final "security
checkpoint" on any item being pulled from a database - the
PreResultListener examines the action (by reflection or otherwise) to find
the object, and checks the user is allowed to retrieve it.

Your idea is probably the sanest way to do it. Write an interceptor[2]
that gets the HttpRequest[3] object, and examines the user agent to
determine what kind of device is making the request. Then it attaches an
appropriate PreResultListener to the stack (for example, you could have
individual subclasses for each device type, and maybe configure them with
a string representing the version, which the PreResultListener uses in its
internal logic).

The PreResultListeners examine the action's result, and if it's success
they modify it to success_devicetype_version, which corresponds to the JSP
/WEB-INF/jsp/devicetype/version/success.jsp, for example. The only ugly
part of this is you'll have lots of results defined for each action in
struts.xml, but at least you have sane separation of your JSPs.

HTH,
Andy.

[1]
http://struts.apache.org/2.1.8.1/docs/can-we-access-an-actions-result.html
[2] http://struts.apache.org/2.1.8.1/docs/interceptors.html
[3]

http://struts.apache.org/2.1.8.1/docs/how-can-we-access-the-httpservletrequest.html


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org



__________ NOD32 4817 (20100129) Information __________

This message was checked by NOD32 antivirus system.
http://www.eset.com




---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org



__________ NOD32 4818 (20100129) Information __________

This message was checked by NOD32 antivirus system.
http://www.eset.com





---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org

Reply via email to