<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JT Dev &#187; seam</title>
	<atom:link href="http://www.jtict.com/blog/tag/seam/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jtict.com/blog</link>
	<description>About programming stuff</description>
	<lastBuildDate>Mon, 13 Jun 2011 16:17:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Seam-gen and default ROOT context</title>
		<link>http://www.jtict.com/blog/seam-gen-context-root/</link>
		<comments>http://www.jtict.com/blog/seam-gen-context-root/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 14:04:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web programming]]></category>
		<category><![CDATA[seam]]></category>

		<guid isPermaLink="false">http://www.jtict.com/blog/?p=10</guid>
		<description><![CDATA[If you are using seam-gen to deploy webapps as war-files to a webserver (for example JBoss AS), the root url of your webapp will be something like http://example.com/myproject/. (Where &#8220;myproject&#8221; is the name that you gave to your webapps when setting it up using seam-gen.) If you want your webapp to be assigned to the root <a href='http://www.jtict.com/blog/seam-gen-context-root/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>If you are using seam-gen to deploy webapps as <strong>war</strong>-files to a webserver (for example JBoss AS), the root url of your webapp will be something like <a href="http://example.com/myproject/">http://example.com/myproject/</a>. (Where &#8220;myproject&#8221; is the name that you gave to your webapps when setting it up using seam-gen.) If you want your webapp to be assigned to the root (<a href="http://example.com/">http://example.com/</a>) (also known as the <strong>default ROOT context</strong>), then read on.</p>
<p>To change the root context, I perform the following steps. Note, there might be a better way, but this one works for me. If you&#8217;re using ejb instead of war, then you probably have to do some additional steps.</p>
<p>Tested using jboss-4.2.2.GA and jboss-seam-2.0.2.SP1.</p>
<p>1) After creating the project, open build.xml. Change</p>
<pre>&lt;property name="war.dir" value="exploded-archives/${project.name}.war" /&gt;</pre>
<p>to</p>
<pre>&lt;property name="war.dir" value="exploded-archives/ROOT.war" /&gt;</pre>
<p>and change</p>
<pre>&lt;property name="war.deploy.dir" value="${deploy.dir}/${project.name}.war" /&gt;</pre>
<p>to</p>
<pre>&lt;property name="war.deploy.dir" value="${deploy.dir}/ROOT.war" /&gt;</pre>
<p>2) Go to the following directory: {your.jboss.home.dir}\server\default\deploy\jboss-web.deployer. And rename ROOT.war to something else. The JBoss manager might then not be available anymore.</p>
<p>3) Now run an explode, and your webapp will be at the ROOT context.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jtict.com/blog/seam-gen-context-root/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSF doesn&#8217;t validate empty forms</title>
		<link>http://www.jtict.com/blog/jsf-empty-form-validation/</link>
		<comments>http://www.jtict.com/blog/jsf-empty-form-validation/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 19:38:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web programming]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[seam]]></category>

		<guid isPermaLink="false">http://www.jtict.com/blog/?p=7</guid>
		<description><![CDATA[Error: Caused by org.hibernate.validator.InvalidStateException with message: &#8220;validation failed for: MyHibernateEntity&#8221; Are you getting this error while trying to validate a form with empty fields using Seam, JSF and Hibernate? Then read on. Seam allows you to define validation conditions on a single place: on the Hibernate / JPA entities. And then use this condition in <a href='http://www.jtict.com/blog/jsf-empty-form-validation/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Error:</p>
<blockquote><p>Caused by org.hibernate.validator.InvalidStateException with message: &#8220;validation failed for: MyHibernateEntity&#8221;</p></blockquote>
<p>Are you getting this error while trying to validate a form with empty fields using Seam, JSF and Hibernate? Then read on.</p>
<p>Seam allows you to define validation conditions on a single place: on the Hibernate / JPA entities. And then use this condition in the view without duplicating them.<br />
Sounds nice, but when you try it in practice, you can easily run into the &#8220;<em>validation failed</em>&#8221; error above.</p>
<p>The problem is caused by JSF. It sounds idiot (and it is), but JSF validators aren&#8217;t invoked on empty fields. So the following code already causes the error when submitting an empty comment field</p>
<pre class="brush: xml; title: ;">&lt;h:inputTextarea id=&quot;comment&quot; value=&quot;#{user.comment}&quot; cols=&quot;10&quot; rows=&quot;3&quot;&gt;
   &lt;s:validate/&gt;
&lt;/h:inputTextarea&gt;
&lt;h:message for=&quot;comment&quot; /&gt;</pre>
<pre class="brush: java; title: ;">
@Entity
public class User {
  // ....

  @NotNull
  private String comment;

  // ....
}</pre>
<p>Fortunately a solution is simple, set the <em>required</em> attribute of the input field element to <em>true</em>. Like this:</p>
<pre class="brush: xml; title: ;">&lt;h:inputTextarea id=&quot;comment&quot; value=&quot;#{user.comment}&quot; cols=&quot;10&quot; rows=&quot;3&quot; required=&quot;true&quot;&gt;</pre>
<p>More info:<br />
<a href="http://jamiemcilroy.wordpress.com/2006/10/10/not-quite-what-i-expectedjsf-validation/">http://jamiemcilroy.wordpress.com/2006/10/10/not-quite-what-i-expectedjsf-validation/</a><br />
<a href="http://forum.java.sun.com/thread.jspa?threadID=5055877">http://forum.java.sun.com/thread.jspa?threadID=5055877</a><br />
<a href="http://www.jboss.com/index.html?module=bb&#038;op=viewtopic&#038;t=127793">http://www.jboss.com/index.html?module=bb&#038;op=viewtopic&#038;t=127793</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jtict.com/blog/jsf-empty-form-validation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Seam and URL rewriting with parameters and forms</title>
		<link>http://www.jtict.com/blog/seam-form-url-rewriting/</link>
		<comments>http://www.jtict.com/blog/seam-form-url-rewriting/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 12:27:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web programming]]></category>
		<category><![CDATA[jsf]]></category>
		<category><![CDATA[seam]]></category>
		<category><![CDATA[url rewriting]]></category>

		<guid isPermaLink="false">http://www.jtict.com/blog/?p=4</guid>
		<description><![CDATA[Making pretty bookmarkable RESTful URLs in JSF is hard. Fortunately the Seam framework solves this problem by supporting HTTP parameters, advanced page navigation, and can use the help of UrlRewriteFilter. But making bookmarkable parameter URLs in combination with a POST form can still be a bit tricky. This blog post shows an example how to solve this <a href='http://www.jtict.com/blog/seam-form-url-rewriting/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Making pretty bookmarkable RESTful URLs in JSF is hard. Fortunately the Seam framework solves this problem by supporting HTTP parameters, advanced page navigation, and can use the help of <a title="UrlRewriteFilter" href="http://tuckey.org/urlrewrite/" target="_blank">UrlRewriteFilter</a>. But making bookmarkable parameter URLs in combination with a POST form can still be a bit tricky. This blog post shows an example how to solve this problem.</p>
<p>Note: The code snippets used are only fragments. I also assume that UrlRewriteFilter is already installed etc. Seam-gen also contains UrlRewriteFilter, but you might have to add it to the deployment and configure web.xml. Use <span style="text-decoration: underline;">/rewrite-status</span> to see if it&#8217;s working.</p>
<h3>Example</h3>
<p>We have a website that shows products of a given catagory. In our case, we use the catagory &#8216;audio&#8217;. We want bookmarkable URLs, like <span style="text-decoration: underline;">http://example.com/products.jsf?catagory=audio</span> instead of <span style="text-decoration: underline;">http://example.com/products.jsf</span>. And we want pretty URLs that hide technology implementation and parameter names, so in the end we want only URLs like <span style="text-decoration: underline;">http://example.com/products/audio</span>.</p>
<p>Also we want a HTML POST form on the page that allows us to add products to a catagory (&#8216;audio&#8217; in this case). After submitting this form, we want the URLs to still be pretty, so also here we only want URLs like <span style="text-decoration: underline;">/products/audio</span>.</p>
<h4>Making bookmarkable URLs for first HTTP requests</h4>
<p>A URL is bookmarkable when the URL by itself contains all parameters needed to retrieve the page, like<br />
<span style="text-decoration: underline;">/products.jsf?catagory=audio</span>.</p>
<p>JSF is unable to do this because it cannot handle URL parameters. JSF depends on a HTTP POST (the postback request) to retrieve the page, so the user first has to click a button, after which JSF will show the page with audio products.<br />
The Seam framework solves this problem by handling URL parameters, so we use Seam. (This is just one reason to use Seam around JSF. There are many more.)</p>
<p>Because we are using Seam around JSF, the URL becomes <span style="text-decoration: underline;">/products.<strong>seam</strong>?catagory=audio</span>.<br />
To make these parameters, we add the following to pages.xml:</p>
<pre class="brush: xml; title: ;">&lt;page view-id=&quot;/products.seam&quot;&gt;
    &lt;param name=&quot;catagory&quot; value=&quot;#{productsManager.catagory}&quot; /&gt;
&lt;/page&gt;</pre>
<p>In the code above, productsManager is a backingbean and catagory is a property that will be set to &#8216;audio&#8217; automatically when the url <span style="text-decoration: underline;">/products.<strong>seam</strong>?catagory=audio</span> is requested.</p>
<h4>Making pretty URLs for first HTTP requests</h4>
<p>After enabling parameters for our URLs, we want them to be pretty. We want <span style="text-decoration: underline;">/products/audio</span> instead of <span style="text-decoration: underline;">/products.seam?catagory=audio</span>.<br />
This is done by using UrlRewriteFilter. We add the following code to urlrewrite.xml:</p>
<pre class="brush: xml; title: ;">&lt;rule&gt;
    &lt;from&gt;/products/(.*)&lt;/from&gt;
    &lt;to&gt;/products.seam?catagory=$1&lt;/to&gt;
&lt;/rule&gt;</pre>
<h4>Bookmarkable URLs after a form submit</h4>
<p>By default, with the code used above, when we use the form at <span style="text-decoration: underline;">/products/audio</span> to add a product the catagory &#8216;audio&#8217;, the form will send us to the URL <span style="text-decoration: underline;">/products.seam</span> without parameters, which is not bookmarkable! To make it bookmarkable, change the code that we have added to pages.xml to:</p>
<pre class="brush: xml; title: ;">&lt;page view-id=&quot;/products.seam&quot;&gt;
    &lt;param name=&quot;catagory&quot; value=&quot;#{productsManager.catagory}&quot; /&gt;
    &lt;navigation from-action=&quot;#{productsManager.addProduct}&quot;&gt;
        &lt;redirect view-id=&quot;/products.seam&quot;/&gt;
    &lt;/navigation&gt;
&lt;/page&gt;</pre>
<p>Where addProduct is an action method bound to the h:commandButton of the form.</p>
<p>When the form is now submitted, the user will be redirected to <span style="text-decoration: underline;">/products.seam?catagory=audio&amp;cid=1</span>, which is bookmarkable.<br />
Notice that a cid parameter is added by Seam, which Seam uses to track conversations. (To remove it, read further.)</p>
<h4>Pretty URLs after a form submit</h4>
<p>After submitting the form, we have <span style="text-decoration: underline;">/products.seam?catagory=audio&amp;cid=1</span>. To make it pretty again (<span style="text-decoration: underline;">/products/audio</span>), we use outbound urlrewriting. Add the following code to urlrewrite.xml:</p>
<pre class="brush: xml; title: ;">&lt;outbound-rule&gt;
    &lt;from&gt;^/products.seam\?catagory=(.*)&lt;/from&gt;
    &lt;to&gt;/products/$1&lt;/to&gt;
&lt;/outbound-rule&gt;</pre>
<p>After a form submit, the URL will now be: <span style="text-decoration: underline;">/products/audio?cid=1</span>. The URL is now prettier, but not completely, we still have the cid parameter. If you don&#8217;t need to maintain conversations, the cid parameter can be removed with by changing the outbound rule to:</p>
<pre class="brush: xml; title: ;">&lt;outbound-rule&gt;
    &lt;from&gt;^/products.seam\?catagory=(\w*)&amp;amp;cid=\d*&lt;/from&gt;
    &lt;to&gt;/products/$1&lt;/to&gt;
&lt;/outbound-rule&gt;</pre>
<h4>Disadvantage of the solution</h4>
<p>1) Extra delay:<br />
If you would make a HTML form without JSF, you could immediately specify the action URL (attribute of the HTML form), so you could immediately specify to URL you want to send form data to, without all the rewriting. When the browser then submits the POST data (immediately to the pretty bookmarkable URL), the server will immediately return the page with results. So only one HTTP request/response is needed. But with Seam/JSF two request/reponses are needed if you want pretty bookmarkable URLs, which is an extra unwanted delay, just to get the job done in these frameworks.</p>
<p>The following steps happen in the background in our example:</p>
<ol>
<li>The user enters <span style="text-decoration: underline;">/products/audio</span> in the browser.</li>
<li>The server responds with the page containing a HTML form like: <code>&lt;form method="post" action="/products.seam"&gt;</code>. Notice that it refers to <span style="text-decoration: underline;">/products.seam</span> without parameters.</li>
<li>The user enters form data and submits it. The browser will generate a HTTP POST request to <span style="text-decoration: underline;">/products.seam</span>.</li>
<li>The server processes the form data using productsManager.addProduct(), and responds with a HTTP REDIRECT to <span style="text-decoration: underline;">/products/audio</span>. (A HTTP redirect doesn&#8217;t contain a page.)</li>
<li>The browser receives the redirect, and immediately requests for <span style="text-decoration: underline;">/products/audio</span>, using a HTTP GET.</li>
<li>The server receives the HTTP GET and gives a HTTP OK reponse containing the page the user already was on.</li>
</ol>
<p>Without the Seam/JSF framework, these steps would be shorter and faster, saving an extra client-server-client roundtrip. Because you could then specify the URL to submit to in the HTML form, and thus won&#8217;t need the HTTP redirect. But these extra step can also be used as an advantage; it allow serversided navigation rules. But it would be nice if both options were possible, allowing the developer to choose.</p>
<p>2) SEO:<br />
Google recently announced that they are going to <a href="http://googlewebmastercentral.blogspot.com/2008/04/crawling-through-html-forms.html">crawl through HTML forms</a> to find URLs.<br />
Because the HTML form is using <span style="text-decoration: underline;">/products.seam</span> in the HTML code instead of the pretty bookmarkable url, Google might index URLs you don&#8217;t want to be indexed. (This can be stopped using robots.txt, but other crawler maybe might not use that file.) </p>
<p>3) Doesn&#8217;t work for validation:<br />
When a form is not validated because the form fields are not passing the specified field conditions, the JSF life cycle will end and thus skip the <em>Invoke Application</em> phase, and thus the navigation rules above will not be executed. I don&#8217;t know if there&#8217;s an easy solution for this.</p>
<h4>Notes:</h4>
<p>1)<br />
When using UrlRewriteFilter, make sure you encode XML entities, so a <em><span style="color: #3366ff;">&amp;</span></em> becomes <em><span style="color: #3366ff;">&amp;</span></em> in urls that have a querystring.</p>
<p>2)<br />
The querystring of an URL is everything behind the questionmark, like <span style="text-decoration: underline;">/products.seam?catagory=audio&amp;login=true</span>. In UrlRewriteFilter, like in mod_rewrite, querystrings are handled separatly from the URL. In UrlRewriteFilter you&#8217;ll have to use the &lt;condition&gt; element when using a &lt;rule&gt; element for an URL containing a querystring. For example:</p>
<pre class="brush: xml; title: ;">&lt;rule&gt;
&lt;condition type=&quot;query-string&quot;&gt;catagory=(\w*)&amp;amp;login=true&lt;/condition&gt;
&lt;from&gt;/products.seam&lt;/from&gt;
&lt;to type=&quot;redirect&quot;&gt;/products/%1&lt;/to&gt;
&lt;/rule&gt;</pre>
<p>Also note that you&#8217;ll have to use %1 instead of $1 when using conditions.<br />
You don&#8217;t have to use the &lt;condition&gt; element when using querystrings with the &lt;outbound-rule&gt; element.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jtict.com/blog/seam-form-url-rewriting/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

