Web Scripts

cancel
Showing results for 
Search instead for 
Did you mean: 

Web Scripts

resplin
Intermediate
0 0 136K

{{Obsolete}}

Note: This topic has been added to the official documentation, and so this page is no longer maintained. The official documentation for Web Scripts in Alfresco 5.0 is here: http://docs.alfresco.com/5.0/concepts/ws-presentation-intro.html




Welcome to the Web Scripts WIKI, the home for all Web Script related documentation.

NOTE: This document describes features found in Alfresco v3 onwards (Older versions: v2)

Web Scripts FAQ


Table of Contents


Why Web Scripts?


Web Scripts allow you to:


  • Build custom URI-identified and HTTP accessible Content Management Web Services
  • Turn your Alfresco repository into a content management powered HTTP Server
  • Easily access, manage, and cross-link your content via a tailored RESTful API

You do not need tooling or Java knowledge. All you need is your favourite text editor or the Alfresco Explorer web client: no compilation, generators, server restarts, or complex installs.


Background

Alfresco Web Scripts (introduced in 2006) brought together the worlds of content repository and the web. There's a blindingly obvious synergy between the two. Consider the web. It's one huge single collection of inter-related documents. Physically, the documents are located in many machines, in many data centers across the globe, stored and managed with many types of software. And yet, to the user in their browser it's one huge collection with easy to click links. This logical simplicity is all due to the underpinnings of the web; HTTP, URIs and HTML (and other types of document e.g. XML). So, what has this to do with ECM repositories. ECM Repositories are containers of documents, important documents that are the heart of Enterprises. However, ECM Repositories have traditionally provided proprietary access points therefore restricting potential use of those documents. This is made worse when ECM Repositories multiply within the Enterprise. Those proprietary access points make it difficult to link documents between repositories. But, wait a minute, users on their home PCs can access the world's huge collection of documents just using their browser. Why can't it be that easy within the Enterprise?  

Traditional ECM Repository interfaces are APIs, a collection of programmer methods for interacting with the Repository.  These APIs are barriers to accessing the documents held within the Repository. You can't get to the documents unless you have a tool that can speak the API. Documents are often identified by some kind of repository-scoped identifier. This style of interface is broadly known as RPC (remote procedure call). It turns out that RPC is not particularly suited to providing the capabilities of the web where distribution and uniform access of content is key. The web underpinnings of HTTP, URIs and media types follow a style known as REST, which stands for Representational State Transfer. Procedure calls are no longer central. Instead, we have uniquely identified Resources (document, feed, stock price, person) via URIs, representations of those resources (HTML, Atom, JSON) containing links to other resources and a small well-defined uniform interface for access (HTTP GET, POST, PUT & DELETE). So, until ECM Repositories become RESTful, it will be difficult to write applications and services that can access all ECM managed content distributed across the Enterprise. Think back to the web. The very essence of a uniform interface gave birth to Google (a search for the world's documents), Digg (a rating system for the worlds documents) and Delicious (a bookmarking and categorization system for the worlds documents). Within the Enterprise, content oriented services such as Transformation, Encryption, Workflow, Entitlement and Deployment can flourish with a uniform interface.

Web Scripts provide RESTful access to content held within your Alfresco Enterprise Content Repository. This allows you to place controls on your enterprise content to manage it, and at the same time, provide uniform access for a wide variety of client applications and services e.g. browser, portal, search engine or custom application. Due to the inherent distributed nature of this interface, all Alfresco Content Repositories within the Enterprise can resemble one logical collection of inter-related documents, just like the web. And as with any other web citizen, you can apply web technologies such as caching, authentication, proxies, negotiation etc. to your repository resources.

With Web Scripts, you can either build your own RESTful interface using light-weight scripting technologies such as JavaScript and Freemarker, allowing you to arbitrarily map any content in the Repository to resources on the web, or you can use pre-built out-of-the-box Web Scripts that already encapsulate many of the mappings. In fact, CMIS (a proposed standard for ECM web services) is implemented in Alfresco as a series of Web Scripts.

Since 2006, Web Scripts proved themselves exceedingly useful and have been used in all kinds of solutions:


  • Integrating Alfresco with 3rd party systems
  • Providing feeds
  • Developing data services
  • Allowing Alfresco to act as a different kind of repository (eg. ActiveResource)
  • Developing UI services such as portlets
  • Customizing search
  • Acting as a back-end to client tools such as Orbean Forms
  • Office integration
  • Facebook application development
  • UI component building in Alfresco SURF, a web site construction platform

What's new in Web Scripts v3?


What is a Web Script?


A Web Script is simply a service bound to a URI which responds to HTTP methods such as GET, POST, PUT and DELETE.  While using the same underlying code, there are broadly two kinds of Web Scripts.


Data Web Scripts


Data Web Scripts encapsulate access and modification of content/data held in the repository therefore are provided and exposed only by the Alfresco Repository server. They provide a repository interface for client applications to query, retrieve, update and perform processes typically using document formats such as XML & JSON. Out-of-the-box, Alfresco provides a series of Data Web Scripts e.g. for tagging, activities, site management...


Presentation Web Scripts


Presentation Web Scripts allow you to build user interfaces such as a dashlet for Alfresco Explorer or Alfresco Share, a portlet for a JSR-168 portal, a UI component within Alfresco SURF, a Web Site or a custom Application. They typically render HTML (and perhaps include browser hosted JavaScript). Unlike Data Web Scripts, Presentation Web Scripts may be hosted in the Alfresco Repository server or in a separate presentation server. When hosted separately, the Presentation Web Scripts interact with Data Web Scripts. Out-of-the-box, Alfresco provides a series of Presentation Web Scripts e.g. Portlets, Office Integration, SURF Components...

See the Web Scripts FAQ for more information.


Implementation


The interface of a Web Script comprises of a URI, HTTP methods, and document types. This is all you need to know if you're just using a pre-built Web Script. However, if you want build your own RESTful interface, it has been made as simple as possible to construct your own Web Script. You do not need tooling or Java knowledge. All you need is your favourite text editor or Alfresco Explorer: no compilation, generators, server restarts, or complex installs.

A Web Script implementation consists of the following components (often summarized as MVC):


  • A description document, which describes the URI that will initiate the script. For example, the service is given a short name and description, along with authentication and transactional needs. URI bindings are described as URI templates.
  • An optional controller script, written in JavaScript, which will do the actual work. For example, the script may query the Alfresco repository to build a set of data items, known as a model to render in the response, or for URIs that intend to modify the repository (hopefully, PUT, POST & DELETE method bindings), the script may update the Alfresco repository. The JavaScript has access to all URI arguments, Alfresco services and repository data entry points.
  • One or more FreeMarker response templates, known as views (or Representations in REST parlance) that will render output in the correct format for your specific needs. For example, HTML, ATOM, XML, RSS, JSON, CSV, or any combination of these. The URL response is rendered via one of the supplied templates where the chosen template is based on the required response content-type or status outcome. The template has access to all URI arguments, common repository data entry points and any data items built by the optional controller script.

