This page relates to the use of plain XForms applications. If you use Form Builder and Form Runner, the content of this page is probably not relevant.
Orbeon doesn't recommend you write new code using this technology. Instead, Orbeon recommends that you use you use Form Builder and Form Runner, including the Form Runner Java Embedding API for integration of Java applications with Form Runner.
Some example applications shipping with Orbeon Forms hook up XForms by using the Page Flow Controller (PFC) and XML pipelines. But it is also possible to use the XForms engine without worrying about these technologies and to simply use it as an XForms engine for your Java applications.
The recommended way of using XForms this way is what is called separate deployment. With this method, your application is deployed in its own Java web archive (WAR), and Orbeon Forms in its own WAR. This has the following benefits:
Easier upgrades of both your application and Orbeon Forms.
Preventing situations where different versions of JAR files could conflict.
Cleaner application architecture.
This is implemented with the help of a servlet filter, referred to as the XForms filter.
The value of the
oxf.xforms.renderer.context parameter specifies the context into which you have deployed Orbeon Forms. By default, Orbeon forms deploys to
/orbeon so this value is usually safe. If you deploy Orbeon Forms to another context, you need to change this value accordingly.
<url-pattern> defined under the first
<filter-mapping> has the value
/xforms-jsp/*. This means that all the data generated by URLs starting with
/xforms-jsp/ is post-processed by Orbeon Forms. You can change this value as desired.
<url-pattern> defined under the second
<filter-mapping> has the value
/orbeon/* value is related to the default context into which you deploy Orbeon Forms: if you change you context, you change this value as well.
<!-- Filter configuration --><filter><filter-name>orbeon-xforms-filter</filter-name><filter-class>org.orbeon.oxf.servlet.OrbeonXFormsFilter</filter-class><init-param><param-name>oxf.xforms.renderer.context</param-name><param-value>/orbeon</param-value></init-param><init-param><param-name>oxf.xforms.renderer.default-encoding</param-name><param-value>UTF-8</param-value></init-param>--></filter><!-- Any web resource under /xforms-jsp is processed by the XForms engine --><filter-mapping><filter-name>orbeon-xforms-filter</filter-name><url-pattern>/xforms-jsp/*</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping><!-- This is necessary so that XForms engine resources can be served appropriately --><filter-mapping><filter-name>orbeon-xforms-filter</filter-name><url-pattern>/orbeon/*</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping>
[SINCE Orbeon Forms 4.6.1]
The filter parameter
oxf.xforms.renderer.default-encoding allows you to specify a default character encoding when the content provided by the servlet or JSP page doesn't specify one. Previously, the default character encoding was hardcoded to
ISO-8859-1. Since 4.6.1 the hardcoded default remains this, but you can change it with
oxf.xforms.renderer.default-encoding. The default Orbeon Forms web.xml overrides this default to
UTF-8, which is what most modern HTML uses.
Limitation: Currently you cannot deploy your application in the default servlet context (i.e. the empty context).
Your WAR must be deployed in such a way that it is allowed forwarding requests to other web applications.
With the default configuration shown above, all JSPs located in the directory called
xforms-jsp in your WAR are processed by the XForms engine. However, it is likely that you will prefer another location. In that case, you just change the
You must not deploy resources under the
/orbeon/ directory, as that directory is reserved for Orbeon Forms resources.
You don't have to produce XForms from JSP. You can do so directly from servlets, or other Java web application frameworks (usually based on servlets and template languages). What matters is that the filter defined in
web.xml kicks in for those resources and that you produce well-formed XML as output. For this to happen, you modify the
<filter-mapping>accordingly to enable the filter for the URLs handled by your framework.
You control security for all of your application's pages, including XForms pages, in your own application's
web.xml. It is not possible to access your application's XForms pages by accessing Orbeon Forms URLs directly: your application controls the generation of XForms content, not Orbeon Forms.
However by default you can still access Orbeon Forms applications through Orbeon Forms URLs. If you don't want to deploy any Orbeon Forms applications directly, you can block external accesses to the Orbeon Forms WAR by configuring the Orbeon Forms WAR's
You deploy Orbeon Forms as a separate WAR with the following steps:
Deploy your own application as a separate WAR.
WEB-INF/lib/orbeon-xforms-filter.jar from the Orbeon Forms WAR into your application's
Configure your application's
web.xml as described in the previous section to setup the Orbeon Forms XForms filter.
Setup your application in cross-context mode, as described in the previous section.
From the uncompressed
orbeon``.war, you can remove:
All the files under
WEB-INF/resources, except the directory
WEB-INF/resources``/config and its content. (This directory contains configuration files which you might want to change, in particular the properties files.)
All the application-server or portal configuration files under
weblogic.xml. (The application-server specific files contain an example of how to declare a data source, so you can safely remove those files even if they are for the application server you are using.)
Before forwarding Ajax requests to Orbeon Forms, the XForms filter checks that a session exists for the current user. This is done to deal with the scenario where users log out from your application but still have, say in another tab, a form created with Orbeon Forms open. When they logout, you invalidate the session in your app, but the Orbeon session is still there. Without this check, after logging, users could switch to the other tab, and continue to interact with the form, and it would work as the Ajax requests would be routed to Orbeon Forms, whose session is still alive, which, obviously, you wouldn't want that happen.
If your application never creates a session, this check will always fail, and Ajax request will never go through. To get around this, you can either:
Setup your application server so your application session is shared with the Orbeon Forms session.
Always create a session in your code, e.g. with
request.getSession(), even if you're not going to store anything in that session.
All URLs are designed go through your web application's context, so your application and the Orbeon Forms XForms engine automatically share the same session.
Your JSP pages or servlets must generate well-formed XML documents that contain XHTML and XForms tags. There are two methods of passing this information to Orbeon Forms, described below.
With this method, your JSP or servlet simply outputs XHTML and XForms in its output as it would HTML content. For example, a basic JSP page typically looks like this:
<xh:htmlxmlns:xh="http://www.w3.org/1999/xhtml"xmlns:xf="http://www.w3.org/2002/xforms"xmlns:xxf="http://orbeon.org/oxf/xml/xforms"><xh:head><xh:title>Guess The Number</xh:title><xf:model><xf:instance>...</xf:instance></xf:model></xh:head><xh:body><xh:h1>My Page</xh:h1><xf:input ref="..."/>...</xh:body></xh:html>
When using JSP, you can then use JSP tags as usual to produce your XHTML and XForms page as you would a regular HTML page.
With this method, the output of your JSP or servlet is ignored by Orbeon Forms. Instead, you set an attribute into the
HttpServletRequest object which is passed to servlets (and also accessible in JSP through the
The name of the attribute must be
"oxf.xforms.renderer.document". It may contain XHTML and XForms as an XML Document Object Model (DOM), as a dom4j
Document, or as a String containing XML.
When you deploy your XForms in the Orbeon Forms resources directory, you can reference instances in separate files from your XForms with:
<xf:instance src="oxf:/path/file.xml">. You can also use XInclude to include arbitrary parts of your form with:
<xi:include href="``oxf:/path/file.xml">. The
oxf: scheme tells Orbeon Forms that the file is loaded from the resource directory, typically from
WEB-INF/resources inside the Orbeon Forms war file.
You could do this in separate deployment as well, but you would need to put the files to include in the Orbeon Forms resource directory. Since that resource directory is typically inside the Orbeon Forms war file, doing so would defeat the purpose of using separate deployment.
For instances, you could use a relative URL such as
<xf:instance src="http://wiki.orbeon.com/file.xml">. If the URL for your form is
http://localhost/myapp/forms/registration.jsp, then Orbeon Forms will load the file to include from
http://localhost/myapp/forms/file.xml. Most likely this will work, but you will incur the cost of an additional HTTP request every time the page is loaded.
So instead, you will want to use an inclusion mechanism native to the template language you are using in your application. If you write JSP, use the include directive. To include an instance, use:
<xf:instance id="my-instance"><%@include file="file.xml"%></xf:instance>
You can use the include directive in the same way to include an arbitrary part of your form stored in a separate file:
<xh:body><!-- Part of the form inline. --><xh:div>...</xh:div><!-- Part of the form stored in a spearate file --><%@include file="part.xhtml"%></xh:body>
Say your application produces XForms using JSP. You might want to pass some information from the Java side to the XForms side. This could be user profile information, data retrieved from a database, etc.
It may be tempting to directly inline data into instances, like this:
<xf:instance id="profile-instance"><profile><user-id><% request.getAttribute('user-id') %></user-id></profile></xf:instance>
This, is not a good way, for the following reason. The XForms engine will receive for a first request e.g.:
Then, for another request:
The two are different, and this is enough for the XForms engine to determine that the two XForms documents are different, and so to disable caching.
The bottom line is this: in order for the best case scenario of caching to happen, the XForms engine must see the same incoming XForms markup.
The good news is that you can initialize instance data in a way that will achieve that, directly in XForms. For example:
With this XForms, the request attribute is queried directly from XForms and stored into the instance. Note the text/plain second parameter, which makes sure that the user-id attribute is not parsed as XML.
The difference with the first example is that the XForms code is the same for all requests, so caching can work.If the request attribute is an entire instance in XML format, you could also write:
<xf:instance id="profile-instance"><!-- Start with empty profile --><profile/></xf:instance><!-- Then load profile from request --><xf:insertevent="xforms-model-construct-done"ref="instance('profile-instance')"origin="xxf:get-request-attribute('profile')"/>
In this case, the value will be parsed as XML before insertion.
You can similarly use other functions, including:
Orbeon Forms supports the
input:instance URI to access XML data submitted to the current page:
<xf:instance id="input" src="input:instance"/>
This allows you to implement scenarios like this one:
JSP page is accessed through HTTP GET
Page generates XForms
XForms is processed by the Orbeon filter and XForms engine
HTML is sent to the browser
User performs action on page 1. XForms server performs a submission to another JSP page, submitting XML through the HTTP
New JSP page is accessed through HTTP
PUT 1. Page generates XForms 2. XForms is processed by the Orbeon filter and XForms engine 3. XForms engine has access to the submitted XML data through the
input:instance URI 4. HTML is sent to the browser NOTE: In separate deployment, you can use
input:instance only if your JSP or servlet has not attempted to read the request body first!
The backend of your forms is usually best implemented with "services" which can be called with
<xf:submission>. Most of the time, XML is being posted to the service and XML is returned by the service. Since services take XML as input and generate XML, XML pipelines are an ideal tool to implement services.
However, you can also implement simple services directly with JSP. To produce XML output, your JSP page has to set the appropriate content type for the response with:
To read XML input, you can create an object that represents the input document using the dom4j API:
Document queryDocument = xmlReader.read(request.getInputStream())
You then use this object to gather data about the query sent to your service.
In XForms you reference the service with the action attribute of
What happens when your JSP or servlet produces an XHTML and XForms document?
If configured appropriately in
web.xml, the Orbeon Forms XForms filter kicks in and intercepts the output of your JSP or servlet (whether produced the regular way or passed as a request attribute).
The Orbeon Forms XForms filter then forward the request to Orbeon Forms, at the location
Orbeon Forms reacts to
/xforms-renderer by extracting the XHTML and XForms document from the forwarded request.
Orbeon Forms sends the XHTML and XForms document to the standard Orbeon Forms epilogue called
/config/epilogue-servlet.xpl. The epilogue performs several tasks, including transforming XHTML and XForms into HTML that the browser can understand. The default configuration of this pipeline should be fine for most use cases, which means you usually don't need to worry about it.
Note that the epilogue applies the default theme under
/config/theme-plain.xsl. However, it does not perform further URL rewriting by default.
The Orbeon Forms filter implemented by
OrbeonXFormsFilter sets the following request attributes:
- contains request path, i.e.
XHTML document as string
the string must contain well-formed XML
content-type of the document passed
whether the filter sees an existing session or not
NOTE: In general, you do not need to know about these properties to use the Orbeon Forms filter.