On Thu, 27 Dec 2001, Jesse Alexander (KABS 11) wrote:
> Date: Thu, 27 Dec 2001 10:57:44 +0100
> From: "Jesse Alexander (KABS 11)" <[EMAIL PROTECTED]>
> Reply-To: Struts Developers List <[EMAIL PROTECTED]>
> To: 'Struts Developers List' <[EMAIL PROTECTED]>
> Subject: RE: [Design Discussion] Multiple Controllers Per Web App
>
> Hi,
>
> how about proposing to use only the "prefix"-noptation for the
> servlet-mappings (/do/... instead of /*.do).
>
> Then it might be possible to specify the mappings like:
>
> /(application_1)/* --> application-1 action-servlet
> /(application_2)/* --> application-2 action-servlet
>
> Wouldn't that make it easier. For bakward compatibility *.do
> still could be used and would drop back to old-style-struts.
>
There are two different types of "mappings" going on, and the choice of
what to do for each are independent:
* Mapping to the controller servlet (typically "*.do" or "/do/*" today),
that must conform to the rules of the servlet specification. Note that
this mapping does *not* apply to JSP pages.
* Associating the context-relative portion of the path to a request URI to
the particular sub-application it is part of. This includes *both*
requests to the controller (for that sub-app), as well as the JSP pages
that belong to it, in order to make all of the lookups work correctly
(for example, <bean:message> has to know what sub-application it is
part of in order to access the right message resources, and an Action
has to look up it's mappings in the table for this sub-app).
Let's look at a concrete example, and assume we were packaging all of the
existing Struts example web-apps as a sub-application inside a "/portal"
webapp. Assume the standard "*.do" mapping for the controller. Now, we'd
have request URIs like this:
/portal/index.jsp Portal home page
/portal/struts-example/index.jsp Example home page
/portal/struts-example/logon.do Example logon action
/portal/struts-example/registration.jsp Example app page
/portal/struts-example/saveRegistration.do Example app action
/portal/struts-upload/display.jsp Upload app JSP page
/portal/struts-upload/upload.jsp Upload app JSP page
/portal/struts-upload/upload.do Upload app action
If you wanted to use path-based matching for the actions, you'd need to
establish multiple servlet mappings to get it to work right:
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/struts-example/do/*</url-pattern>
</servlet-maping>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/struts-upload/do/*</url-pattern>
</servlet-mapping>
and the action URIs quoted above would become:
/portal/struts-example/do/logon
/portal/struts-example/do/saveRegistration
/portal/struts-upload/do/upload
without changing any of the JSP page mappings (from the servlet
container's perspective).
Bottom line -- you can still use either kind of mapping for the controller
with no difficulties. For associating requests with sub-apps, using a
path prefix seems like the only feasible strategy (and it's the strategy
employed in a couple of other frameworks that formally support the notion
of a sub-app).
> Just my 2cents...
>
> Alexander Jesse
>
Craig
> -----Original Message-----
> From: Ted Husted [mailto:[EMAIL PROTECTED]]
> Sent: Thursday, December 27, 2001 5:26 AM
> To: Struts Developers List
> Subject: Re: [Design Discussion] Multiple Controllers Per Web App
>
>
> +1 overall.
>
> Very much one of those brilliant ideas that only seem obvious after
> someone *else* brings it up.
>
> Though I wonder if we need to have a single servlet is catch all the
> requests and then do the mapping. What if the standard servlet-mapping
> for a sub-app matched their prefix, and we let the request be routed by
> the container? The specification says the longest one wins, so
> /this-prefix/*.do should be matched before *.do.
>
> A way to look at this is that given a WAR named
>
> {application-name}.war
>
> our URI breaks down to
>
> /(application-name}/{servlet-name}/{action-path}
>
> so we might have a configuration like
>
> <servlet>
> <servlet-name>default</servlet-name>
>
> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
> <init-param>
> <param-name>config</param-name>
> <param-value>/WEB-INF/conf/default.xml</param-value>
> </init-param>
> < ... >
> </servlet>
> <servlet>
> <servlet-name>logon</servlet-name>
>
> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
> <init-param>
> <param-name>servlet-context</param-name>
> <param-value>logon</param-value>
> </init-param>
> <init-param>
> <param-name>config</param-name>
> <param-value>/WEB-INF/conf/logon.xml</param-value>
> </init-param>
> <init-param>
> <param-name>default</param-name>
> <param-value>false</param-value>
> </init-param>
> < ... >
> </servlet>
>
> <servlet-mapping>
> <servlet-name>default</servlet-name>
> <url-pattern>*.do</url-pattern>
> </servlet-mapping>
>
> <servlet-mapping>
> <servlet-name>logon</servlet-name>
> <url-pattern>/logon/*.do</url-pattern>
> </servlet-mapping>
>
> I believe a "default" servlet with a *.do or /do/* servlet would then
> receive any requests not sent to a longer matching URI (e.g one with a
> servlet-name prefix).
>
> So, with the links being expanded to include the servlet-context (when
> non-blank), and the RequestURI being expanded to return the right
> configuration based on the expanded URI, we might be able to let the
> container do the matching in the normal course.
>
> I'd also suggest that we call multiple-servlet applications "sub-apps"
> or "apps", and reserve "application" to refer to that which could be
> placed into a single Web Application Resource file. Otherwise, it starts
> to get confusing.
>
> This is a *very* exciting idea. It neatly solves several problems, and
> open several new doors. Besides supporting team development, where each
> group can be working on parallel sub-apps, it also makes Struts
> "portlets" much simplier to do. We could start assembling applications
> out of components apps, and resuse code in bulk.
>
> We should give some thought early-on to what other API mechanisms Struts
> "portlets" might need. For example a customization resource to provide a
> common look and feel across sub-applications. This might mean a way to
> specify a global directory (or sub-app) for resources like stylesheets
> and images.
>
> Going the other way, teams working together on parallel sub-apps might
> also want to share message resources, so that if a key is not found in
> the sub-app message resource, it could check the "default" or some other
> global sub-app. The sub-app would then only have to define messages not
> carried in the global app.
>
> Ditto for forwards. If a forward is not found in the local app, should
> it try the global app?
>
> -Ted.
>
>
>
> "Craig R. McClanahan" wrote:
> >
> > One of the highly requested features for Struts has been the concept of
> > wanting to define multiple "applications" (or multiple "controllers")
> > within a single Struts-based web application. Implementing this feature
> > in the current controller servlet is pretty complicated, due to its
> > assumpations all over the code that there is only one controller.
> >
> > Recent discussions on the STRUTS-DEV list, some thought that Ted Husted
> > put in on the "ContextHelper" class recently checked in, and a little bit
> > of time (Sun is shut down this week, so I've got a little quality time to
> > put in on Struts) leads me to propose a way to accomplish the goals of
> > multiple applications, using a single controller servlet, in a way that
> > should remain backwards-compatible for current users (which is *always* a
> > very important consideration IMHO).
> >
> > The basic design would include the following elements:
> >
> > * Running multiple "applications" within a single web app will be
> > accomplished by defining each "application" to have a particular
> > prefix on the context relative path. Thus, a complete request
> > URI gets divided into:
> >
> > /{context-path}/{application-prefix}/{action-select-path}
> >
> > * When the controller processes an incoming request, it will parse
> > the request URI and try to match it to a particular "application
> > configuration" by matching against the application prefixes it
> > knows about, in a manner similar to how a servlet container figures
> > out which web app to run by matching against the context paths
> > that it knows about.
> >
> > * In addition to the defined application prefixes, there will be a
> > "default" application that processes all requests that cannot be
> > assigned to any other application. This default application will
> > be configured *exactly* as the current one-and-only application is
> > defined, thus maximizing backwards compatibility.
> >
> > * Each application that is defined will have its own struts-config.xml
> > file. The initialization parameters of the controller servlet will
> > define an application prefix, and corresponding path to the config file,
> > for each supported application.
> >
> > * Internally, all of the static configuration information from a
> > particular struts-config.xml file will be organized into a single
> > "application configuration" object. I've checked in a new package
> > of classes (org.apache.struts.config) to represent this data. Each
> > ApplicationConfig object will be exposed as a servlet context attribute,
> > rather than all of the individual objects (ActionMappings,
> > ActionForwards, and so on). LIKELY EXCEPTION: The actual
> > javax.sql.DataSource objects for connection pools.
> >
> > * All cases of "context-relative" paths in the current Struts environment
> > will be modified to be "application-relative" instead. This allows you
> > to configure an application's XML file completely independent of the
> > application prefix that will be assigned -- exactly the way a web app is
> > independent of the context path to which it is assigned. (Note also
> > that this still works for the "default" application -- think of this as
> > having a zero-length String as the prefix, so that all application
> > relative paths are actually context relative.
> >
> > * All logic in the existing classes (and custom tag implementations) that
> > currently looks up the configuration information in servlet context
> > attributes, or via method calls on ActionServlet, will need to be
> > modified to look up the info for the current application instead. To
> > facilitate this, we'll add a utility method to RequestUtils that looks
> > up the appropriate ApplicationConfig object for a given request URI.
> >
> > * Existing classes in org.apache.struts.action that represent the config
> > information will be deprecated in favor of the new classes in
> > org.apache.struts.config. The exception will be ActionMapping (because
> > it is passed as an argument to the perform() method of action classes),
> > but ActionMapping will be modified to subclass
> > org.apache.struts.config.ActionConfig instead of being its own class.
> > This maximizes backwards compatibility, but *will* require applications
> > to be compiled against the version of Struts that they are going to
> > be run against (not a big restriction, IMHO).
> >
> > What do you think? Does this sound like a strategy that can accomplish
> > the "multiple controllers" feature request without messing up existing
> > Struts based applications?
> >
> > Craig McClanahan
> >
> > --
> > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
> -- Ted Husted, Husted dot Com, Fairport NY USA.
> -- Custom Software ~ Technical Services.
> -- Tel +1 716 737-3463
> -- http://www.husted.com/struts/
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>