org.apache.shale.remoting.package.html Maven / Gradle / Ivy
This package contains interfaces and APIs to support access for remoting
(client side components that need to perform server side activities and/or
retrieve information on a background thread). A JavaServer Faces
PhaseListener
is used to gain control at the end of the
Restore View phase of the request processing lifecycle, and
determine whether or not the view identifier of the requested
view now matches one of a set of configured patterns. When a match is
detected, control of this request is handed over to a configured
Processor instance, which can take complete
responsibility for creating the response for this request (and then
calling FacesContext.responseComplete()
to tell JSF this has been
done).
Concrete Processor Implementations
You can define your own Processor implementations,
and map them to requests as shown below. Alternatively, the following concrete
implementations are available out of the box for your use:
- ClassResourceProcessor -
Serves static resources (such as stylesheets or JavaScript source files)
from the web application classpath. In other words, resource files can
be packaged inside a JAR file that is included in the
/WEB-INF/lib
directory, without requiring the developer to
modify their build script to extract the resources into the webapp root
directory or a specially configured subdirectory.
- WebResourceProcessor -
Serves static resources (such as stylesheets or JavaScript source files)
from the web application's document root. This is essentially the same
as allowing your servlet container's default file-serving servlet to
serve the resources, but allows operation in scenarios where such a
file serving servlet has not been configured.
- MethodBindingProcessor -
Translates the resource portion of the URL (see examples below) into a
JavaServer Faces method binding expression that points at a
public method taking no parameters, and then executes a call to this
method. As a result of evaluating the method binding, it is possible
that the JavaServer Faces managed beans facility will be
invoked to create and configure the bean containing the called method.
- ChainProcessor - Translates the
resource portion of the URL into execution of an appropriate
Commons Chain
Chain
or Command
from an appropriate
Catalog
.
The static resource serving Processor implentations
share the following features:
- Disallow access to prohibited resources (web application resources
under
/WEB-INF
or /META-INF
, Java class
files, and JSP source files).
- Set the content type of the response based on the extension portion
of the resource identifier. This is done by first consulting the
servlet or portlet container (which supports mapping of extensions
to content types with a
<mime-type>
element in the
web application deployment descriptor), and then by consulting a
fallback list of mappings for common types of resources.
- Support browser caching of static content, by watching for incoming
requests that contain an
If-Modified-Since
HTTP header,
and returning an HTTP "not modified" (304) response if this application
has not been restarted since the resource was served to this client.
- Requests for non-existent resources will return a standard HTTP
"not found" (404) response.
- Standard servlet access control features may be applied to the served
resources, by using standard security constraint elements in the web
application deployment descriptor.
The dynamic logic invoked by
MethodBindingProcessor can use any technique it desires to create the
content for this response. Available options (starting with the one that is
recommended best practice) include:
- For a text response, acquire a
ResponseWriter
instance
and use its methods, just as a Renderer
would:
FacesContext context = FacesContext.getCurrentInstance();
ResponseWriter writer = (new ResponseFactory()).getResponseWriter(context, "text/xml");
writer.startDocument();
...
writer.endDocument();
writer.close();
- For a binary response, acquire a
ResponseStream
instance
and use its methods:
FacesContext context = FacesContext.getCurrentInstance();
ResponseStream stream = (new ResponseFactory()).getResponseStream(context, "image/gif");
stream.write(...);
...
stream.close();
- Stash relevant model data (typically in request scope), and then forward
to a JSP page (with either JSF components or JSTL tags coupled with EL
expressions) that will produce the actual response:
FacesContext context = FacesContext.getCurrentInstance();
context.getExternalContext().dispatch("/results.jsp");
- Access the response object from the external context, and acquire a
writer or stream from the response object directly. Note that this
technique, unlike those illustrated above, requires you to program
specfically to either the servlet or portlet response APIs.
Before returning, the dynamic logic should call responseComplete()
on the FacesContext
instance for the current request, to bypass
the remaining phases of the JavaServer Faces request processing lifecycle.
Configuring Remoting Support
In order for a request URI to be processed at all by the Shale remoting
facilities, it must match the mapping for FacesServlet
that is
already defined in /WEB-INF/web.xml
. Once that occurs, JSF will
have constructed a corresponding view identifier that can be retrieved by
calling:
String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
This view identifier is then compared to a set of matching patterns which,
like servlet mappings, can be either prefix matched (/foo/*
) or
extension matched (*.foo
). If the view identifier matches, it will
be transformed into a corresponding resource identifier that is passed
to the process()
method of an appropriate
Processor instance.
Mapping of view identifiers to resources is configured by specifying comma
delimited lists of "pattern:classname" pairs for the following context initialization
parameters in /WEB-INF/web.xml
. For each of these parameters that
is not specified, the value illustrated here will be the default (WARNING
- this decision may be changed later, so double check the latest documentation):
<context-param>
<param-name>
org.apache.shale.remoting.CLASS_RESOURCES
</param-name>
<param-value>
/static/*:org.apache.shale.remoting.impl.ClassResourceProcessor
</param-value>
</context-param>
<context-param>
<param-name>
org.apache.shale.remoting.DYNAMIC_RESOURCES
</param-name>
<param-value>
/dynamic/*:org.apache.shale.remoting.impl.MethodBindingProcessor
</param-value>
</context-param>
<context-param>
<param-name>
org.apache.shale.remoting.WEBAPP_RESOURCES
</param-name>
<param-value>
/webapp/*:org.apache.shale.remoting.impl.WebResourceProcessor
</param-value>
</context-param>
In addition, you can configure the following additional context initialization
parameters:
org.apache.shale.remoting.OTHER_RESOURCES
- configuration
pairs as described above, which will be marked with the "other"
mechanism type. No default value.
org.apache.shale.remoting.MAPPING_CLASS
- fully qualified
classname of class used to create Mapping
instances to record configuration information. If not specified, the
MappingImpl class will be used.
org.apache.shale.remoting.MAPPINGS_CLASS
- fully qualified
classname of class used to create a Mappings
instance to record configuration information. If not specified, the
MappingsImpl class will be used.
Once the configuration information has been processed (which will occur on
the first JSF request after the application has started), an instance of
Mappings will be stored as an application scope
parameter under the key identified by Globals.MAPPINGS_ATTR
which
contains all of the configuration information being used. This instance might
be useful, for example, to a JSF component that wishes to dynamically determine
the appropriate mapping for class resources.
Example URLs
Given the default resource mappings described above, and assuming that the
developer has mapped FacesServlet
to the *.faces
pattern, the following request URLs will be mapped to appropriate resources
and processed as follows:
http://localhost:8080/myapp/dynamic/foo/bar.faces
Constructs a method binding expression #{foo.bar}
and then
executes it. This will cause the bean instance at attribute name foo
to be located (or created, if necessary), and then the public bar()
method, which takes no parameters, will be called on that instance.
http://localhost:8080/myapp/static/mycompany/mypackage/MyScript.js.faces
Locates and serves a static resource (/mycompany/mypackage/MyScript.js
)
from the web application class loader, which will therefore locate such resources
in the /WEB-INF/classes
directory, or packaged in a JAR file in the
/WEB-INF/lib
directory.
http://localhost:8080/myapp/webapp/resources/MyScript.js.faces
Locates and serves a static resource (/resources/MyScript.js
)
from the document root of the web application.