blob: e6f13ff0f92a92bf12de0a710823f3f56f382745 [file] [log] [blame]
Title: Web Applications
<H3><A name="WebApplications-PuttingCayenneFilesinWebApplicationCLASSPATH"></A>Putting Cayenne Files in Web Application CLASSPATH</H3>
<P>When deploying an application in a web container it is possible to follow the procedure for the standalone applications, i.e. put all XML files in the application CLASSPATH (e.g. in &quot;mywebapp/WEB-INF/classes/&quot;, but DON'T put it in container shared locations!). Session DataContext can be obtained via ServletUtil:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">HttpSession session = ...;
DataContext context = ServletUtil.getSessionContext(session);</PRE>
</DIV></DIV>
<P>However you may consider a deployment procedure described below, as it provides more flexibility and a number of additional useful features.</P>
<H3><A name="WebApplications-CayenneServletFilter"></A>Cayenne Servlet Filter</H3>
<P>Adding the following filter to the <TT>web.xml</TT> would automate Cayenne setup in the web application:</P>
<DIV class="preformatted panel" style="border-width: 1px;"><DIV class="preformattedContent panelContent">
<PRE>&lt;filter&gt;
&lt;filter-name&gt;CayenneFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.apache.cayenne.conf.WebApplicationContextFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;CayenneFilter&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</PRE>
</DIV></DIV>
<P>The filter will ensure that for each matching request a ObjectContext (which is actually a DataContext instance) is bound to the request thread. Context itself is session-scoped. So you can retrieve it anywhere in the application, even if you don't have a reference to the web environment:</P>
<DIV class="code panel" style="border-width: 1px;"><DIV class="codeContent panelContent">
<PRE class="code-java">ObjectContext context = BaseContext.getThreadObjectContext();</PRE>
</DIV></DIV>
<P>Filter can match a specific URL as shown above, or a specific servlet:</P>
<DIV class="preformatted panel" style="border-width: 1px;"><DIV class="preformattedContent panelContent">
<PRE>&lt;servlet&gt;
&lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
&lt;servlet-class&gt;org.example.MyServlet&lt;/servlet-class&gt;
&lt;load-on-startup&gt;0&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;filter&gt;
&lt;filter-name&gt;CayenneFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.apache.cayenne.conf.WebApplicationContextFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;CayenneFilter&lt;/filter-name&gt;
&lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;
&lt;/filter-mapping&gt;</PRE>
</DIV></DIV>
<P>Additionally the filter supports putting files in <TT>myapp/WEB-INF/</TT> directory instead of the CLASSPATH, so a .war file may look like this:</P>
<DIV class="preformatted panel" style="border-width: 1px;"><DIV class="preformattedContent panelContent">
<PRE>index.jsp
WEB-INF/cayenne.xml
WEB-INF/xyz.map.xml
WEB-INF/lib/...</PRE>
</DIV></DIV>
<P>Actually, Cayenne files can be stored in any subdirectory of <TT>myapp/WEB-INF/</TT>. To specify a subdirectory, you'll need to add <TT>&lt;context-param&gt;</TT> named <TT>cayenne.configuration.path</TT> to your application descriptor:</P>
<DIV class="preformatted panel" style="border-width: 1px;"><DIV class="preformattedContent panelContent">
<PRE>&lt;context-param&gt;
&lt;param-name&gt;cayenne.configuration.path&lt;/param-name&gt;
&lt;param-value&gt;/WEB-INF/config/cayenne-files&lt;/param-value&gt;
&lt;/context-param&gt;</PRE>
</DIV></DIV>
<H3><A name="WebApplications-ObjectContextScope"></A>ObjectContext Scope</H3>
<P>ServletUtil and WebApplicationContextFilter would both provide an ObjectContext shared between the requests in the same user session (session-scoped context). This is the default behavior. However, depending on the application needs, you may choose to use application-scoped context (usually for read-only parts of the application, and combined with caching), or per-request context (to avoid race conditions on long-running operations). In those cases you won't be able to use ServletUtil and WebApplicationContextFilter, but you can easily write your own correctly scoped replacements, or set it up via an IoC container, such as Spring.</P>