URL Addressability

Document created by resplin Employee on Jun 6, 2015
Version 1Show Document
  • View in full screen mode

{{Obsolete}}

This functionality was removed from Alfresco in 5.0.b.


Introduction


The JSF based component architecture of the web-client does not lend itself to URL addressability or bookmarking of page URLs. To compensate for this, Alfresco web-client provides a set of servlets that provide direct URL based access to any item of content within the repository and to allow direct navigation to pages within the web-client. Servlets are also provided to render templates and execute workflow upon documents.




Security


Access to content or pages in servers is protected by the same node level security as any other API within Alfresco. If a request for node content is made without an appropriate security context, a login page will be presented. If NTLM or other single sign-on authentication is present, then it will be used if applicable. Guest Access or a Ticket URL Argument can also be used if appropriate to avoid the login page.


Guest Access


Guest access is now supported for all Alfresco URLs. The URL parameter guest=true can be appended to any Alfresco URL and the login page will not be displayed before the URL is processed. The Guest user must have access to the item referenced by the URL or the access attempt will fail. For example:

http://myserver:8080/alfresco/download/attach/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf?guest=true

Guest access allows URLs to be sent in emails etc. to provide external access to content or template rendering results to users who do not have an Alfresco login. If the Guest login is successful then the URL will not require a login page, however if guest access fails the Login page is shown as normal. Also, if a permissions check to the template or node referenced by the URL fails then the Login page is shown.


Ticket URL Argument


If the API you are using wishes to use a servlet directly and does not require the Alfresco web-client screen for security authentication, then you must aquire a valid Authentication ticket from the appropriate API call - you can use a Web Script or Web Services call to request a ticket.

This can then be appended to any servlet URL as the alf_ticket argument to provide authentication without login, for example:

/alfresco/download/attach/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf?ticket=1234567890

DownloadContentServlet


This servlet has the following class name:

org.alfresco.web.app.servlet.DownloadContentServlet

Responsible for streaming node content from the repo directly to the response stream. The NodeRef of the content to retrieve is encoded on the URL. The appropriate mimetype to return in the header of the stream is calculated based on filename extension passed as the final element on the url path.

The URL to the servlet is of the form:

/alfresco/download/<direct|attach>/<workspace>/<store>/<nodeId>/<filename>

In Alfresco 3.x and beyond a short form of the servlet is also available

/alfresco/d/<d|a>/<workspace>/<store>/<nodeId>/<filename>

Examples:

/alfresco/download/attach/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf
/alfresco/download/direct/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf
/alfresco/d/a/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf
/alfresco/d/d/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf

The 'attach' or 'direct' element is used to indicate whether to display the stream directly
in the browser or download it as a file attachment. Specify attach to attach the content stream as an HTTP1.1 attachment object, or specify direct to return the content stream directly to the output. The URL elements then encode the repository store protocol, the store ID, followed by the content Node Id. The last element is the stream attachment filename to return to the browser.


URL arguments


ticket - can be supplied as a URL argument to allow authentication for external use - see above.

