Home > Articles > Programming > Java

  • Print
  • + Share This
This chapter is from the book

3.4 PDF, Email, and Rich Text

So far, we have discussed the JSF enhancements provided by Facelets and the jboss-seam-ui.jar library. Those are important usability and integration features required by almost all Seam web applications. In this section, we discuss several additional UI features Seam provides. To use those features, you need to bundle more library JAR files in your application and provide extra configuration as described below. You can choose and mix the UI feature sets you want in the application while keeping its footprint and configuration complexity to a minimum.

3.4.1 Generate PDF Reports

The Facelets XHTML files generate HTML web pages by default. However, a real-world web application sometimes needs to generate PDF output for printer-ready documents such as reports, legal documents, tickets, receipts, etc. The Seam PDF library leverages the open source iText toolkit to generate PDF documents. Here is a simple Facelets file, hello.xhtml, which renders a PDF document:

<p:document xmlns:p="http://jboss.com/products/seam/pdf"
            title="Hello">
  <p:chapter number="1">
    <p:title>
      <p:paragraph>Hello</p:paragraph>
    </p:title>
    <p:paragraph>Hello #{user.name}!</p:paragraph>

    <p:paragraph>The time now is

      <p:text value="#{manager.nowDate}">
        <f:convertDateTime style="date" format="short"/>
      </p:text>

    </p:paragraph>
  </p:chapter>

  <p:chapter number="2">
    <p:title>
      <p:paragraph>Goodbye</p:paragraph>
    </p:title>
    <p:paragraph>Goodbye #{user.name}.</p:paragraph>
  </p:chapter>
</p:document>

While the hello.xhtml file has the xhtml suffix, it is really an XML file with Seam PDF UI tags. When the user loads the hello.seam URL, Seam generates the PDF document and redirects the browser to hello.pdf. The browser then displays the hello.pdf file in its PDF reader plugin or prompts the user to save the PDF file. By passing the pageSize HTTP parameter to the URL, you can specify the page size of the generated PDF document. For instance, the hello.seam?pageSize=LETTER URL produces a letter-sized hello.pdf document. Valid pageSize options also include A4, LEGAL, and others.

