Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
Back to Web Scripts.
NOTE: This document describes features found in Alfresco v3 onwards (Older versions: v2)
The Web Script framework is the engine for the registration and execution of Web Scripts. This page describes the architecture of the engine and how it can be configured.
Before diving into the architecture of the framework it's worth reviewing the flow of execution when a Web Script is called.
WebOrientedRestStyleArchitecture.jpg
1. A request for a given URI arrives at the Web Script Runtime.
2. The Runtime finds the appropriate Web Script for the URI. If one is found, the Runtime executes the Web Script but only after successfully authenticating first, if required. The first step of execution is to invoke the JavaScript bound into the Web Script.
3. With JavaScript, you have access to a set of Alfresco services. When hosted within the Repository server you can search for information, navigate around the repository, modify information, create new documents, set properties on those documents, move data around, and delete data, plus access to all other Repository services. Outside of the Repository you can invoke remote services such as those by the Repository server.
4. The results from the JavaScript are rendered using FreeMarker response templates. The response format may be one of HTML, ATOM, XML, RSS, JSON, CSV, or any combination of these. You must provide the appropriate templates.
5. The Web Script Runtime sends the rendered results back via a response using the same protocol as the URI request.
6. The Web Script client receives the response in the requested format.
In Alfresco v3, the Web Script framework architecture was refactored to allow the hosting of it in any environment, not just the Alfresco Repository server. This opens the door to applying Web Scripts to all sorts of problems (not just data services in the Repository) such as User Interface rendering in a presentation tier. In fact, the Alfresco SURF Platform, a web application framework hosts the Web Script framework for re-usable UI components.
Although Web Scripts are accessible via HTTP, their URI addressability means they can actually be hosted in a number of different environments (and therefore accessed via a protocol appropriate to the environment). The Web Script framework separates the notion of a Web Script (that is, a unit of work) and its environment (that is, the host within which the unit of work is executed), which is known as a Web Script Runtime. The most commonly used run-time is the Servlet run-time which supports the HTTP protocol for access.
A typical deployment includes an Alfresco Repository server hosting data Web Scripts with one or more Alfresco clients hosting presentation Web Scripts where communication between the two is over HTTP. The Alfresco Repository utilises the Servlet Run-time whereas a remote Web Client utilises the SURF Run-time for hosting Web Scripts. However, this is just one of many options given the following available Web Script Runtimes:
It's important to note that presentation Web Scripts may be hosted in multiple environments without code change. For example, a portlet style Web Script such as 'My Tasks' which is self-contained from a user interface perspective may be developed once, but deployed as a Share Dashlet, JSR-168 portlet or URI addressable HTML page.
The Web Script framework is a Spring configured engine consisting of the following high-level components:
Most components are an implementation of an interface. This allows alternative component implementations for each environment within which to execute Web Scripts. Responsbilities of each component are:
We've already seen there are several types of Runtime available out-of-the-box. These Runtimes can be setup in conjunction with one the following out-of-the-box Containers:
All of these components are bound together via Spring configuration. The vanilla Web Script framework suitable for building User Interface components which can be housed in any environment is defined in
webscript-framework-application-context.xml
An extended version of the binding to support Repository embedding (and the Alfresco RESTful API) is defined in
web-scripts-application-context.xml
Finally, an Alfresco SURF binding to support web page rendering is defined in
web-framework-application-context.xml
Web Scripts logging is controlled via the following log4j entries:
To execute Web Scripts behind a firewall or proxy, you must first provide your public Web Server address, so that any links generated by Web Scripts refer back to the public server.
This is achieved by editing (or providing a custom):
webscript-framework-config.xml
and providing the host details in the following:
<config evaluator='string-compare' condition='Server'>
<!-- The public web server hosting this web client -->
<server>
<scheme>http</scheme>
<hostname>anexample</hostname>
<port>8080</port>
</server>
</config>
All Web Script URLs support the format argument for specifying the response type.
Formats available 'out-of-the-box' are:
e.g.
GET http://<host>:<port>/<contextPath>/<servicePath>/helloworld?to=fred&format=xml
GET http://<host>:<port>/<contextPath>/<servicePath>/helloworld.xml?to=fred
New response formats may be supported by declaring a 'Format Map' Spring Bean as follows where format short names are mapped to mimetypes
<bean parent='webscripts.formatmap'>
<property name='formats'>
<props>
<prop key='wav'>audio/x-wav</prop>
</props>
</property>
</bean>
Multiple beans may be declared.
A custom 'Format Map' may be provided for a given user agent
<bean parent='webscripts.formatmap'>
<property name='agent'><value>MSIE</value></property>
<property name='formats'>
<props>
<prop key='atom'>text/xml</prop>
</props>
</property>
</bean>
Valid agent values are (currently):
The Servlet Runtime maps HTTP requests to Web Scripts.
It's configured just as any other servlet in web.xml:
<servlet>
<servlet-name>WebScriptServlet</servlet-name>
<servlet-class>org.alfresco.web.scripts.WebScriptServlet</servlet-class>
<init-param>
<param-name>authenticator</param-name>
<param-value>webscripts.authenticator.basic</param-value>
</init-param>
</servlet>
The following initialization parameters are supported:
Multiple Web Script servlets may be configured, allowing multiple url mappings where each mapping may use a different authenticator.
<servlet-mapping>
<servlet-name>WebScriptServlet</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
The following pre-defined Web Script are available:
See Surf Platform for details.
The JSR-168 Runtime maps a portlet to a Web Script.
A JSR-168 proxy portlet class is provided which may be configured as follows:
<portlet>
<description>A Portlet</description>
<portlet-name>Portlet Name</portlet-name>
<portlet-class>org.alfresco.web.scripts.portlet.WebScriptPortlet</portlet-class>
<init-param>
<param-name>authenticator</param-name>
<param-value>webscripts.authenticator.jsr168.webclient</param-value>
</init-param>
<init-param>
<name>scriptUrl</name>
<value>/alfresco/service/portlet/aportlet</value>
</init-param>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>VIEW</portlet-mode>
<portlet-info>
<title>Portlet Title</title>
<short-title>Portlet Short Title</short-title>
</portlet-info>
</portlet>
Note: For versions beyond 3.3 the WebScriptPortlet class has been moved to Spring Surf. Instead use:
<portlet-class>org.springframework.extensions.webscripts.portlet.WebScriptPortlet</portlet-class>
The following initialization parameters are supported:
The JSF Runtime maps a JSF component to a Web Script.
It's configured as follows within a JSP:
<web script url>' />
The following parameters are available:
Authentication is handled by the Alfresco Web Client.
Alfresco is a secure server requiring authenticated access.
The Web Script framework defers authentication to a plug-in Authenticator. By default, Basic HTTP Authentication is activated. See available Runtimes for information on how to change the authentication mechanism in each runtime.
Other forms of authentication will also be considered:
(id: webscripts.authenticator.basic)
This authenticator supports HTTP Basic Authentication. The authorisation header must contain either:
For restricted environments that do not allow the setting of HTTP Request Headers, a ticket may be passed via the URL argument 'alf_ticket'.
(id: webscripts.authenticator.webclient)
This authenticator relies on the authentication mechanism configured into the Alfresco Explorer web client. If login is required, a redirect to the Alfresco Explorer login page is made.
(id: webscripts.authenticator.jsr168)
This authenticator relies on the user name setup by the JSR-168 runtime. It assumes the user has already been authenticated by the Portal. The Alfresco Repository executes in the context of the Portal user.
(id: webscripts.authenticator.jsr168.webclient)
This authenticator ensures that the Alfresco Explorer web client user context is kept in sync with the Portal user. This allows Web Scripts that depend on Alfresco Explorer functionality to be used within the Portal.
Note: It is only possible to use this authenticator in the repository tier, not the presentation tier.
The Presentation Container is a vanilla container which provides basic support to Web Scripts for calling remote data sources. Its simplicity makes it ideal for hosting Web Scripts in any environment.
The Repository Container is a specialised container for embedding only in the Alfresco Repository. It hooks directly into Alfresco Repository support for transactions and authentication. It also provides Repository specific root objects to Controller Scripts and Templates.
The Web Script Framework has several Service Provider Interfaces for extending or replacing the behaviour of the framework. You will need to understand how to configure Spring and develop Java code to carry out this kind of change.
An Authenticator simply has to implement the interface:
org.alfresco.web.scripts.Authenticator
All context required by the implementation should be passed in at construction time. Note, the Authenticator is constructed by the Runtime. There's only method to implement.
/**
* Authenticate Web Script execution
*
* @param required required level of authentication
* @param isGuest is Guest accessing the web script
*
* @return true if authorised to execute the script, false otherwise
*/
public boolean authenticate(RequiredAuthentication required, boolean isGuest);
The required parameter is an enumeration of the <authentication> value defined in the Web Script Description Document.
A Web Script Runtime is implemented by deriving a Java class from:
org.alfresco.web.scripts.Runtime
This is an abstract class requiring the following methods to be implemented:
/**
* Get the web script method e.g. get, post
*
* @return web script method
*/
protected abstract String getScriptMethod();
/**
* Get the web script Url
*
* @return web script url
*/
protected abstract String getScriptUrl();
/**
* Create a web script request
*
* @param match web script matching the script method and url
* @return web script request
*/
protected abstract WebScriptRequest createRequest(WebScriptMatch match);
/**
* Create a web script response
*
* @return web script response
*/
protected abstract WebScriptResponse createResponse();
/**
* Create a Web Script Authenticator
*
* @return web script authenticator
*/
protected abstract Authenticator createAuthenticator();
Implementations of:
org.alfresco.web.scripts.WebScriptRequest
org.alfresco.web.scripts.WebScriptResponse
org.alfresco.web.scripts.Authenticator
are also required as they are instantiated by createRequest, createResponse and createAuthenticator respectively. The helper class:
org.alfresco.web.scripts.WebScriptURLRequest
provides a skeleton implementation of WebScriptRequest given a URL string.
The following pattern is used to execute a Web Script via a Web Script Runtime:
WebScriptRuntime runtime = new CustomWebScriptRuntime(...);
runtime.executeScript();
Runtime context is passed in via the constructor, for example, for a servlet, the HttpServletRequest and HttpServletResponse.
A new Web Script Runtime must be instantiated for each invocation (where the context changes), for example, for each servlet request.
A Web Script Container is implemented by deriving a Java class from:
org.alfresco.web.scripts.RuntimeContainer
This is an abstract class requiring the following methods to be implemented:
/**
* Execute the script in the context of the provided request and response
*
* @param scriptReq
* @param scriptRes
*/
public void executeScript(WebScriptRequest scriptReq, WebScriptResponse scriptRes, Authenticator auth)
throws IOException;
A Format Reader simply has to implement the interface:
org.alfresco.web.scripts.FormatReader
It has to implement the following methods:
/**
* Gets the source mimetype to convert from
*
* @return mimetype
*/
public String getSourceMimetype();
/**
* Gets the Java Class to convert to
*
* @return Java Clas
*/
public Class<String, Object> createScriptParameters(WebScriptRequest req, WebScriptResponse res);
Format Reader implementations are registered via Spring configuration:
<bean id='...' parent='webscripts.adaptorset'>
<property name='readers'>
<list>
<bean class='x.x.x.CustomFormatReader'/>
</list>
</property>
</bean>