Advanced implementations may fall-back to Java.  The different components (description doc, controller, and templates) are tied together through a document convention.

Web Scripts are registered and executed by the Web Scripts Framework.


Alfresco RESTful API Reference


Out-of-the-box, Alfresco provides several RESTful APIs (built as Web Scripts):


How Do I Use a Web Script?


This section focuses on using pre-built Web Scripts. You will need to understand:


  • What is a URI
  • How to invoke HTTP methods such GET & POST from your environment of choice
  • Optionally, how to construct or parse XML & JSON if using Data Web Scripts

Basically, Web scripts are URI & HTTP accessible, so it is a case of putting together the correct HTTP request.  Each Web Script is uniquely identified by its URI, although some Web Scripts may support multiple URIs.


Where Can I Use a Web Script?


Web Scripts may be used in a number of environments:


Anatomy of a Web Script URI


Web Script URIs are of the form:

http[s]://<host>:<port>/[<contextPath>/]/<servicePath>/<scriptPath>[?<scriptArgs>]

Where:

host - name or address of server hosting the Web Script
port - port where Web Script is exposed on server
contextPath - path where application is deployed to, generally /alfresco
servicePath - path where Web Script service is mapped to, generally /service
scriptPath - path to Web Script (as defined by Web Script)
scriptArgs - arguments to pass to Web Script

Some examples:

http://localhost:8080/alfresco/service/api/path/Workspace/SpacesStore/Company%20Home/children
http://localhost:8081/share/service/mytasks?priority=1

Depending on where a Web Script is invoked, the URI may be absolute or relative.  In some cases Web Scripts may be deployed to the root application which means the contextPath is not required.

http://localhost:8080/service/api/path/Workspace/SpacesStore/Company%20Home/children

Some environments (such as Alfresco SURF and the Web Script Portal Runtime) only require the script path to identify a Web Script.

/api/path/Workspace/SpacesStore/Company%20Home/children

The servicePath is generally mapped to /service. However, the means for authenticating may be controlled via this path.


Listing Available Web Scripts


An index of all registered Web Scripts is available at the following URIs:

http://<host>:<port>/<contextPath>/<servicePath>/
http://<host>:<port>/<contextPath>/<servicePath>/index

Example:

http://localhost:8080/alfresco/service/index
http://localhost:8081/share/service/index

A description of each registered Web Script is provided including its URI(s) for calling the Web Script. Some URIs contain {tokens} - those are also valid URIs - they are expressed as URI Templates allowing for the URI path to be parameterized.

The index provides a view of Web Scripts by:


  • Package
  • URI
  • Family

Also, if there happens to be an issue with the registration of a Web Script, the index also provides a list of Web Scripts that failed registration.

Note: This index page is itself implemented as a Web Script

Note: The Alfresco RESTful API Reference pages in this WIKI are just index pages rendered as MediaWIKI markup instead of HTML


Authenticating


Web Scripts may require the caller to be authenticated. Each Web Script dictates its own authentication requirements. If a Web Script requires authenticated access and the call is unauthenticated an appropriate authentication process is initiated. Upon successful authentication the Web Script is invoked.

The style of authentication depends on the environment within which the Web Script is hosted e.g. within a servlet run-time HTTP Auth may be used. Within a portal run-time, the portal may decide. 


Repository Authentication Options

When Web Scripts are hosted within the Repository server two options are available for authentication.


  1. HTTP BASIC Authentication - the authentication process follows the handshake as defined by RFC2617
  2. Alfresco Explorer Authentication - the authentication process supported by the Explorer Web Client, that is the authentication mechanism as defined by the alfresco global properties authentication.chain.

The first is useful for external systems that wish to programmatically invoke Alfresco RESTfully (that is, using standard HTTP mechanisms), whereas the second is useful when single sign on is required across both the Alfresco Explorer Client and the Web Script, such as linking from the Explorer to a Web Script page.

The caller can choose which authentication option by specifying an appropriate <servicePath> in the Web Script URI.


  1. /service => HTTP Basic Authentication e.g. http://localhost:8080/service/api/path/Workspace/SpacesStore/Company%20Home/children
  2. /wcservice => Alfresco Explorer Authentication e.g. http://localhost:8080/wcservice/api/path/Workspace/SpacesStore/Company%20Home/children

Note: In both cases, the successful authentication may be remembered in the caller session, thus only requiring the authentication process to be initiated once


Pre-Authorized Calls

To force authenticated access specify the following URI argument:

alf_ticket=<ticket>

For example

http://<host>:<port>/<contextPath>/<servicePath>/api/path/Workspace/SpacesStore/Company%20Home/children?alf_ticket=<ticket>

Tickets may be established by the calling environment (e.g. Alfresco SURF) or explicitly using the Login Web Script APIs.


Guest Access

Web scripts may allow guest access.  To force guest access specify the following URL argument:

guest=true

For example

http://<host>:<port>/<contextPath>/<servicePath>/api/path/Workspace/SpacesStore/Company%20Home?guest=true

Content Negotiation and Response Formats


Each Web Script returns its result in a reponse stream. The result may be encoded in one or more formats (i.e. mimetypes) such as HTML, XML or JSON depending on the capabilities of the invoked Web Script.

If a Web Script call does not provide any hints on which response encoding to use, the Web Script uses its pre-defined default encoding. However, a client can provide the following hints:


  1. URL extension e.g. http://<host>:<port>/<contextPath>/<servicePath>/api/path/Workspace/SpacesStore/Company%20Home/children.atom
  2. Format Argument e.g. http://<host>:<port>/<contextPath>/<servicePath>/api/path/Workspace/SpacesStore/Company%20Home/children?format=atom
  3. Accept Header (as defined by HTTP 1.1)

Hints 1 & 2 specify a Web Script Format which a registered short name for a mimetype. The typical mimetypes are mapped:


  • html  => text/html
  • text => text/plain
  • xml  => text/xml
  • atom  => application/atom+xml
  • rss  => application/rss+xml
  • json  => application/json

Hint 3 is typically provided by a Web Browser, although may be controlled programmatically via many HTTP client libraries and is specified as a comma-separated of mimetypes and preferences.

Note: Each Web Script dictates which of the above hints are adhered to via its Web Script Description


Tunneling HTTP Methods


Not all clients can issue all HTTP methods. In the most severe case, a client may be restricted to GET and POST only. In this situation, web scripts provide two mechanisms for issuing any HTTP method via POST:


HTTP Request Header 'X-HTTP-Method-Override'

URI parameter 'alf_method'

Note: If both the header and query parameter are specified in the request, the header takes precedence over the query parameter.