You can use any JSF EL expressions in the xhtml page; these EL expressions are resolved on the fly when the PDF document is rendered, just as are EL expressions on web pages. You can also use JSF converters to control text formatting, the <f:facet> tag to control table formatting, or the Facelets <ui:repeat> tag to render a list or table from dynamic data. See the Seam Reference Documentation (http://seamframework.org/Documentation) for more details on the tags.

To use the Seam PDF tags, you need to include the jboss-seam-pdf.jar and itext.jar files in the WEB-INF/lib directory of your WAR application archive.

mywebapp.ear
|+ app.war
   |+ web pages
   |+ WEB-INF
      |+ web.xml
      |+ faces-config.xml
      |+ other config files
      |+ lib
         |+ jsf-facelets.jar
         |+ jboss-seam-ui.jar
         |+ jboss-seam-debug.jar

         |+ jboss-seam-pdf.jar
  
         |+ itext.jar
|+ app.jar
|+ lib
   |+ jboss-el.jar
   |+ jboss-seam.jar
|+ META-INF
   |+ application.xml
   |+ jboss-app.xml

Then, you need to configure the PDF-related Seam component in the components.xml file. The useExtensions property indicates that the hello.seam URL should redirect to the hello.pdf URL. If the useExtensions property is set to false, the redirection would not happen and the web application would serve PDF data directly to the browser from a .seam URL, which could cause usability problems in some browsers.

<components xmlns:pdf="http://jboss.com/products/seam/pdf"
            xmlns:core="http://jboss.com/products/seam/core">
  <pdf:documentStore useExtensions="true"/>

  ... ...

</components>

Finally, you need to set up servlet filters for the .pdf files. Those filters are only needed when you have the useExtensions property set to true in the components.xml configuration we've just seen.

<web-app ...>

  ... ...

  <filter>
    <filter-name>Seam Servlet Filter</filter-name>
    <filter-class>
      org.jboss.seam.servlet.SeamServletFilter
    </filter-class>
  </filter>

  <filter-mapping>
    <filter-name>Seam Servlet Filter</filter-name>
    <url-pattern>*.pdf</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>
      Document Store Servlet
    </servlet-name>
    <servlet-class>
      org.jboss.seam.pdf.DocumentStoreServlet
    </servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>
      Document Store Servlet
    </servlet-name>
    <url-pattern>*.pdf</url-pattern>
  </servlet-mapping>
</web-app>

The Seam PDF library supports generating digitally signed PDF documents. The public key configuration, however, is beyond the scope of this book. See the Seam Reference Documentation and iText documentation for more details.

3.4.2 Template-Based Email

Sending email from your web application is not hard—but it can be a messy task. The standard JavaMail API requires developers to embed the email messages as literal strings inside Java code. That makes it very difficult to write rich email (i.e., HTML email with elaborate text formatting and embedded images), and makes it nearly impossible for non-developers to design and compose the email messages. The lack of design and branding in email messages is a major weakness in many web applications.

In Seam, we provide a template-based approach to handling email. A business person or a page designer writes the email as a web page. Here is an example email template page hello.xhtml:

<m:message xmlns="http://www.w3.org/1999/xhtml"
           xmlns:m="http://jboss.com/products/seam/mail"
           xmlns:h="http://java.sun.com/jsf/html">
  <m:from name="Michael Yuan" address="myuan@redhat.com"/>
  <m:to name="#{person.firstname} #{person.lastname}">
    #{person.address}
  </m:to>
  <m:subject>Try out Seam!</m:subject>
  <m:body>
  <p>Dear #{person.firstname},</p>
  <p>You can try out Seam by visiting
  <a href="http://labs.jboss.com/jbossseam">
    http://labs.jboss.com/jbossseam
    </a>.</p>
  <p>Regards,</p>
  <p>Michael</p>
  </m:body>
</m:message>

When a web user needs to send out the hello.xhtml message, he or she clicks on a button or a link to invoke a Seam backing bean method to render the hello.xhtml page. Below is an example method to send the hello.xhtml email. The message recipient is dynamically determined at runtime via the #{person.address} EL expression. Similarly, you can dynamically determine the sender address or any content in the message via EL expressions.

public class ManagerAction implements Manager {

  @In(create=true)
  private Renderer renderer;

  public void send() {
    try {
      renderer.render("/hello.xhtml");
      facesMessages.add("Email sent successfully");
    } catch (Exception e) {
      facesMessages.add("Email sending failed: " + e.getMessage());
    }
  }
}

If a message has multiple recipients, you can insert multiple <m:to> tags using the Facelets <ui:repeat> tag. You can also use the Facelets <ui:insert> tag to compose messages from a template.

To use the Seam email support tags, you need to bundle the jboss-seam-mail.jar file in the WEB-INF/lib directory of your WAR archive.

mywebapp.ear
|+ app.war
   |+ web pages
   |+ WEB-INF
      |+ web.xml
      |+ faces-config.xml
      |+ other config files
      |+ lib
         |+ jsf-facelets.jar
         |+ jboss-seam-ui.jar
         |+ jboss-seam-debug.jar

         |+ jboss-seam-mail.jar
|+ app.jar
|+ lib
   |+ jboss-el.jar
   |+ jboss-seam.jar
|+ META-INF
   |+ application.xml
   |+ jboss-app.xml

Then, you need to configure an SMTP server to actually send the email. That is done via the Seam mailSession component in components.xml. You can specify the host name, port number, and login credentials for the SMTP server. Here is an example SMTP configuration:

<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core="http://jboss.com/products/seam/core"
            xmlns:mail="http://jboss.com/products/seam/mail">

  <mail:mailSession host="smtp.example.com"
                    port="25"
                    username="myuan"
                    password="mypass" />
  ... ...

</components>

3.4.3 Display Rich Text

A community-oriented web application often needs to display user-contributed content (e.g., forum posts, comments etc.). Here, a big issue is how to allow rich text formatting in user-contributed content. Allowing the web user to submit arbitrary HTML-formatted text is out of the question, as raw HTML is insecure and prone to various cross-site scripting attacks.

One solution is to use a WYSIWYG rich text editor widget to capture user input. The widget transforms its content to sanitized HTML when the form is submitted to the server. Refer to Section 21.3.2 for more on this subject.

Another solution, which we cover here, is to provide the web users with a small set of non-HTML markup tags they can use to format the content. When the application displays the content, it automatically converts the markup to HTML tags. A popular non-HTML text markup language is Wikitext which is widely used on wiki community sites (e.g., the http://wikipedia.org site). The Seam <s:formattedText> UI component converts Wikitext to HTML formatted text. For instance, suppose that the #{user.post} Seam component contains the following text:

It's easy to make *bold text*, /italic text/,
|monospace|, -deleted text-, super^scripts^,
or _underlines_.

The UI element <s:formattedText value="#{user.post}"/> would produce the following HTML text on the web page:

<p>
It's easy to make <b>bold text</b>,
<i>italic text</i>, <tt>monospace</tt>
<del>deleted text</del>, super<sup>scripts</sup>,
or <u>underlines</u>.
</p>

Support for the <s:formattedText> tag is already included in the jboss-seam-ui.jar file. But it depends on the ANTLR (ANother Tool for Language Recognition, see www.antlr.org) parser to process the Wikitext grammar. In order to use the <s:formattedText> tag, you need to bundle the ANTLR JAR in your WAR archive:

mywebapp.ear
|+ app.war
   |+ web pages
   |+ WEB-INF
      |+ web.xml
      |+ faces-config.xml
      |+ other config files
      |+ lib
         |+ jsf-facelets.jar
         |+ jboss-seam-ui.jar
         |+ jboss-seam-debug.jar

         |+ antlr-x.y.z.jar
|+ app.jar
|+ lib
   |+ jboss-el.jar
   |+ jboss-seam.jar
|+ META-INF
   |+ application.xml
   |+ jboss-app.xml

With the ANTLR parser, Seam can potentially support other markup languages beyond the Wikitext. For instance, it might one day support sanitized HTML (i.e., HTML text with all potential security loopholes removed), BBCode (widely used in online forms), and others. Refer to Seam documentation for the latest updates on this subject.

  • + Share This
  • 🔖 Save To Your Account