By default, the servlet assumes that the content is on the {http://www.alfresco.org/model/content/1.0}content content property. If you require the content of a different specific model property, provide the fully qualified name of the property as an additional URL argument called property. For example:

/alfresco/download/direct/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf?property={http://www.company.org/model/custom/1.0}myprop

The reference to the content can be specified as a 'path' URL argument rather than as NodeRef element. For example:

/alfresco/download/direct?path=/Company%20Home/My%20Home%20Space/myimage.jpg

Paths are specified in a similar way to a WebDav path - they are 'cm:name' based URL encoded strings.

Note that the entire URL must be URL encoded appropriately.


CMIS alternatives


In Alfresco 3.x and beyond the Repository RESTful API provides support for downloading content streams through the CMIS Content Retrieval API.


UploadContentServlet


This servlet has the following class name:

org.alfresco.web.app.servlet.UploadContentServlet

Responsible for streaming content directly from servers into the repository using the HTTP PUT command.  The NodeRef of the node onto which the content will be streamed can be encoded into the URL.  In this situation the content of the property can be considered to be updated once the servlet has returned. 

If a NodeRef is not specified in the URL then the content is streamed into the content store and the content data (including the content store URL, the mimetype, the encoding and the size) will be returned to the client on the response.  This information can later be used to manually update the content of a node by setting it to the values of the content property fo the node in question.  This is a technique used when updating content via the web service API.

Example URL with NodeRef provided:

/alfresco/upload/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf

Example URL with NodeRef not provided:

/alfresco/upload/myfile.pdf

By default the upload servlet assumes, when uploading content, it should do so to the cm:content property.  If this is not the case then the content property name should also be encoded into the URL.  The property argument should be set to the fully qaulified name of the content property.

The mimetype and encoding of the content being uploaded can also be encoded onto the URL.  In cases that they are not the mimetype is determined from the file extension and encoding is defaulted to 'UTF-8'.  The 'mimetype' and 'encoding' properties should be set to the required mimetype and encoding value respectivly.

The 'ticket' parameter is used to pass the authentication information to the servlet.  Guest access is currently denied.


GuestDownloadContentServlet


This servlet has the following class name:

org.alfresco.web.app.servlet.GuestDownloadContentServlet

This servlet follows exactly the same rules as DownloadContentServlet, the same parameters and usage model applies.

The URL to the servlet is of the form:

/alfresco/guestDownload/<direct|attach>/<workspace>/<store>/<nodeId>/<filename>

The main difference with this servlet is the handling of sessions. This servlet will always download the content as the 'guest' user, however, the guest user will not be logged in, as is the case when DownloadContentServlet is used. The other difference is if the content referenced by the URL is not accessable to the guest user, a 403 Forbidden error will be returned rather than the login page.




ExternalAccessServlet


This servlet has the following class name:

org.alfresco.web.app.servlet.ExternalAccessServlet

Responsible for redirecting the web-client to display various global JSF views. It also accepts additional URL arguments to setup the context required for certain JSF views.

The URL specifies the JSF 'outcome' to be executed, which provides the JSF View to be displayed. The JSF 'outcome' must equate to a global navigation rule or it will not be displayed. The servlet may also accepts additional elements that encode a space or content NodeRef as part of the view context. A third mechanism is to encode the webdav path of the node instead of the NodeRef.

Servlet URL is of the form:

/alfresco/navigate/<outcome>[<workspace>/<store>/<nodeId>]
/alfresco/navigate/<outcome>/webdav/<path>

Currently supported are the following outcomes and arguments:


browse :navigate to the main browse screen, optionally supply a NodeRef to the folder to show initially.
showSpaceDetails :navigate to the Space Details screen, must supply a NodeRef to the space to display the details for.
showDocDetails :navigate to the Document Details screen, must supply a NodeRef to the file to display the details for.
logout :force a logout and redisplay the login page.
myalfresco :navigate to the My Alfresco user configurable dashboard page. Available in Alfresco 1.4!
dialog :navigates to the dialog with the specified name, optionally supply a NodeRef to init the context with
wizard :navigates to the wizard with the specified name, optionally supply a NodeRef to init the context with

Examples:

/alfresco/navigate/browse
/alfresco/navigate/browse/workspace/SpacesStore/0000-0000-0000-0000
/alfresco/navigate/showSpaceDetails/workspace/SpacesStore/0000-0000-0000-0000
/alfresco/navigate/showDocDetails/webdav/My%20Home%20Space/New%20Folder
/alfresco/navigate/wizard/startWorkflow

URL arguments:

ticket - can be supplied as a URL argument to allow authentication for external use - see above.


TemplateContentServlet


This servlet has the following class name:

org.alfresco.web.app.servlet.TemplateContentServlet

Responsible for returning the result of processing a template against a specified node and the default template model. Allows direct processing of Templates against nodes (and the default template model) with streaming of the result to the output stream. This allows the use of simple URLs to execute arbitary templates against nodes without the web-client interface.

Servlet URL is of the form:

/alfresco/template/<workspace>/<store>/<nodeid>

The result is the output of the default template (from the 'templatable' aspect set on the specified NodeRef), processed using the standard template model (see Template Guide) and the supplied NodeRef. A template must have been set on the node using the templatable aspect for this to work!

/alfresco/template/<workspace>/<store>/<nodeid>/<workspace>/<store>/<nodeid>

The result is the output of the template (specified as the last 3 elements of the URL), processed using the standard template model and the supplied NodeRef on the URL.

In addition to the default template model, the NodeRef supplied on the URL will be placed into the model as both
document and space and the object can be used as appropriate to its type.

Examples:

/alfresco/template/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554
/alfresco/template/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554/workspace/SpacesStore/abdc1234-1234-11da-97b9-123443211234
/alfresco/template/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554/workspace/SpacesStore/abdc1234-1234-11da-97b9-123443211234?mimetype=text%2Fxml

URL arguments:

ticket - can be supplied as a URL argument to allow authentication for external use - see above.

mimetype - can be supplied as a URL argument to set the mimetype for the response returned on the outputstream ('text/html' is assumed by default)

The default template assigned to the requested node will be used but it's also possible to assign a different template to the node (useful when no template is set or you need a different template than the default one):

/alfresco/template/<nodeWorkspace>/<nodeStore>/<nodeID>/<templateWorkspace>/<templateStore>/<templateID>/

Any other additional arguments can be passed to the servlet, they will be collected and supplied to the templating data-model into a Map object called args. The args object is accessable from the root of the templating data-model and contains all the URL name/value pairs supplied to the servlet.

Available in Alfresco 1.4!

The reference to the template or the context node can now be specified as 'templatePath' and 'contextPath' URL arguments rather than as NodeRef elements. For example:

/alfresco/template?templatePath=/Company%20Home/Data%20Dictionary/Presentation%20Templates/doc_info.ftl&contextPath=/Company%20Home/mydoc.txt

Paths are specified in a similar way to a WebDav path - they are 'cm:name' based URL encoded strings.

Note that the entire URL must be URL encoded appropriately.

The servlet now also supports POST'ed parameters. As with parameters passed on the URL, these will be collected and supplied to the templating data-model into a Map object called args. The args object is accessable from the root of the templating data-model and contains all the name/value pairs supplied to the servlet (usually via an HTML form). Please note though, that file upload is not supported.


Example to create RSS Feeds


Using URL addressability and Presentation Templates it is possible to define an RSS feed for any Space within Alfresco.  All that is needed is to apply the RSS Presentation Template that is distributed with Alfresco to the required Space using a URL - this can either be by explicit reference to the template or implicitly through a Space Dashboard.

The easiest approach is to use the Dashboard feature, which only takes 5 simple steps!



Step 1: In the Alfresco web client, navigate to the space you wish to subscribe to, and choose 'View Details' from the Actions menu.

Step 2:  Click 'Apply Dashboard' and choose the 'RSS_2.0_recent_docs.ftl' template, then click 'OK'.

Step 3:  From the Space Details page, right-click on the 'External Access URL' link and copy the link location, then paste the URL into your favorite text editor.

Step 4:  Edit the URL link and change the '/navigate/showSpaceDetails/' part to '/template/', then add '?mimetype=text%2Fxml&guest=true' to the end.

Step 5:  Copy and paste this final URL into your preferred RSS reader.

You should now get a feed of all content that has been modified in the past 7 days.  Your RSS URL should look something like:


http://myserver:8080/alfresco/template/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554?mimetype=text%2Fxml&guest=true

If you do not want to use the Dashboard approach, then you will need to find the Node Reference for the RSS template (from its Details page) and build a URL that also includes it.  The format of that URL will be:


http://myserver:8080/alfresco/template/workspace/SpacesStore/<space-node-ref>/workspace/SpacesStore/<template-node-ref>?mimetype=text%2Fxml&guest=true

NOTE:  You must ensure that the Guest user has access to the space you wish to feed the RSS stream from! This can be achieved using the 'Manage Space Users' dialog and inviting the 'Guest' user into the Space.


GuestTemplateContentServlet


This servlet has the following class name:

org.alfresco.web.app.servlet.GuestTemplateContentServlet

This servlet follows exactly the same rules as TemplateContentServlet, the same parameters and usage model applies.

The URL to the servlet is of the form:

/alfresco/guestTemplate/<workspace>/<store>/<nodeid>

or

/alfresco/guestTemplate/<workspace>/<store>/<nodeid>/<workspace>/<store>/<nodeid>

The main difference with this servlet is the handling of sessions. This servlet will always run the template as the 'guest' user, however, the guest user will not be logged in, as is the case when TemplateContentServlet is used. The other difference is if the node or the template referenced by the URL is not accessable to the guest user, a 403 Forbidden error will be returned rather than the login page.


CommandServlet


This servlet has the following class name:

org.alfresco.web.app.servlet.CommandServlet

A generic servlet that can be configured and customized with custom classes using the well known Command and Strategy design patterns. It is responsible for direct execution of named commands using a configured command processor instance. For example in the default installation of Alfresco 1.3, a Workflow command processor is supplied that can execute 'approve' and 'reject' commands. This mechanism allows the use of simple URLs to execute commands against nodes without the web-client interface.

Servlet URL is of the form:

/alfresco/command/<command-processor>/<command>/<args...>

The args element(s) is optional and depend on the individual command being executed. It is up to the command to specify and process args as appropriate for the implementation (see below). E.g. for the workflow command processor executing the 'approve' command the URL could be of the form:

/alfresco/command/workflow/approve/<workspace>/<store>/<nodeid>

URL arguments:

return-page - if supplied then instead of the status page, the servlet will redirect to the specified URL once the command has been completed.

ticket - can be supplied as a URL argument to allow authentication for external use - see above.


Command Processors


The first element in the URL after the servlet name specifies the command processor to use. Command processors are simple classes responsible for executing a related set of commands. They are configured in web-client-config.xml - or in the appropriate extension config file. The config block is as follows:

  <config evaluator='string-compare' condition='Command Servlet'>



     <command-servlet>
        <command-processor name='workflow' class='org.alfresco.web.app.servlet.command.WorkflowCommandProcessor' />
     </command-servlet>
  </config>

Any number of command-processor config elements can be supplied.

A command processor class must implement the following interface:

org.alfresco.web.app.servlet.command.CommandProcessor


/**
  * This interfaces defines the contract and lifecycle of a Servlet Command Processor.
  *
  * A command processor is defined as a class capable of executing a set of related Command
  * objects. It performs the bulk of the work for the command servlet. The processor impl
  * is responsible for validating that the command can be processed (given the supplied remaining
  * URL arguments from the servlet) and processing the command. It is also responsible for
  * supply an output status page on successfuly execution of the command.
  *
  * The arguments passed to a Command Processor are the remaining URL elements from the command
  * servlet URL after removing the web-app name, servlet name and command processor name. 
  *
  * @author Kevin Roast
  */
public interface CommandProcessor
{
   /**
    * Pass and validate URL arguments for the command processor. Validate if the command can be
    * executed given the arguments supplied. Generally at this post a Command Processor will
    * convert the supplied arguments to the objects it expects, and also check any permissions
    * that are required by the current user to execute the command.
    *
    * @param serviceRegistry  ServiceRegistry instance
    * @param command          Name of the command the arguments are for
    * @param args             String[] of the remaining URL arguments to the command servlet.
    *
    * @return true if the command can be executed by the current user given the supplied args.
    */
   public boolean validateArguments(ServiceRegistry serviceRegistry, String command, String[] args);
  
   /**
    * Process the supplied command name. It is the responsibility of the Command Processor
    * to lookup the specified command name using the CommandFactory registry. For that reason
    * it also has the responsiblity to initially register commands it is responsible for so
    * they can be constructed later. If the supplied command is unknown to it then an
    * exception should be thrown to indicate this.
    * 
    * @param serviceRegistry  ServiceRegistry
    * @param request          HttpServletRequest
    * @param command          Name of the command to construct and execute
    */
   public void process(ServiceRegistry serviceRegistry, HttpServletRequest request, String command);
  
   /**
    * Output a simple status message to the supplied PrintWriter.
    * It can be assumed that the process() method was successful if this method is called.
    *
    * @param out              PrintWriter
    */
   public void outputStatus(PrintWriter out);
}

The lifecycle of the command processor is as follows:


validateArguments() : The array of args passed to the method represent the remaining URL elements that followed the command processor and command names on the URL - this may be empty. The command processor should validate that the supplied arguments are valid for the command to be executed, throwing a runtime exception if this is not the case. The command processor will generally convert the supplied args to objects it needs (e.g. a NodeRef) ready for command execution later.
process() : Performs the bulk of the work for the command processor. It is passed a named command to execute against the previously arguments as passed to validateArguments(). The command processor should create the named command using the CommandFactory singleton instance and execute it - throwing an approriate runtime exception if any error occurs. An example process() method may look as follows:


  public void process(ServiceRegistry serviceRegistry, HttpSession session, String command)
  {
     Map<String, Object> properties = new HashMap<String, Object>(1, 1.0f);
     // all workflow commands use a 'target' Node property as an argument
     properties.put(ApproveWorkflowCommand.PROP_TARGET, this.targetRef);
     Command cmd = CommandFactory.getInstance().createCommand(command);
     if (cmd == null)
     {
        throw new AlfrescoRuntimeException('Unregistered workflow command specified: ' + command);
     }
     cmd.execute(serviceRegistry, properties);
  }



outputStatus() : called on successful execution of the command - it should output a simple success status message to the supplied PrintWriter.

In addition, it is the responsibilty of the command processor instance to register the related set of named commands it is expecting to process with the CommandFactory singleton instance. This is generally performed within a static initialiser block, for example:

  static
  {
     // add our commands to the command registry
     CommandFactory.getInstance().registerCommand('approve', ApproveWorkflowCommand.class);
     CommandFactory.getInstance().registerCommand('reject', RejectWorkflowCommand.class);
  }

The named commands are registered by name against class. It should be noted that for each execution of a command a new command processor instance is created and then discarded at the end of the lifecycle.

Available in Alfresco 1.4!

The servlet now supports POST'ed parameters. All supplied parameters will be stored in the map of arguments passed to the command processor. Please note though that file uploads are not supported.


Workflow Command Processor


Responsible for executing 'approve' and 'reject' workflow commands on a Node.
The appropriate workflow command will be executed on node specified by the NodeRef elements in the URL. Currently the only available command names are 'approve' and 'reject'.
Returns a very simple status HTML page on successful execution of the workflow command.

Examples:

/alfresco/command/workflow/approve/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554
/alfresco/command/workflow/reject/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554

Task Command Processor


Responsible for managing advanced workflow tasks.  The appropriate task command will be executed on the task specified by the taskId element in the URL.  Currently, the only available command is 'end' which accepts an optional transition name.  Returns a very simple status HTML page on successful execution of the task command.  Valid taskId and transition names are those returned by the Workflow Service.

URL construct:

/alfresco/command/task/end/<taskId>/transition

Examples:

/alfresco/command/task/end/jbpm$12
/alfresco/command/task/end/jbpm$1234/approve

Script Command Processor


Responsible for processing an Alfresco JavaScript through the 'execute' command.
The NodeRef supplied as the first 3 arguments of the node specify the script to execute. Optionally an additional NodeRef can be specified to provide a document node context to the script (in addition the parent folder of the document node will then be used as the space context to the script).
Returns the result of the script (if any) converted to a string as the HTML response.
See the JavaScript API page for more information on the Alfresco JavaScript API.

Examples:

/alfresco/command/script/execute/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554
/alfresco/command/script/execute/workspace/SpacesStore/d8470f03-b80a-11da-97b9-8d453af5a554/workspace/SpacesStore/12345678-9012-11da-97b9-8d453af5a554

Any additional URL parameter arguments can be passed to the servlet, they will be collected and supplied to the scripting data-model into an associative JavaScript array object called args. The args object is accessable from the root of the script scope and contains all the URL name/value pairs supplied to the servlet.

Available in Alfresco 1.4!

The reference to the script or the context node can now be specified as 'scriptPath' and 'contextPath' URL arguments rather than as NodeRef elements. For example:

/alfresco/command/script/execute?scriptPath=/Company%20Home/Data%20Dictionary/Scripts/append%20copyright.js&contextPath=/Company%20Home/file.txt

Paths are specified in a similar way to a WebDav path - they are 'cm:name' based URL encoded strings.

Note that the entire URL must be URL encoded appropriately.

It is not not always desirable to allow all users to do this as it is an advanced feature - in Alfresco 3.3 this is changed so that unless configured, only the admin user can perform this action via a command servlet URL.

The Explorer web-client custom config to re-enable this feature for non-admin users is as follows:



<alfresco-config>
   <config>
      <client>
         <allow-user-script-execute>true</allow-user-script-execute>
      </client>
   </config>
</alfresco-config>

Commands


The element in the URL after the command processor name is the command the command processor should execute. Commands are simple classes responsible for encapsulating a single task. Each command processor is responsible for a known set of register commands. Command classes must implement the following interface:

org.alfresco.web.app.servlet.command.Command


/**
* Simple servlet command pattern interface.
*
* @author Kevin Roast
*/
public interface Command
{
   /**
    * Execute the command
    *
    * @param serviceRegistry     The ServiceRegistry instance
    * @param properties          Bag of named properties for the command
    */
   public void execute(ServiceRegistry serviceRegistry, Map<String, Object> properties);
  
   /**
    * @return the names of the properties required for this command
    */
   public String[] getPropertyNames();
}

The command processor instance responsible for a command should pass a Map of appropiate properties (generated from the arguments supplied to the command processor) to the execute() method.

The command implementation should check that the appropriate properties have been passed to the execute() method and then perform any work.


Command Factory


This singleton class is a registry for Command class definitions and can create new Command instances by name. The class is as follows:

org.alfresco.web.app.servlet.command.CommandFactory

SecurityWeb Client CustomizationCore Concepts

Attachments

    Outcomes