Jeromy Evans wrote:
Should I just send all "/widgets/*" to a single action that does it's own URL
parsing?
I think this is an argument for a custom action mapper that supports
your expressions. It's up to the mapper to parse the URL to extract the
namespace, action and params.
I thought that for a while when I composed my last message, but changed
my mind before I sent it. The problem is that I only want this funky
parse for urls that start with the plural form of my five nouns, which
could each be their own namespace if need be. The ActionMapper is
defined not per namespace but for the entire app. Is the
CompositeActionMapper what I'm looking for to get both? I can write my
own mapper that parses the url into tuples (like the
Restful2ActionMapper, but that uses a storage mechanism that won't mask
multiply-specified constraints), but have it return null if it doesn't
start with one of the magic 5 namespaces, and have CompositeActionMapper
allow normal parsing for the rest. (I'm also not sure how I'd configure
this custom mapper with the 5 magic names.)
But it's not really the mapping from url to action that is difficult
here -- there are exactly 5, and all 5 could use the same action. It's
the parameter parsing. And since I want to be able to have duplicates I
really don't want that part of the url space to be handled as normal
parameters, anyway. This makes me think that I don't want a custom
action mapping, just custom url parsing within my (1 or 5) action(s).
That's assuming that I can get the request to the right action in the
first place.
I'd start by looking at the parseNameAndNamespace method of
http://svn.apache.org/repos/asf/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
To get urls of the form "/user/bob.html" I've been using wildcards:
<package name="viewUser" namespace="/user" extends="default">
<action name="*" class="userAction" method="view">
<param name="username">{1}</param>
<result name="success">/WEB-INF/pages/viewUser.jsp</result>
<result name="badID">/404.jsp</result>
</action>
</package>
From reading the DefaultActionMapper source, I think a similar solution
like the following might result in it selecting the correct action mapping:
<package name="viewUsers" namespace="/users" extends="default">
<action name="*" class="elementListAction">
<param name="elementType">User</param>
<result name="success">/WEB-INF/pages/viewUserList.jsp</result>
<result name="badID">/404.jsp</result>
</action>
</package>
But I'm not sure (for example will that unreferenced wildcard cause
problems?). I guess it's time to stop reading code and start trying
stuff out :-)
NamedVariablePatternMatcher is interesting, as:
<package
name="viewUsers/friendOf/{username}/attendedEvent/{eventShortName}"
namespace="/users" extends="default">
<action name="*" class="elementListAction">
<param name="elementType">User</param>
<result name="success">/WEB-INF/pages/viewUserList.jsp</result>
<result name="badID">/404.jsp</result>
</action>
</package>
Would work (even if the order of those two constraints were reversed),
but it still would mask one of the constraints in my
/friendOf/joe/friendOf/amy example.
The patterns mentioned in the javadoc are assumed to be specified using
@Namespace within your action (rest/codebehind) but I suppose you could
specify them with namespace attributes in struts.xml too (I'm guessing)
as it all results in the same config.
Hrm...I'm confused why this is designed just for matching wildcards in
namespaces and not also in action names? In other words why must the
above be in it's own package instead of something like:
<action name="users/friendOf/{username}/attendedEvent/{eventShortName}"
class="elementListAction">
Hope some of this helps. I haven't tried anything as complicated or
flexible as you're doing with action params.
It's definitely led me to the right pieces of xwork/struts code to be
reading to better understand this stuff. I very much appreciate your
responses!
This all started with a custom tag to be able to drop in a view of some
collection in a page. For collections that are too big that code
generated by that tag only includes some values, but also adds
javascript to asynchronously fetch additional element blocks from the
server as they are needed. The urls fetched by the javascript didn't
have to be pretty, but now that I want to use this same mechanism to
generate pages the URLs are much more important. The changes here will
have to be mimicked in that tag so I can support fetching the next block
of values for friendOf/joe/friendOf/amy style collections...
I guess in the tag I'll have to put a setter for each of the bazillion
constraints, and make the setFriendOf() method add the argument into the
list so one value doesn't overwrite the previous one...So I should be
able to do this as long as
<myTagLib:myTag showMe="Users" friendOf="joe" friendOf="amy"/>
is valid (which I'm not sure it is). Guess I'll find out when I get
that far. If someone can tell me now that this is invalid I guess I can
change everything to /friendOf/amy,joe/attendedEvent/newYearsEve style,
which would enable me to use more of these tools, but would require me
to have a bazillion setConstraintName methods on my action, as well...
(I thank anyone that's read this far, whether or not you can offer any
advice!)
-Dale
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]