In either case, the value is set to the HTTP method name to be invoked.

For example, if the HTTP DELETE method is not supported by a client, but the client wishes to delete a repository folder, the following may be issued:

POST X-HTTP-Method-Override=DELETE http://<host>:<port>/<contextPath>/<servicePath>/api/path/Workspace/SpacesStore/Company%20Home/

POST http://<host>:<port>/<contextPath>/<servicePath>/api/path/Workspace/SpacesStore/Company%20Home?alf_method=DELETE

Forcing Success Response Status


Not all clients can gracefully handle non-success HTTP Responses, for example, the Flash runtime player - the runtime for Adobe Flex applications.

In this situation, web scripts provide a mechanism to force all HTTP Responses to indicate success in their Response Header.  However, the Response body will still represent the content as if a non-success status had occurred.

To force HTTP Response Header success set the following HTTP Request Header:


alf-force-success-response = true

JSON Callbacks


If your web scripts provide JSON responses, it is likely they will be invoked directly from within a Web Browser via the XMLHttpRequest object. However, due to security reasons, you may run into cross-domain issues, a restriction that requires you to proxy your requests on the server side. Typically, to workaround these issues, public services such as Yahoo! JSON Services provide a callback mechanism.

Web scripts also provide this mechanism which wraps the JSON output text in parentheses and a function name of your choosing. A callback is invoked by adding the following URL parameter on JSON URL requests:


alf_callback=function

where function is the name of a client-side JavaScript function to be invoked.

The following simple HTML page demonstrates this:


  
    
    

This will result in the JSON response looking like this:

showTitle( ...json output... );

NOTE: For security reasons, this mechanism is disabled by default. To enable it on any SpringWebScripts container, set the bean property: allowCallbacks = true, for example:

  <bean id='webscripts.container' parent='webscripts.abstractcontainer' class='org.springframework.extensions.webscripts.PresentationContainer'>
     <property name='name'><value>Spring Web Scripts Container</value></property>
     <property name='allowCallbacks'><value>true</value></property>
     ...
  </bean>

Caching


Web Scripts comply with HTTP Caching supporting the notions of Last Modified Time and ETag allowing a Web Script response to be cached. A cache manager (suitable for the client environment) can interpret the cache controls (if any) returned with the Web Script response and cache appropriately.

A typical scenario is where a Repository-hosted Web Script is invoked via HTTP. In this case, any HTTP caching proxy may be used between the client and Alfresco Repository Server.

Note: Each Web Script dictates its caching controls, if any


How Do I Create a Web Script?


This section demonstrates how to create a Web Script. The Web Script in question is a simple Hello World example requiring authenticated access which simply greets the user in both HTML and XML.

You will need to understand:


  • XML for expressing the Web Script description
  • Optionally, JavaScript for writing Web Script behaviour
  • Freemarker for rendering a Web Script response

The only tools you'll need are an Alfresco Repository server and the Alfresco Explorer web client. Alternatively, advanced Web Scripts may be developed in Java.


Examples and Guidelines


Before diving into the technical bit, you may want to browse or refer to the available Web Scripts Examples.

If you're really impatient, you can create your first Web Script within the next minute or so.

You may also wish to refer to the Alfresco guidelines for designing RESTful Web Scripts.


Choosing a URI


First, choose a URI and HTTP method for your Hello World Web Script...

GET /<contextPath>/<servicePath>/sample/helloworld?to={name?}

The URI is under your control, but must be unique.

Note the following URL namespaces are reserved for Alfresco use:

/<contextPath>/<servicePath>/sample
/<contextPath>/<servicePath>/api
/<contextPath>/<servicePath>/ui
/<contextPath>/<servicePath>/office
/<contextPath>/<servicePath>/wcm

Deciding Where to Place Web Script Implementation


With a URI decided, it is necessary to bind a Web Script implementation to it, consisting of the following files:


  1. A Description Document
  2. A Controller Script (optional)
  3. One or more Response Templates
  4. A Configuration Document (optional)
  5. A Locale Bundle (optional)

Our example Hello World implementation will consist of the following files:

helloworld.get.desc.xml
helloworld.get.js
helloworld.get.html.ftl
helloworld.get.xml.ftl
helloworld.get.html.400.ftl
helloworld.get.xml.400.ftl
helloworld.get.config.xml
helloworld.get.properties

These files need to be stored in a folder somewhere. They can live in either the Alfresco Repository or the Java ClassPath.  The following folders are listed in the sequence in which Alfresco searches for Web Script implementation files:


  1. repository folder: /Company Home/Data Dictionary/Web Scripts Extensions
  2. repository folder: /Company Home/Data Dictionary/Web Scripts
  3. class path folder: /alfresco/extension/templates/webscripts
  4. class path folder: /alfresco/templates/webscripts

Within any of these folders, you can use subfolders to organize web scripts.

New web scripts will not be visible until the 'Refresh Web Scripts' link is clicked on the /alfresco/service/ page.

Warning! do not store web scripts in:

/org/alfresco

or any of its subfolders - these folders are reserved for Alfresco use.


Creating a Description Document


Our URI is described by creating an .xml description document in one of the above Web Script folders. For now, assume all files are placed into the repository folder: /Company Home/Data Dictionary/Web Scripts.

Within any Web Script folder, sub-folders may be used to organise Web Scripts. For example, we can place our Hello World Web Script in the folder

/Company Home/Data Dictionary/Web Scripts/org/alfresco/sample

and within this folder, create the file

helloworld.get.desc.xml

Naming is important. Web Scripts employ convention over configuration for their definition to reduce the amount of required typing. The postfix .desc.xml informs Alfresco that this is a Web Script description document.

The complete folder and file name

org/alfresco/sample/helloworld.get.desc.xml

defines


  1. A package of org/alfresco/sample
  2. A service id of helloworld
  3. A binding to the HTTP GET method



The content of the Hello World Web Script description document is defined as follows:

<webscript>
  <shortname>Hello World</shortname>
  <description>Greet a user</description>
  <url>/helloworld?to={name?}</url>
  <url>/hello/world?to={name?}</url>
  <format default='html'>extension</format>
  <authentication>user</authentication>
</webscript>

Where:


  • shortname is a human readable name for the Web Script
  • description (optional) is documentation for the Web Script
  • url (one or more) is a URI Template to which the Web Script is bound; variants of the URI template which specify a format do not need to be registered, however, they are useful for documentation purposes
  • format (optional) controls how the content-type of the response can be specified via the URI; valid values are:
    • argument the content-type is specified via the format query string parameter, for example /helloworld?to=dave&format=xml
    • extension the content-type is specified via the URI extension, for example /hello/world.xml?to=dave
    • any either of the above can be used
    • Note: if not specified, the default value is any
    • Note: if the caller does not specify a required content-type at all, the default content-type is taken from the (optional) default attribute of the format element. By default, if not set, the html format is assumed. In some cases, a URI may decide upon a response content-type at runtime. For these URIs, specify an empty format, for example format default=''
  • authentication (optional) is the required level of authentication; valid values are:
    • none specifies that no authentication is required at all
    • guest specifies that at least guest authentication is required
    • user specifies that at least named user authentication is required
    • admin specifies that at least a named admin authentication is required
    • Note: if not specified, the default value is none
    • Note: The optional runas attribute can be used to force the execution of a web script as a specific user. This can only be specified for web scripts that are stored in the Java Class path.

