[jboss-cvs] JBossAS SVN: r103724 - projects/snowdrop/examples/trunk/sportsclub/docs/guide/en-US.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Apr 8 23:03:40 EDT 2010
Author: marius.bogoevici
Date: 2010-04-08 23:03:40 -0400 (Thu, 08 Apr 2010)
New Revision: 103724
Modified:
projects/snowdrop/examples/trunk/sportsclub/docs/guide/en-US/Modules.xml
Log:
docs
Modified: projects/snowdrop/examples/trunk/sportsclub/docs/guide/en-US/Modules.xml
===================================================================
--- projects/snowdrop/examples/trunk/sportsclub/docs/guide/en-US/Modules.xml 2010-04-09 01:16:25 UTC (rev 103723)
+++ projects/snowdrop/examples/trunk/sportsclub/docs/guide/en-US/Modules.xml 2010-04-09 03:03:40 UTC (rev 103724)
@@ -433,8 +433,9 @@
<para>The following bean is used for backing JSF pages. Please note
that Spring beans defined in the web layer may use scopes, and a
significant number of the Spring beans used in Reservations
- application are session-scoped. Spring provides a request scope as
- well.</para>
+ application are session-scoped (like the one in the following
+ example). Spring provides a request scope as well, but it is not used
+ in this example.</para>
<programlisting><bean id="reservationCreate" class="org.jboss.snowdrop.samples.sportsclub.jsf.beans.ReservationCreate" scope="session" init-method="init">
<property name="reservationService" ref="reservationService"/>
@@ -444,15 +445,314 @@
</bean></programlisting>
<informalexample>
- <para>P</para>
+ <para>In order to be make the Spring beans visible to JSF pages, a
+ special VariableResolver has to be defined in
+ /WEB-INF/faces-config.xml.</para>
+
+ <informalexample>
+ <para><programlisting><application>
+ <!-- other definitions -->
+ <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
+</application></programlisting>Now, we can use the Spring bean defined
+ above directly in a JSF page, as in the following excerpt from
+ createReservation.xhtml:</para>
+
+ <informalexample>
+ <para><programlisting><rich:panel>
+ <f:facet name="header">Select Account</f:facet>
+ <h:form id="AccountSelectForm">
+ <rich:extendedDataTable id="accountsTable" value="#{accountFilterCreate}" var="account"
+ selectionMode="single"
+ selection="#{accountFilterCreate.selection}"
+ enableContextMenu="true"
+ height="250px"
+ rows="5">
+ <a4j:support event="onselectionchange"
+ action="#{reservationCreate.updateSelectedAccount}"
+ reRender="reservationDetails"/>
+
+ <rich:column label="Id" width="7%">
+ <f:facet name="header">
+ <h:outputText value="Id"/>
+ </f:facet>
+ <h:outputText value="#{account.id}"/>
+ </rich:column>
+
+ <rich:column label="First Name">
+ <f:facet name="header">
+ <h:outputText value="First Name"/>
+ </f:facet>
+ <h:outputText value="#{account.subscriber.name.firstName}"/>
+ </rich:column>
+
+ <rich:column label="Last Name">
+ <f:facet name="header">
+ <h:outputText value="Last Name"/>
+ </f:facet>
+ <h:outputText value="#{account.subscriber.name.lastName}"/>
+ </rich:column>
+
+ <rich:column label="City">
+ <f:facet name="header">
+ <h:outputText value="City"/>
+ </f:facet>
+ <h:outputText value="#{account.subscriber.address.city}"/>
+ </rich:column>
+
+ <rich:column label="Country">
+ <f:facet name="header">
+ <h:outputText value="Country"/>
+ </f:facet>
+ <h:outputText value="#{account.subscriber.address.country}"/>
+ </rich:column>
+
+ <f:facet name="footer">
+ <rich:datascroller id="scrollerAccount" for="accountsTable" maxPages="5"
+ page="#{accountFilterCreate.currentPage}"/>
+ </f:facet>
+ </rich:extendedDataTable>
+ </h:form>
+ </rich:panel></programlisting>All the EL variables
+ that are used in the previous example, including the ones
+ referenced in the Richfaces elements are, in fact, Spring beans.
+ They can be used either as backing beans for retrieving and
+ setting values, as well as for invoking methods corresponding to
+ JSF events.</para>
+ </informalexample>
+ </informalexample>
</informalexample>
</informalexample>
</section>
+
+ <section>
+ <title>Invoicing: Spring MVC and EJB</title>
+
+ <para>The Invoicing application provides another example of
+ interoperability between Spring and the Java EE services provided by
+ JBoss. If in the previous example, the business tier was implemented
+ using Spring and the web tier was using JSF, in this example the roles
+ are reversed: the business tier is using EJB and the web tier is using
+ Spring.</para>
+
+ <para>The Spring MVC beans are defined in the
+ /WEB-INF/spring-servlet-context.xml file, referenced by the Spring MVC
+ DispatcherServlet definition that is described WEB-INF/web.xml. For this
+ implementation, we have chosen the Spring 2.5 annotation-based
+ configuration, and the AccountController class that implements the
+ controller part of the configuration is injected with EJBs defined in
+ section 3.2:</para>
+
+ <para><informalexample>
+ <para><programlisting>@Controller
+public class AccountController
+{
+
+ @EJB(mappedName = "sportsclub/BillingService")
+ BillingService billingService;
+
+ @EJB(mappedName = "sportsclub/SubscriptionService")
+ SubscriptionService subscriptionService;
+
+ /* some code ommitted */
+
+ @RequestMapping(value = "/accountDetail.do", method = RequestMethod.GET)
+ ModelMap getAccountDetail(@RequestParam("id") String id)
+ {
+ Account account = subscriptionService.findAccountById(Long.parseLong(id));
+
+ List<Invoice> invoices = billingService.getInvoices(account);
+
+ boolean hasCurrentInvoice = false;
+ Date currentDate = new Date();
+
+ for (Invoice invoice: invoices)
+ {
+ if (invoice.getBillingPeriod().contains(currentDate))
+ {
+ hasCurrentInvoice = true;
+ break;
+ }
+ }
+
+ List<Payment> payments = billingService.getPayments(account);
+
+ ModelMap model = new ModelMap();
+ model.addAttribute(account);
+ model.addAttribute("invoices", invoices);
+ model.addAttribute("payments", payments);
+ model.addAttribute("hasCurrentInvoice",hasCurrentInvoice);
+ return model;
+ }
+
+
+ @RequestMapping(value = "/generateInvoice.do", method = RequestMethod.POST)
+ ModelMap generateInvoice(@RequestParam("id") String id)
+ {
+ Account account = subscriptionService.findAccountById(Long.parseLong(id));
+ Invoice invoice = billingService.generateInvoice(account);
+
+ ModelMap model = new ModelMap();
+ model.addAttribute("id",id);
+ model.addAttribute(invoice);
+ return model;
+ }
+
+}
+</programlisting>The @Controller annotation will be detected by Spring, as it
+ does a scanning of the classpath which is prompted by including the
+ following line into /WEB-INF/spring-servlet-context.xml.</para>
+
+ <informalexample>
+ <para><programlisting><context:component-scan base-package="org.jboss.snowdrop.samples.sportsclub.springmvc"/>
+</programlisting></para>
+ </informalexample>
+ </informalexample></para>
+
+ <para>As a Spring-managed object, the bean is injected with the EJBs
+ BillingService and SubscriptionService, as required by annotated the
+ respective fields with the @EJB annotation.</para>
+
+ <para>The @RequestMapping-annotated methods will be executed when the
+ user is accessing the specified URL and HTTP method. The request
+ parameters will be bound to method arguments. In the example above,
+ invoking the URL
+ http://localhost:8080/sportsclub/invoicing/accountDetail.do?id=1 will
+ cause the invocation accountController.getAccountDetail(1). The method
+ will invoke the appropriate business services (in this case, exposed as
+ EJBs) and will return a map of business object collections, indexed by
+ their names. Spring MVC will take care of setting them on the request,
+ so that they can be used for rendering the response.</para>
+
+ <para>By default, Spring MVC will try to find a view whose name is
+ 'accountDetail', and based on the view resolver definition from
+ /WEB-INF/spring-servlet-context.xml, it will use the JSP file at
+ /WEB-INF/jsp/accountDetail.jsp. This JSP uses the Spring tag libraries
+ for form processing, so that the collections previously returned will be
+ accessible using JSTL expressions, and furthermore, we will find the
+ following declaration:</para>
+
+ <informalexample>
+ <programlisting><form:form action="generateInvoice.do">
+ This account does not have an invoice for the current billing period.<p/>
+ You can create one now:
+ <input type="hidden" name="id" value="<c:out value="${account.id}"/>">
+ <input type="submit" value="Create invoice"/><br/>
+ </form:form></programlisting>
+ </informalexample>
+
+ <para>Clicking the 'Create Invoice' button will result in a POST
+ submission to
+ http://localhost:8080/sportsclub/invoicing/generateInvoice.do?id=1 and
+ the subsequent invocation of the generateInvoice method.</para>
+
+ <para>A small note here: in order to be able to demonstrate a few
+ Spring/JBoss integration features, the Invoicing application also
+ contains a number of business services that are using Spring. They do
+ not play any role in the Spring MVC/EJB integration, and we will discuss
+ more about them in section 6.</para>
+ </section>
+
+ <section>
+ <title>An problem of reusing content</title>
+
+ <para>Having three different web applications to be included in the same
+ package raises the problem of reusing some content. Surely, the images
+ and stylesheets that are part of the application design can be copied in
+ each individual project, but this raises the problem of maintainability.
+ Therefore, most of the static content used by the Sportsclub application
+ is defined in a separate web module, sportsclub-staticwebcontent, which
+ is then included by Maven at build time as follows:</para>
+
+ <para><informalexample>
+ <para><programlisting><dependency>
+ <groupId>org.jboss.snowdrop.samples.sportsclub</groupId>
+ <artifactId>sportsclub-staticwebcontent</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
+ <scope>runtime</scope>
+</dependency></programlisting><note>
+ <para>When working in an IDE this might produce an undesirable
+ side-effect. If the IDE does not know how to apply Maven
+ overlays correctly, the static content may not be available when
+ building and deploying the application through the IDE, without
+ Maven. This does not affect the general functionality of the
+ application but may affect the look and feel in that particular
+ situation. However, if the application is build using Maven this
+ will not be a problem.</para>
+ </note></para>
+ </informalexample></para>
+ </section>
</section>
<section>
- <title>Other Enterprise Integration features</title>
+ <title>Enterprise Integration Features</title>
- <para></para>
+ <para>Apart from the Spring/JSF/EJB integration, which you have seen in
+ the previous sections, the Sportsclub application suite provides a few
+ other examples of integrating Spring and JBoss. Since all the features are
+ Spring-based, they have been included as business services of the
+ Invoicing web application. </para>
+
+ <section>
+ <title>Payment processing: JMS integration through JCA</title>
+
+ <para>Besides displaying the current status of invoices and payments for
+ a given account and generating invoices through the web interface, the
+ Sportsclub application can also process payments for various accounts.
+ The assumption of this scenario is that the system can receive payment
+ notifications asynchronously, through a JMS queue. Once such a payment
+ has been received, it can be processed by a message-driven component,
+ which in our case is a Spring bean. In order to take full advantage of
+ the managed environment provided by the application server, the Spring
+ bean will be invoked in a JCA context.</para>
+ </section>
+
+ <section>
+ <title>Aspects and auditing</title>
+
+ <para>Payments must be audited. Besides keeping a record of payments
+ associated with an account, we may want to set up an auditing service
+ that will audit every attempt of making a payment. In the simplest case
+ we can just log that information, although in a real life scenario
+ things may be more sophisticated. In order to do so, we set up a
+ PaymentAuditor aspect that intercepts every call made to the
+ PaymentProcessor.</para>
+
+ <para>The solution applied in this application is to use the 'aop'
+ namespace provided by Spring and XML configuration, defining pointcuts
+ via AspectJ syntax.</para>
+ </section>
+
+ <section>
+ <title>Configuring Spring beans through JMX</title>
+
+ <para>JMX is a very important tool for monitoring and configuring Java
+ applications. Collecting information about the system and the ability of
+ making configuration at runtime are important administration tools. For
+ this example, the requirement is to be able to turn auditing on and off,
+ at runtime, as required. Removing an aspect once it has been applied by
+ Spring is not possible, so the solution in this case is to define a flag
+ property on the aspect, which controls whether the auditing
+ functionality will be invoked or not. </para>
+
+ <para>In order to be able to make changes at runtime, the Spring bean
+ which implements the aspect will be configured as a JMX bean and
+ registered in the MBean server of JBoss. As a result, you can turn this
+ functionality on and off directly from the JBoss AS JMX administration
+ console. </para>
+ </section>
+
+ <section>
+ <title>Payment processing: exposing a JAX-WS web service</title>
+
+ <para>Another way of interacting with external applications, is by
+ exposing a web service. In this scenario, payment notifications may not
+ arrive only as asynchronous events on a message queue, but also as
+ synchronous web service invocations. For this purpose, the application
+ will expose a Spring bean with JAX-WS annotations as a web
+ service.</para>
+
+ <para></para>
+ </section>
</section>
</chapter>
More information about the jboss-cvs-commits
mailing list