The description provides Alfresco with all the necessary information to bind the web script to one or more URIs.  It also provides enough to document the Web Script.


Advanced Description Options


Description documents also provide the following options, which are important, but not as frequently used or mandated.


  • transaction (optional) is the required level transaction; valid values are:
    • none specifies that no transaction is required at all
    • required specifies that a transaction is required (and will inherit an existing transaction, if open)
    • requiresnew specifies that a new transaction is required
    • Note: If not specified, the default value is none if authentication is also none, otherwise the value is required
  • family (optional) is a tag for categorizing similar or related web scripts. The family tag may be repeated if this script belongs to more than one family.
  • cache (optional) is the required level of caching; valid child elements are:
    • never (optional) specifies whether caching should be applied at all; valid values (optional) are:
      • true (default) specifies the web script response should never be cached
      • false specifies the web script response may be cached
      • Note: If never is not specified, the default is true
    • public (optional) specifies whether authenticated responses should be cached in a public cache; valid values (optional) are:
      • true (default) specifies the web script authenticated response may be cached in a public cache
      • false specifies the web script authenticated response may not be cached in a public cache
      • Note: If public is not specified, the default is false
    • mustrevalidate (optional) specifies whether a cache must revalidate its version of the web script response in order to ensure freshness; valid values (optional) are:
      • true (default) specifies that validation must occur
      • false specifies that validation may occur
      • Note: If mustrevalidate is not specified, the default is true
  • negotiate (zero or more) associates an Accept header MIME type to a specific web script format of response; the (mandatory) value specifies the format while the mandatory accept attribute specifies the MIME type
    • Note: Content Negotiation is enabled with the definition of at least one negotiate element
  • kind (optional) is an attribute discriminator for overriding the kind of web script. See list of available web script kinds.
  • lifecycle (optional) is an attribute for describing the lifecycle of the web script. Web scripts typically start out in some sort of draft state, are promoted to full production use, and are then retired at the end of their life.
    • noneThis web script is not part of a lifecycle.
    • sample This web script is a sample and is not intended for production use.
    • draft This method may be incomplete, experimental, or still subject to change.
    • public_api This method is part of the Alfresco public API and should be stable and well tested.
    • draft_public_api This method is intended to eventually become part of the public API but is incomplete or still subject to change.
    • deprecated This method should be avoided. It may be removed in future versions of Alfresco.
    • internal This script is for Alfresco use only. This script should not be relied upon between versions. It is likely to change.

An example of a full web script description follows:

<webscript kind='org.alfresco.httpsonly'> 
  <shortname>Hello World</shortname>
  <description>Greet a user</description>
  <url>/sample/helloworld?to={name}</url>
  <url>/sample/helloworld.xml?to={name}</url>
  <format default='html'>extension</format>
  <lifecycle>sample</lifecycle>
  <authentication runas='fred'>user</authentication>
  <transaction>required</transaction>
  <family>Sample</family>
  <cache>
    <never>false</never>
    <public>false</public>
    <mustrevalidate/>
  </cache>
  <negotiate accept='text/html'>html</negotiate>
  <negotiate accept='text/xml'>xml</negotiate>
</webscript>

URI Templates


A URI template is simply a URI containing tokens which may be substituted with actual values. The URI template syntax is minimal and simple, and as of Alfresco v3, complies with the template syntax of JSR-311 (JAX-RS). Common forms of URI template include:


/content/a/b/c/d.txt
/sample/helloworld?to={name?}
/blog/search?q={searchTerm}&amp;n={numResults}
/people/{personName}/profile/{profileStyle}
/blog/category/{category}?n={itemsperpage?}
/user/{userid}


A token of the form {<name>?} means it is optional. Typically, tokens are used for URI arguments, but may also be used for path segments.

Note the third example passes two parameters to the Web Script. Normally an ampersand (&) is used to separate parameters, though in your XML Web Script Description document one must use the escaped literal '&amp;' instead.

For now, Web Scripts do not enforce mandatory arguments. However, it is still useful to provide a full URI template for documentation purposes.

URI templates are specified relative to http://<host>:<port>/<contextPath>/<servicePath>.

When a URI request is made, Alfresco locates the appropriate Web Script by finding the closest match to a URI template in a Web Script description document.

Given the following URI Templates:

1 /a
2 /a/b
3 /a/{val1}
4 /a/{val1}/b
5 /a/{val1}/b/{val1}
6 /a/{val1}/b/{val2}

The following URIs match the above templates as follows:

/a => template 1
/a/b => template 2
/a/c => template 3
/a/b/b => template 4
/a/c/b => template 4
/a/c/b/c => template 5
/a/c/b/d => template 6

However, the following URIs do not match any of the above templates:

/b
/a/c/c

As an implementor of a Web Script you have access to the values provided for tokens in the URI template e.g. access to the values for {val1} and {val2}. The values are available in both the Web Script Controller Script and Response Templates via the root object url.templateArgs.

When using java backed controllers the tokens can be accessed through the org.alfresco.web.scripts.WebScriptRequest.getServiceMatch() API. In Community Edition 3.2r2 this will return a org.alfresco.web.scripts.Match instance that has a getTemplateVars() method returning a Map of all tokens.


Creating a Controller Script


A Web Script may optionally execute some JavaScript on invocation of its respective URI. The JavaScript can perform queries or updates against a back-end store. Also, the JavaScript may build a data model that is passed to the appropriate Web Script response template for subsequent response rendering.

For our example Hello World service we create the following file in the same folder as the Web Script description document

helloworld.get.js

Again, naming conventions apply where controller script file names have the following structure

<serviceId>.<httpMethod>.js

The following JavaScript root objects are available to all Web Scripts, regardless of their hosting environment.


args: an associative array of all URI parameters. See example.

argsM: an associative array of all URI parameters (where each key is an argument name and each value is an array containing all respective argument values, even if only one is supplied). See example.

headers: an associative array of all request headers.

headersM: an associative array of all request headers (where each key is an header name and each value is an array containing all respective header values, even if only one is supplied). See example.

url: provides access to the URI (or parts of the URI) that triggered the web script.

model: An empty associative array which may be populated by the JavaScript. Values placed into this array are available as root objects in Web Script response templates.

status: provides ability to control response status codes.

cache: provides ability to control caching of response.

config: provides access to the Web Script configuration.

msg: provides access to Web Script localized messages.

format: provides information on the response format to be rendered.

guest: A boolean indicating whether the web script is executing as 'Guest'.

webscript: An associative array of meta-data properties describing the Web Script.

server: An associative array of meta-data properties describing the server hosting the Web Script.

jsonUtils: A host object for parsing and generating JSON objects.

atom: A host object for parsing and generating Atom (Publishing) documents.

logger: A host object providing access to console logging facilities for debugging of scripts. See the Logging API.

Web Scripts hosted within the Alfresco Repository tier also have access to the following root objects which provide direct access to Repository services and content.


roothome: the repository root node (only available if authenticated)

companyhome: the company home folder (only available if authenticated)

person: the person node of the currently authenticated user (only available if authenticated)

userhome: the user home folder (only available if authenticated)

search: A host object providing access to Lucene and Saved Search results. See the Search API.

people: A host object providing access to Alfresco people and groups. See the People API.

actions: A host object providing invocation of registered Alfresco Actions. See the Actions API.

session: Session related information such as the current authentication ticket. See the Session API.

classification: Access to the root elements of the classification API. See the Classification API.

utils: Access to a library of useful helper functions not provided as part of generic JavaScript. See the Utility Functions.

avm: Access to WCM objects such as AVM paths and searching within AVM stores and web projects. See the AVM API.

crossRepoCopy: Cross repository copy support. See the Cross Repository Copy.

workflow: Start workflows and access, control in-flight workflows.  See the JavaScript API#Workflow API.

Web Scripts hosted within the presentation tier (i.e. within Alfresco SURF) have their own extras as described in the Surf Platform - Freemarker Template and JavaScript API.

For our example Hellow World, we can write the following JavaScript to either greet the currently authenticated user via their user name, or via the name provided as an URI argument:

model.toWho = (args.to != null) ? args.to : person.properties.userName; 

The result of the script is added to the model root object and given the name who. Web Script response templates rendered after the execution of the JavaScript will now also have the root object named who, which in this case represents the name of the person to greet.

Of course, a Web Script can also perform updates, in which case, the model root object can be used to record items that have been updated, status, and so on.


Debugging a Controller Script


The Alfresco Server provides a built-in Javascript debugger.


Creating a Response Template


The final stage of a Web Script is to render a response for the HTTP request. Multiple response formats may be provided. Responses are rendered by FreeMarker templates.

For our example Hello World service, we create the following file in the same folder as the Web Script description document

helloworld.get.html.ftl

Again, naming conventions apply where response template file names have the following structure

<serviceId>.<httpMethod>.<format>.ftl

where


  • format specifies the format of the response template whose value is one of the following formats.

The following FreeMarker template root objects are available to all Web Scripts, regardless of their hosting environment.


args: an associative array of all URI parameters. See example.

argsM: an associative array of all URI parameters (where each key is an argument name and each value is an array containing all argument values, even if only one is supplied). See example.

headers: an associative array of all request headers.

headersM: an associative array of all request headers (where each key is an header name and each value is an array containing all respective header values, even if only one is supplied). See example.

url: provides access to the URI (or parts of the URI) that triggered the web script.

status: provides ability to control response status codes.

cache: provides ability to control caching of response.

config: provides access to Web Script configuration.

messages: a JSON representation of all localized messages for the Web Script.

format: provides information on the response format to be rendered.

guest: A boolean indicating whether the web script is executing as 'Guest'.

webscript: An associative array of meta-data properties describing the Web Script.

server: An associative array of meta-data properties describing the server hosting the Web Script.

date: A date representing the date and time of the web script request.

Web Scripts hosted within the Alfresco Repository tier also have access to the following template root objects which provide direct access to Repository services and content.


roothome: the repository root node (only available if authenticated)

companyhome: the company home folder (only available if authenticated)

person: the person node of the currently authenticated user (only available if authenticated)

userhome: the user home folder (only available if authenticated)

Web Scripts hosted within the presentation tier (i.e. within Alfresco SURF) have their own extras as described in the Surf Platform - Freemarker Template and JavaScript API.

And remember, the FreeMarker template also has access to any root objects created by the controller script, if one has been associated with the Web Script.

Web script templates also have access to the following methods:


absurl(url): Returns an absolute URL representation of the passed url. Useful when rendering links within ATOM (and similar formats).

xmldate(date): Returns an ISO8601 formatted result of the passed date. Useful when rendering dates within XML.

scripturl(queryString): Returns a url that references this web script. The passed queryString is added to the url. System arguments such as guest and format are automatically added. Note, this method is particularly useful for protection against the runtime environment within which the web script is executing. In some environments (such as a Portal) the url may be encoded.

clienturlfunction(funcName): Generates a client-side JavaScript function that can generate a URL back to this web script.

argreplace(argString, argName, argValue, ...): Replace specified argName with argValue, or add argName if it does not exist in argString.

encodeuri(uriString): encode string into URL-safe form.

For our example blog search, we can write the following FreeMarker to render the HTML response:


  
     At ${date?datetime}, ${person.properties.userName} says hello to ${toWho?html}
  


Note how the above template makes use of standard root objects, for example ${date?datetime} and root objects created by the controller script, for example ${toWho?html}.


Multiple Response Formats


Multiple response formats are simply supported by creating further template files following the naming convention outlined above.

Note: New and updated Templates are automatically registered and will be honoured when the Web Script is next invoked.

For our Hello World example, we can support add a machine-readable XML response by adding the following file

helloworld.get.xml.ftl

whose content is

<helloworld>
  <from>${person.properties.userName}</from>
  <says>hello</says>
  <to>${toWho?xml}</to>
</helloworld>

With our Hello World example description document and associated templates, the following URI mappings are available:


HTML template: /<contextPath>/<servicePath>/sample/helloworld?to=friend

HTML template: /<contextPath>/<servicePath>/sample/helloworld?to=friend&format=html

HTML template: /<contextPath>/<servicePath>/sample/helloworld.html?to=friend

XML template: /<contextPath>/<servicePath>/sample/helloworld?to=friend&format=xml

XML template: /<contextPath>/<servicePath>/sample/helloworld.xml?to=friend

Response Status


Web Scripts use HTTP response status codes to:


  • inform a client of an error situation (for example, item not found)
  • inform a client of an occurrence of an event (for example, item created)
  • instruct a client to perform a follow-up request (for example, authorization required)
  • inform a client of success

Response status codes are set in the controller script via the status root object.

We can add a status to our Hello World example indicating that we can only greet one person at a time i.e. the 'to' argument is specified only once. We can use status code 400 (Bad Request) to represent this. The controller script is extended as follows:

if (argsM.to != null && argsM.to.length > 1)
{
   status.code = 400;
   status.message = 'Can only greet one person at a time.';
   status.redirect = true;
}
else
{

   model.toWho = (args.to != null) ? args.to : person.properties.userName;
}

Redirect allows the rendering of a custom response template for the specified status code. If redirect is not set (that is, false), the response header status code is set but the relevant standard web script response template is used, as would normally apply.

If redirect is true, then an appropriate status response template is searched for. The search is performed in the following order:


Web Script specific template named <scriptid>.<method>.<format>.<code>.ftl : located in the same folder as the web script description document and used for the specified status code only, for example
/org/alfresco/sample/helloworld.get.html.400.ftl

Web Script specific template named <scriptid>.<method>.<format>.status.ftl : located in the same folder as the web script description document used for any status code, for example


/org/alfresco/sample/helloworld.get.html.status.ftl


Package level template named <format>.<code>.ftl : this template is first located in the package of the web script, but if not found, is searched for in the parent package hierarchy, up to the root package, for example
/org/alfresco/sample/html.400.ftl

Package level template named <format>.status.ftl : this template is first located in the package of the web script, but if not found, is searched for in the parent package hierarchy, up to the root package, for example
/org/alfresco/sample/html.status.ftl

Default template named <code>.ftl : located in the root package and always renders html, for example
/400.ftl

Default template named status.ftl : located in the root package (provided out-of-the-box) and always renders html, for example
/status.ftl

Status Response templates have access to the same root objects as standard Web Script response templates. The exception is that the default templates /<code>.ftl and /status.ftl only have access to the root objects 'url', 'status', 'server' and 'date'.

To provide a custom Bad Request status response for our Hello World example we create the following file in the same folder as the web script description document

helloworld.get.html.400.ftl

whose content is


  
     ${status.message}
  


We can also provide a meaningful response for machine-readable XML requests:

helloworld.get.atom.400.ftl

<response>
  <code>${status.code}</code>
  <codeName>${status.codeName}</codeName>
  <codeDescription>${status.codeDescription}</codeDescription>
  <message>${status.message}</message>
</response>

Remember, these templates are optional, as the search for an appropriate status template will always eventually find the default template /status.ftl.


Advanced Implementations


Configuration


Configuration is accessed via the config root object, which is available during both controller script and template execution.

There are 3 types of configuration, 'script', 'scoped' and 'global'. Script configuration is defined in an XML document with an arbitary structure stored locally with the Web Script. Global and scoped configuration are specified in Alfresco configuration files, as used in Alfresco Explorer.


Web Script Configuration


Web Script configuration is read from an XML file packaged with the Web Script.

For our example Hello World service we create the following file in the same folder as the Web Script description document

helloworld.get.config.xml

Again, naming conventions apply where configuration file names have the following structure

<serviceId>.<httpMethod>.config.xml

The content of the configuration may be any valid XML.

<helloworld>
  <greeting>hello</greeting>
  <fromproperty>userName</fromproperty>
</helloworld>

Within a Controller Script, access to the configuration is via E4X which is essentially 'ECMAScript For XML' (tutorials can be found at http://www.w3schools.com/xml/xml_e4x.asp and/or http://wso2.org/library/1050, http://phpforms.net/tutorial/tutorial.html).

We can update our Hello World Controller script example to determine how to display 'who' the greeting is from.

model.toWho = (args.to != null) ? args.to : person.properties.userName;
var s = new XML(config.script);
model.fromWho = person.properties[s.fromproperty];

FreeMarker has builtin support for processing XML data allowing response templates direct access to configuration too. We can update our Hello World template example to extract the greeting from the configuration.


  
     At ${date?datetime}, ${fromWho?html} says ${'''config.script.helloworld.greeting'''?html} to ${toWho?html}
  


Global and Scoped Config


Global and scoped config is read by the Alfresco Configuration Service. By default the following files are read:


Versions 4.x:


  • classpath:alfresco/web-scripts-config.xml (already exists in 'alfresco.jar'; don't overwrite it!)
  • classpath:alfresco/web-scripts-cmis-config.xml
  • classpath:alfresco/extension/web-api-config-custom.xml
  • classpath:alfresco/extension/web-scripts-config-custom.xml
  • classpath:alfresco/extension/web-scripts-cmis-config.xml

Versions 5.x:


  • classpath:alfresco/web-scripts-config.xml (already exists in 'alfresco.jar'; don't overwrite it!)
  • classpath:alfresco/extension/web-scripts-config-custom.xml


Configuration sections that do not have an evaluator or condition are known as 'global' config sections i.e. these will always appear in a configuration lookup, a typical global configuration section has the following appearance.

<alfresco-config>
  <config>
    <server>
      <errorpage>/jsp/error.jsp</errorpage>
      <loginpage>/jsp/login.jsp</loginpage>
      <guesthome enabled='true'>/jsp/guesthome.jsp</guesthome>
      <url>/</url>
      <url>/alf</url>
      <url>/alfresco</url>
    </server>
  </config>
</alfresco-config>

Scoped configuration, on the other hand, is a configuration section that does have an evaluator and condition, for example.

<alfresco-config>
  <config evaluator='string-compare' condition='Remote'>
    <remote>
       <endpoint>http://localhost:8080/alfresco</endpoint>
    </remote>
  </config>
</alfresco-config>

For changes in these files to take effect, the ALFRESCO server must be stopped and restarted (refreshing the webscripts is not sufficient).


Accessing Global and Scoped Configuration


Accessing the configuration above is achieved using the same techniques and syntax as any other model data, the global configuration is exposed via the config.global root object and the scoped config is exposed via the config.scoped root object.

For example to access the server configuration from the example above the following syntax would be used in a JavaScript:

var serverCfg = config.global.server;

and the following syntax would be used in a FreeMarker template:

<serviceId>.<httpMethod>.properties

Each line of the file represents a message identified by a unique key. The key may be dot separated.

Our example consists of:

at=At
says=says
to=to
greeting.hello=hello
greeting.howdy=howdy

Messages are accessed via the template method msg.

The Hello World HTML template is updated as follows:


  
     ${msg('at')} ${date?datetime}, ${fromWho?html} ${msg('says')} ${msg('greeting.' + config.script.helloworld.greeting)} ${msg('to')} ${toWho?html}
  


Multi-part Form Processing


When posting a request of mimetype multipart/form-data the following additional root object is available to the Controller Script.


formdata: provides access to multipart/form-data requests allowing the upload of files.

This root object allows a Web Script to read all fields included in the form including those of type 'file'. It provides a mechanism for iterating through each field and examining its meta-data such as name, value, content type etc.

All fields that are not of type 'file' are also mapped into the args and argsM root objects allowing access to fields by name.

View the File Upload Example to see how formdata is used to upload files into the Alfresco Repository.


Request Processing


A Controller Script can gain access to a request body allowing the processing of content posted to a Web Script.

By default, the following root object is provided:


requestbody: a ScriptContent representing the content of the request body

As with formdata, the content may be converted to a string (if plausible) or written to an output stream such as a content object held in the Alfresco Repository.

Often, content is posted in a structured form such as XML or JSON. In these cases, the content can be converted to a string and subsequently parsed by the controller script. However, this can become cumbersome or error prone if the parsing is required by several Web Scripts implementations. To alleviate this problem, the Web Scripts framework provides the notion of a Format Reader which parses a request of a given mimetype into an object structure that is then automatically provided to the Controller Script. 

Out-of-the-box, the Web Script framework provides the following Format Readers.


JSON: parses a request of mimetype application/json into a JSON object named json

Atom Feed: parses a request of mimetype application/atom+xml;type=feed into an Apache Abdera Feed object named feed

Atom Entry: parses a request of mimetype application/atom+xml;type=entry into an Apache Abdera Entry object named entry

Atom : parses a request of mimetype application/atom+xml into either an Abdera Feed or Entry object named feed and entry respectively

Format Readers are not invoked automatically i.e. sending a JSON request to a Web Script does not automatically provide a json root object to the Controller Script. The fall-back requestbody is provided instead.

To explicitly initiate a Format Reader requires a Controller Script whose name is structured:

<serviceId>.<httpMethod>.<format>.js

e.g.

folder.post.json.js  => create 'json' root object for Controller Script when application/json mimetype is posted
folder.post.atomentry.js  => create 'entry' root object for Controller Script when application/atom+xml;type=entry mimetype is posted

Runtime Cache Controls


Runtime cache control is optionally specified via the root object cache which is available to the Web Script Controller script. At runtime, expiry criteria may be set, and definition-time controls may be overridden.


Java-Backed Implementations


Sometimes, scripts and templates are not powerful enough to implement the required functionality behind a URI.  For example, streaming content.

For these scenarios it is possible to bind an Alfresco Spring configured Java Bean into the Web Script. The Java Bean may take full control, or work in conjunction with the script and templates.

For reference, you may browse these Java samples.


Spring Bean Declaration


To bind a Spring bean to a Web Script it is only necessary to create a bean with an id of the following structure:

id='webscript.<packageId>.<serviceId>.<httpMethod>'

and ensure its parent is the 'webscript' bean:

parent='webscript'

Note: <packageId> is the package (directory) that the Web Script descriptor (.desc.xml file) is located in, not the package of the Java class that implements the logic for the Web Script.

For example:

<bean id='webscript.org.alfresco.sample.helloworld.get'
      class='my.java.package.structure.HelloWorld'
      parent='webscript' />

Note that the bean id is made up of:


  • prefix = webscript (must always start with this value)
  • packageId = org.alfresco.sample
  • serviceId = helloworld
  • httpMethod = get

From this we can determine that the descriptor for this Web Script is called helloworld.get.desc.xml and is located in the directory org/alfresco/sample (either in the repository or in the classpath, as described in Deciding Where to place Web Script Implementation).

As with any Spring bean, other service(s) your Java class requires (including the Alfresco APIs) may be dependency injected into your Java bean.


Web Script Java Class


The Java Class must implement the Java Interface:

org.alfresco.web.scripts.WebScript

which declares the following methods:

/**
* Gets the Service Description
*
* @return service description
*/
public WebScriptDescription getDescription();
   
/**
* Execute service
*
* @param req
* @param res
* @throws IOException
*/
public void execute(WebScriptRequest req, WebScriptResponse res)
  throws IOException;

Java Helper Classes


Abstract helper classes are also provided to simplify the development of a Java backed Web Script.

The first helper class is:

org.alfresco.web.scripts.AbstractWebScript

which allows a Web Script to take full control over the request. This is achieved by providing an implementation of the execute method. The helper class provides access to information such as the Web Script description document and methods for invoking JavaScript and templates.

The second helper class is:

org.alfresco.web.scripts.DeclarativeWebScript

which allows a web script to mix Java, JavaScript, and templates. This kind of Web Script supports all the behaviour described in this document, with the addition of first executing some Java. As with the controller script, the Java code can build a data model that is available to Response templates. The Java to be executed is placed into the executeImpl method.


Managing Response Status


A Java implemented web script also has support for response status codes. There are two approaches to sending a response code:


Approach 1 - Throw an Exception

All exceptions thrown from a Web Script are caught by the Web Script Runtime and converted to response status codes. By default, the status code 500 (Internal Error) is used. However, the exception WebScriptException supports the constructor:

public WebScriptException(int statusCode, String message)

This constructor is used to explicitly set a response code in an error situation, for example

if (req.getParameter('q') == null || req.getParameter('q').length() == 0)
{
   throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, 'Search term not provided');
}

Using this approach will always render the relevant status response template.


Approach 2 - Explicit Setting of Response Status

The helper class DeclarativeWebScript provides the method executeImpl whose signature is:

protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status, Cache cache)

The status argument may be used to explicitly set a response status code & message, as well as control the redirect to a status response template, for example

if (req.getParameter('q') == null || req.getParameter('q').length() == 0)
{
   status.setCode(HttpServletResponse.SC_BAD_REQUEST);
   status.setMessage('Search term not provided');
   status.setRedirect(true);
   return;
}

Exceptions may be handled as follows:

catch(AuthenticationException e)
{
   status.setCode(HttpServletReponse.SC_FORBIDDEN);
   status.setMessage('Invalid username & password');
   status.setException(e);
   status.setRedirect(true);
}

Creating a New Kind of Web Script


By default, Alfresco Web Scripts support an MVC style of implementation. Sometimes, it's useful to override the default behavior to add an extra capability, or provide a completely different style of Web Script such as those that need to stream large amounts of data back on the response. This can be done by developing a Java-backed implementation, however, it cannot be re-used across several Web Scripts without changes to Spring configuration.

A Web Script 'Kind' allows a Java-backed implementation to be named, and for any Web Script Description Document to state it wants to use that implementation instead of the out-of-the-box one provided by Alfresco. See list of currently available Web Script kinds.

The steps for creating a new 'Kind' are:


Implement a Web Script backing bean

The steps here are exactly the same as for any other Java-backed implementation as described above.


(optional) Implement a Description Document Extension

The backing bean may be configured via extensions to the Web Script Description Document. To access those extensions it is necessary to provide an implementation of the interface:

org.alfresco.web.scripts.DescriptionExtension

which defines the following method:

/**
* Gets the custom description extensions
*
* @param serviceDescPath  path to service doc
* @param serviceDesc  service doc input stream
* @return  extensions mapped by name
*/
public Map<String, Serializable> parseExtensions(String serviceDescPath, InputStream servicedesc);

The method parses the complete Description Document (XML), extracts its extensions and places them into a map (indexed by the name of extension) which is returned. It is called when the Web Script is registered with the Web Script framework.

Spring is used to register the Description Extension implementation:

<bean id='webscriptdesc.my.kind.of.web.script' class='my.kind.of.WebScriptDocumentExtension'/>

The id is the same as the Web Script backing bean except it starts with webscriptdesc instead of webscript.


(optional) Access Extensions within your Web Script Implementation

To gain access to your extension values within your backing bean you can use the following method which returns the map created above:

getDescription().getExtensions()

That's it. To use your new 'Kind' of Web Script refer to Advanced Description Options. Note: The id referenced in the kind attribute is specified without the webscript. prefix.


How Do I Administer Web Scripts?


Resetting the Web Script Index


New and updated Web Scripts can be registered without restarting the Alfresco server. This makes it easy to use the Alfresco Repository to develop Web Scripts.

To register a Web Script:


  1. Visit the index page as described in Listing Available Web Scripts.
  2. Click on Refresh to re-register all Web Scripts. 

Logging


The 3.0 Web Scripts Framework provides logging of Web Script registration and execution.


Testing


Various tools are available for testing Web Scripts.


Dump & Load


Web Scripts that are not Java-backed may be exported from one Repository and imported to another via the simple Web Script Dump and Load utility.

The utility is also useful for viewing the complete implementation of a Web Script in a single page, allowing it to be copied and sent via e-mail or posted to the forums for sharing or diagnosing a problem.


Localization of Status Code Messages


The resource bundle /alfresco/messages/webscripts.properties contains status code names and descriptions for all HTTP codes.


Web Script Framework


Learn more about


Appendix A: Web Script Root Objects


formdata


A host object providing access to multipart/form-data requests allowing file upload from a web script. See example.

Note: You must use enctype='multipart/form-data' in your form tag or the formdata variable will not be populated with fields.


hasField: boolean indicating the existence of a named form field in the multipart request

fields: an array of formfield where each entry represents a field within the multipart request

formfield


A host object providing access to a form field within a multipart/form-data request.


name: the name of the form field (Note that form fields may not be uniquely named)

isFile: boolean indicating whether this field represents a file (content)

value: string representing the field value (in the case of isFile is true, the filename will be returned, use content instead)

content: a ScriptContent representing the content of the field

mimetype: the mimetype of the content (or null, if isFile is false)

filename: the filename of the source file used to provide the content (or null, if isFile is false, or a filename was not provided)

url


A host object providing access to the URL (or parts of the URL) that triggered the web script.


context: Alfresco context path, for example /alfresco
serviceContext: Alfresco service context path, for example /alfresco/service
service: Web script path, for example /alfresco/service/blog/search
full: Web script URL, for example /alfresco/service/blog/search?q=tutorial
templateArgs: a map of substituted token values (within the URI path) indexed by token name
args: Web script URL arguments, for example q=tutorial
match: The part of the web script URL that matched the web script URL template
extension: The part of the web script URL that extends beyond the match path (if there is no extension, an empty string is returned)



For example, imagine a web script URL template of

/user/{userid}

and a web script request URL of

/alfresco/service/user/fred?profile=full&format=html

The url root object will respond as follows:


  • url.context => /alfresco
  • url.serviceContext => /alfresco/service
  • url.service => /alfresco/service/user/fred
  • url.full => /alfresco/service/user/fred?profile=full&format=html
  • url.args => profile=full&format=html
  • url.templateArgs['userid'] => fred
  • url.match => /user/
  • url.extension => fred

URL and authentication


You can reuse the web clients authentication by using the /alfresco/wcservice/ URL to reference you web script. Change the URL to /alfresco/service/ and you will get an HTTP authentication prompt even if you are logged in in the Alfresco web client. The first option is the most convenient for the end user, the second may be useful while testing with different accounts.


status


An associative array of response status properties that allow control over the status and content of the Web Script response.


code: (read/write) status code (primarily a HTTP status code, but can be any number)
codeName: (read) human readable status code name
codeDescription: (read) human readable status code description
message: (read/write) status message
redirect: (read/write) a boolean indicating whether to redirect to a status specific response template
exception: (read/write) the exception (if any) which has caused this status
location: (read/write) the absolute URI to which the client should resubmit a request - often used with 3xx redirect status codes.  See example.

cache


An associative array of cache control properties that allow control over how the Web Script response is cached. See example.


neverCache: (read/write boolean) control whether Web Script response should be cached at all; true means never cache. If not set, the default value is specified by the cache control section of the Web Script definition.
isPublic: (read/write boolean) control whether web script response should be cached by public caches. If not set, the default value is specified by the cache control section of the web script definition.
mustRevalidate: (read/write boolean) control whether cache must re-validate its version of the web script response to ensure freshness. If not set, the default value is specified by the cache control section of the web script definition.
maxAge: (read/write long) specifies the maximum amount of time (in seconds, relative to the time of request) that the response will be considered fresh. If not set, the default value is null.
lastModified: (read/write date) specifies the time that the content of the response last changed. If not set, the default value is null.
ETag: (read/write string) specifies a unique identifier that changes each time the content of the response changes. If not set, the default value is null.

format


The format of the response.


name: (read only) format name

mimetype: (read only) mimetype associated with format

json


If the content is JSON then an object called 'json' is added to the model.

The json object is either a JSONArray or JSONObject depending upon whether the content is an array or not.


jsonUtils


jsonUtils allows access to the json data from the controller script.


  • var jsonData = jsonUtils.toObject(requestbody.content);
  • var jsonString = jsonUtils.toJSONString(object);

JSONArray


These are the commonly used methods of JSONArray.


  • length()
  • getJSONObject(index)




JSONObject


These are the commonly used methods of JSONObject.


  • get(fieldName)
  • has(filedName)
  • isNull(fieldName)
  • getJSONArray(fieldName)

atom


TODO:


server


An associative array of meta-data properties that describe the hosting Alfresco server.


versionMajor: server major version number, for example 1.2.3
versionMinor: server minor version number, for example 1.2.3
versionRevision: server revision number, for example 1.2.3
versionLabel: server version label, for example Dev
versionBuild: server build number, for example build-1
version: server version, for example major.minor.revision (label)
edition: server edition, for example Enterprise
schema: server schema, for example 10

webscript


An associative array of meta-data properties describing the web script.


id: The web script Id
shortName: The web script short name
description: The web script description
defaultFormat: The default response format if none explicitly specified in web script URL
formatStyle: The accepted ways of specifying the format in the web script URL
URIs: A (string) array of URL templates
method: HTTP Method
requiredAuthentication: required level of authentication
requiredTransaction: required level of transaction
storePath: the path of the persistent store where the web script is stored
scriptPath: the path (within storePath) of web script implementation files
descPath: the path (within storePath) of the web script description document