<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-17500411</id><updated>2012-02-04T15:50:08.387-05:00</updated><title type='text'>Fenqiang's J2EE Share Brain Blog</title><subtitle type='html'>We are Web2.0 application consultant/developer group based on Ottawa. Currently our interesting parts are &lt;b&gt;Ajax(ExtJS), Grail(Spring, hibernate), Adobe AIR&lt;/b&gt; etc. And hopefully we can keep up with the latest 'interesting' stuff.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>66</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-17500411.post-3624444425350862516</id><published>2010-05-13T16:23:00.009-04:00</published><updated>2010-05-13T16:34:28.480-04:00</updated><title type='text'>Grails Acegi change locale after user login</title><content type='html'>In Acegi and Grails application, I would like to set the locale to the users preferred language after they log in. Here comes some steps I made:&lt;br /&gt;&lt;br /&gt;In config file: conf/security.groovy. Add the following line:&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;security {&lt;br /&gt;    active = true&lt;br /&gt;    loginUserDomainClass = "User"&lt;br /&gt;    authorityDomainClass = "Role"&lt;br /&gt;    requestMapClass = "Requestmap"&lt;br /&gt;    security.defaultRole="ROLE_USER"&lt;br /&gt;&lt;br /&gt;    useSecurityEventListener = true&lt;br /&gt;    onInteractiveAuthenticationSuccessEvent = { e, appCtx -&gt;&lt;br /&gt;        // handle AuthenticationSuccessEvent&lt;br /&gt;        def autservice = appCtx.authenticateService&lt;br /&gt;        def domain = autservice.userDomain()&lt;br /&gt;        def request = org.codehaus.groovy.grails.plugins.springsecurity.SecurityRequestHolder.getRequest()&lt;br /&gt;        def session = request.getSession(false)&lt;br /&gt;&lt;br /&gt;        // ok set session information for lang file - tested and ok&lt;br /&gt;        if (domain) {&lt;br /&gt;            def person = User.get(domain.id)&lt;br /&gt;            def userSetting = UserSetting.findByAuthor(person)&lt;br /&gt;            def lang = 'en'            &lt;br /&gt;            if (session &amp;&amp; userSetting &amp;&amp; userSetting.language != null) {&lt;br /&gt;                session.lang = userSetting.language&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And I have a table called userSetting which hold the user setting information, you need change it as your table information.&lt;br /&gt;&lt;br /&gt;Ok, now we need call this function in any controller you want to change locale, maybe you'd better create a new general controller which will be extended by any controller:&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;    // this is for locale change ...&lt;br /&gt;    def localeChangeCheck = {&lt;br /&gt;        def locale;&lt;br /&gt;        if (session.lang != null) {&lt;br /&gt;            locale = new Locale(session.lang)&lt;br /&gt;            RCU.getLocaleResolver(request).setLocale(request,response,locale)&lt;br /&gt;        }&lt;br /&gt;        if (locale == null) {&lt;br /&gt;            locale = RCU.getLocale(request)&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now you are on fly. To see running example, you can try @&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.feyasoft.com"&gt;www.feyasoft.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ok, do not forget to change properties file under your i18n folder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-3624444425350862516?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/3624444425350862516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=3624444425350862516' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3624444425350862516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3624444425350862516'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2010/05/grails-acegi-change-locale-after-login.html' title='Grails Acegi change locale after user login'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-3643249243694655574</id><published>2010-04-22T10:06:00.014-04:00</published><updated>2010-04-22T10:25:48.646-04:00</updated><title type='text'>Quick add multiple language to extjs + grails application</title><content type='html'>Recently we quick added multiple language to our application. To see demo, you can login @ www.feyasoft.com/main&lt;br /&gt;&lt;br /&gt;1: In database, we create a table which hold on the setting for language. &lt;br /&gt;&lt;br /&gt;2: In grail MainController file, add the following code:&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;/**&lt;br /&gt; * Copyright (c) 2005 - 2010 FeyaSoft Inc. All Rights Reserved.&lt;br /&gt; */&lt;br /&gt;import grails.converters.*&lt;br /&gt;&lt;br /&gt;class MainController extends GeneralController {&lt;br /&gt;&lt;br /&gt;    def index = {&lt;br /&gt;        // get login user id&lt;br /&gt;        User loginUser = getLoginUser()&lt;br /&gt;        if (loginUser == null) {&lt;br /&gt;            def json = [failure : "true", errorInfo : "Please login before post"]&lt;br /&gt;            render json as JSON&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        def item = UserSetting.findByAuthor(loginUser);&lt;br /&gt;        def lang = 'en'&lt;br /&gt;        if (item) lang = item.language;&lt;br /&gt;&lt;br /&gt;        render(view: 'main', model: [lang: lang])&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3: In main.gsp file, the following code are added, really simple:&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;    &lt;~g:javascript library="extjs/src/locale/ext-lang-${lang}" /~&gt;&lt;br /&gt;    &lt;~g:javascript library="feyaSoft/lang/${lang}" /~&gt;&lt;br /&gt;&lt;/pre&gt;And you need create the related lang file now. For example, we have this lang file under my folder: web-app\js\feyaSoft\lang\en.js&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;/**&lt;br /&gt; * FeyaSoft Online MyActivity&lt;br /&gt; * Copyright(c) 2006-2010, FeyaSoft Inc. All right reserved.&lt;br /&gt; * info@feyasoft.com&lt;br /&gt; */&lt;br /&gt;Ext.ns("feyaSoft");&lt;br /&gt;&lt;br /&gt;feyaSoft.lang = {&lt;br /&gt;&lt;br /&gt;    'common':{&lt;br /&gt;        'accessories': 'Accessories',&lt;br /&gt;        'align': 'Align',&lt;br /&gt;        'average': 'Average',&lt;br /&gt;        'brush': 'Brush',&lt;br /&gt;        'calculate': 'Calculate',&lt;br /&gt;....}&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4: Now you can use something like this in your JS file:&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;    feyaSoft.lang.common['average']    &lt;br /&gt;&lt;/pre&gt;And you are on fly now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-3643249243694655574?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/3643249243694655574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=3643249243694655574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3643249243694655574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3643249243694655574'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2010/04/quick-add-multiple-language-to-extjs.html' title='Quick add multiple language to extjs + grails application'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1794749845640818397</id><published>2010-04-18T13:13:00.008-04:00</published><updated>2010-04-22T10:20:25.005-04:00</updated><title type='text'>UTF-8 setting in Grails, mysql</title><content type='html'>Client UTF8----(A)----&gt; &lt;br /&gt;Server UTF8 ----(B)----&gt; &lt;br /&gt;Database UTF8 --- (C)----&gt; &lt;br /&gt;Table UTF8 ---(D)----&gt; Row UTF8 &lt;br /&gt;&lt;br /&gt;1: Client UTF8&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;    &lt;~meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2: Server UTF8&lt;br /&gt;&lt;br /&gt;In DataSource.groovy&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;url = "jdbc:mysql://localhost:3306/home?tcpKeepAlive=true&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF8"&lt;br /&gt;&lt;/pre&gt;This forces the driver to recognize that all text being sent to the driver is in UTF8. This should conform directly with Java's default UTF8 encoding without any translations occurring.&lt;br /&gt;&lt;br /&gt;3: Database UTF8&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;mysql&gt; show variables like '%character%';&lt;br /&gt;&lt;br /&gt;+--------------------------+----------------------------+&lt;br /&gt;| Variable_name            | Value                      |&lt;br /&gt;+--------------------------+----------------------------+&lt;br /&gt;| character_set_client     | utf8                       |&lt;br /&gt;| character_set_connection | utf8                       |&lt;br /&gt;| character_set_database   | utf8                       |&lt;br /&gt;| character_set_filesystem | binary                     |&lt;br /&gt;| character_set_results    | utf8                       |&lt;br /&gt;| character_set_server     | utf8                       |&lt;br /&gt;| character_set_system     | utf8                       |&lt;br /&gt;| character_sets_dir       | /usr/share/mysql/charsets/ |&lt;br /&gt;+--------------------------+----------------------------+&lt;br /&gt;8 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; set global character_set_server=utf8;&lt;br /&gt;&lt;/pre&gt;be sure to include the option in your my.cnf to ensure this option is persisted for a mysqld restart.&lt;br /&gt;&lt;br /&gt;/etc/mysql/my.conf - default-character-set = utf8&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1794749845640818397?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1794749845640818397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1794749845640818397' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1794749845640818397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1794749845640818397'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2010/04/utf-8-setting-in-grails-mysql.html' title='UTF-8 setting in Grails, mysql'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-2262479869707936131</id><published>2009-11-04T09:51:00.020-05:00</published><updated>2009-11-18T22:32:58.569-05:00</updated><title type='text'>Compress all output  and speed up download big js files</title><content type='html'>We can speed up downloads or web page access time with Apache mod_deflate module. The mod_deflate module provides the DEFLATE output filter that allows output from our server to be compressed before being sent to the client over the network.&lt;br /&gt;&lt;br /&gt;This decreases the amount of time and data transmitted over the network, resulting in faster web experience or downloads for visitors.&lt;br /&gt;&lt;br /&gt;Today we add the following config in our Apache server,&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And our js file size are huge reduced. The big one reduce as follow:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ext-all.js - from 609 k to 167 k&lt;/span&gt;&lt;br /&gt;home_mini.js - from 523 k to 101 k&lt;br /&gt;&lt;br /&gt;It makes our site load really quick and it is really help. You can try it at our site: &lt;a href="http://www.feyasoft.com"&gt;www.feyasoft.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Notice&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Enabling filters with AddOutputFilterByType  may fail partially or completely in some cases. For example, no filters are applied if the MIME-type could not be determined and falls back to the DefaultType setting, even if the DefaultType is the same.&lt;br /&gt;&lt;br /&gt;However, if you want to make sure, that the filters will be applied, assign the content type to a resource explicitly, for example with AddType or ForceType. Setting the content type within a (non-nph) CGI script is also safe.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ok, here are the details steps to create it:&lt;/span&gt;&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;# cd /usr/local/apache/config/&lt;br /&gt;# vi httpd.conf&lt;br /&gt;&lt;/pre&gt;Add the following line:&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;LoadModule deflate_module modules/mod_deflate.so&lt;br /&gt;&lt; Location / &gt;&lt;br /&gt;AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript application/javascript&lt;br /&gt;&lt; /Location &gt;&lt;br /&gt;&lt;/pre&gt;And now your need restart apache. If you did not have mod_deflate.so in your apache. Ok, now you need config and build one from apache source code. Here is a good link for your:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://streetsmartingit.blogspot.com/2007/11/how-to-compileinstall-moddeflate-into.html"&gt;http://streetsmartingit.blogspot.com/2007/11/how-to-compileinstall-moddeflate-into.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-2262479869707936131?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/2262479869707936131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=2262479869707936131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/2262479869707936131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/2262479869707936131'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/11/compress-all-output-and-make-js-file.html' title='Compress all output  and speed up download big js files'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-5860499559116392664</id><published>2009-10-29T14:58:00.003-04:00</published><updated>2009-10-29T15:08:54.163-04:00</updated><title type='text'>Online PowerPoint 1.0.0 Beta is released</title><content type='html'>After a while, online PowerPoint 1.0.0 Beta is released. And you can insert Text and Image in this version. And you can Drag and Drop the item. Finally you can review it.&lt;br /&gt;&lt;br /&gt;See detail demo @ &lt;a href="http://www.feyasoft.com/"&gt;www.feyasoft.com&lt;/a&gt; and login as: demo/demo&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_gx3yNfk96Ts/SunoHJ6HatI/AAAAAAAAASg/Y2FB_blipIE/s1600-h/ppt.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 191px;" src="http://3.bp.blogspot.com/_gx3yNfk96Ts/SunoHJ6HatI/AAAAAAAAASg/Y2FB_blipIE/s400/ppt.jpg" alt="" id="BLOGGER_PHOTO_ID_5398100837996653266" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-5860499559116392664?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/5860499559116392664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=5860499559116392664' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/5860499559116392664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/5860499559116392664'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/10/online-powerpoint-100-beta-is-released.html' title='Online PowerPoint 1.0.0 Beta is released'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_gx3yNfk96Ts/SunoHJ6HatI/AAAAAAAAASg/Y2FB_blipIE/s72-c/ppt.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-9012322085626725365</id><published>2009-08-04T09:05:00.003-04:00</published><updated>2009-08-04T09:16:38.006-04:00</updated><title type='text'>New version of Online Calendar release</title><content type='html'>We just push another version of our calendar online. Have a look if you shows interesting. It includes the following features:&lt;br /&gt;&lt;br /&gt;1: Day/Week/Month view&lt;br /&gt;2: DnD, Resize&lt;br /&gt;3: Support Multiple Calendar&lt;br /&gt;&lt;br /&gt;We will continue add more features in the near future.&lt;br /&gt;&lt;br /&gt;To see/use it, you can login: &lt;a href="http://www.feyasoft.com/"&gt;http://www.feyasoft.com&lt;/a&gt; and sign in as Guest or using: demo/demo&lt;br /&gt;&lt;br /&gt;Worked in FF, Chrome, IE.&lt;br /&gt;&lt;br /&gt;Month View:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_gx3yNfk96Ts/SngzfTspCQI/AAAAAAAAARI/HY3tl4pil90/s1600-h/calendar2.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 192px;" src="http://1.bp.blogspot.com/_gx3yNfk96Ts/SngzfTspCQI/AAAAAAAAARI/HY3tl4pil90/s400/calendar2.JPG" alt="" id="BLOGGER_PHOTO_ID_5366095568968419586" border="0" /&gt;&lt;/a&gt;Week view:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_gx3yNfk96Ts/Sngys570TsI/AAAAAAAAAQ4/hS2K5Kusoyk/s1600-h/calendar1.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 192px;" src="http://2.bp.blogspot.com/_gx3yNfk96Ts/Sngys570TsI/AAAAAAAAAQ4/hS2K5Kusoyk/s400/calendar1.JPG" alt="" id="BLOGGER_PHOTO_ID_5366094703059291842" border="0" /&gt;&lt;/a&gt;Day view:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_gx3yNfk96Ts/Sng0am-zL2I/AAAAAAAAARQ/byfZHJdo0gc/s1600-h/calendar0.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 194px;" src="http://4.bp.blogspot.com/_gx3yNfk96Ts/Sng0am-zL2I/AAAAAAAAARQ/byfZHJdo0gc/s400/calendar0.JPG" alt="" id="BLOGGER_PHOTO_ID_5366096587757137762" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-9012322085626725365?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/9012322085626725365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=9012322085626725365' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/9012322085626725365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/9012322085626725365'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/08/new-version-of-calendar-release.html' title='New version of Online Calendar release'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_gx3yNfk96Ts/SngzfTspCQI/AAAAAAAAARI/HY3tl4pil90/s72-c/calendar2.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-3250285389137477782</id><published>2009-05-09T13:20:00.010-04:00</published><updated>2009-05-09T14:03:43.877-04:00</updated><title type='text'>Extjs Code Style</title><content type='html'>Ext JS as a cross-browser JavaScript library, it is a really flexible language. Two peoples have different code style will generate totally different code. So it is really important for us to follow some standard - especial for the piece of code share between groups memeber. Here list some coding standard shared in our group:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_gx3yNfk96Ts/SgW9FvSVQUI/AAAAAAAAAQA/2k5JGmeZgL0/s1600-h/nameStructure.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 182px; height: 307px;" src="http://3.bp.blogspot.com/_gx3yNfk96Ts/SgW9FvSVQUI/AAAAAAAAAQA/2k5JGmeZgL0/s400/nameStructure.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5333877239980572994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1: File Structure and name&lt;br /&gt;&lt;br /&gt;Because UI level can be easily divided as center/south/east/west/noth panel. For each page - especial complex UI, we will always create a folder for each panel, such as: Center, South etc. And we always put the share files into the common folder.&lt;br /&gt;&lt;br /&gt;In a words, the file and folder should be easy to connect to the UI level - this will save lots of time for future maintainance.&lt;br /&gt;&lt;br /&gt;And namespace will be always used for each folder: Ext.ns('feyaSoft.calendar.dayView')&lt;br /&gt;&lt;br /&gt;2: Define the Class&lt;br /&gt;&lt;br /&gt;The target of extjs is to achieve complex UI. Obviously this includes part of logic to achieve UI behavior. To make code readable and reusable, we'd better separate the logic code and UI code. For example:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;Ext.ns("feyaSoft.main");&lt;br /&gt;&lt;br /&gt;feyaSoft.main.MainPanel = function(){&lt;br /&gt;....&lt;br /&gt;    // down tab panel&lt;br /&gt;    this.downTabPanel = new Ext.TabPanel({&lt;br /&gt;        region: 'south',&lt;br /&gt;        tabPosition: 'bottom',&lt;br /&gt;        activeTab: 0,&lt;br /&gt;        deferredRender: false,&lt;br /&gt;        layoutOnTabChange:true,&lt;br /&gt;        height: 190,&lt;br /&gt;        split:true,&lt;br /&gt;        resizeTabs:true,&lt;br /&gt;        tabWidth:200,&lt;br /&gt;        minTabWidth: 120,&lt;br /&gt;        plugins: new Ext.ux.TabCloseMenu(),&lt;br /&gt;&lt;br /&gt;        items:[{&lt;br /&gt;            title: 'Our Customer\'s Project',&lt;br /&gt;            iconCls: 'application',&lt;br /&gt;            closable: false,&lt;br /&gt;            autoScroll:true,&lt;br /&gt;            layout:'fit',&lt;br /&gt;            border: false,&lt;br /&gt;            cls:'feyasoft-images-view',  &lt;br /&gt;            items: [this.customerView]&lt;br /&gt;        }]&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    ....&lt;br /&gt;    feyaSoft.main.MainPanel.superclass.constructor.call(this, {&lt;br /&gt;        id: 'main_panel_page',&lt;br /&gt;        region: 'center',&lt;br /&gt;        layout: 'border',&lt;br /&gt;        border: false,&lt;br /&gt;        items: [this.upTabPanel, this.downTabPanel]&lt;br /&gt;    });&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Ext.extend(feyaSoft.main.MainPanel, Ext.Panel, {&lt;br /&gt;&lt;br /&gt;    // click customer image link&lt;br /&gt;    onCustomerClickFn : function(dv, index, node, e){&lt;br /&gt;        var rd = dv.store.getAt(index);&lt;br /&gt;        var data = rd.data;&lt;br /&gt;        var name = data['name'];&lt;br /&gt;&lt;br /&gt;        .....&lt;br /&gt;    },&lt;br /&gt;&lt;br /&gt;    ....&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this way, we can reuse this logic code as we like. And make code really easy to readable.&lt;br /&gt;&lt;br /&gt;3: Try to avoid use "id" in the panel/Grid/field etc. &lt;br /&gt;&lt;br /&gt;Because id is binded with dom field, there will be only one place work correct when we reuse the same piece of code with id in another place. &lt;br /&gt;&lt;br /&gt;In general, the purpose of id is to make get the reference of item in different place , like: &lt;span style="font-weight:bold;"&gt;Ext.getCmp('myId')&lt;/span&gt;. We can achieve this through pass reference or try use: &lt;span style="font-weight:bold;"&gt;this.ownerCt.reload()&lt;/span&gt; to get other item reference.&lt;br /&gt;&lt;br /&gt;Some suggestion:&lt;br /&gt;&lt;br /&gt;1: Try to reuse the code - if 2 place have similar code, make it comment and reuse&lt;br /&gt;2: Any function and method should not more than 100 line. Try to have sub function/method if it is too big.&lt;br /&gt;3: Try to use this: if (true == flag) instead of: if (flag == true)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-3250285389137477782?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/3250285389137477782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=3250285389137477782' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3250285389137477782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3250285389137477782'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/05/extjs-code-style.html' title='Extjs Code Style'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_gx3yNfk96Ts/SgW9FvSVQUI/AAAAAAAAAQA/2k5JGmeZgL0/s72-c/nameStructure.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-3321162201432130065</id><published>2009-04-28T21:21:00.016-04:00</published><updated>2009-04-29T10:15:58.626-04:00</updated><title type='text'>Upgrade to Grails 1.1</title><content type='html'>It is a pain process to update to Grails 1.1 (Your know I do not want to read long release notes)&lt;br /&gt;&lt;br /&gt;1: Acegi Security failed - need re-run plugin again. (Plugins are now stored in your USER_HOME directory. You will need to re-install your plugins or run: grails -Dgrails.project.plugins.dir =./plugins run-app)&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;    1.1: Install the Acegi plugin&lt;br /&gt;    &gt; grails install-plugin acegi&lt;br /&gt;&lt;br /&gt;    1.2: CREATE THE USER, ROLE, AND REQUESTMAP DOMAIN CLASSES&lt;br /&gt;    &gt; grails create-auth-domains User Role Requestmap&lt;br /&gt;&lt;br /&gt;    1.3: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR USER, ROLE, AND REQUESTMAP DOMAIN CLASSES&lt;br /&gt;    &gt; grails generate-manager&lt;br /&gt;&lt;br /&gt;    1.4: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR CAPTCHA, REGISTER, AND AN EMAILER SERVICE.&lt;br /&gt;    &gt; grails generate-registration&lt;br /&gt;&lt;br /&gt;    1.5: CREATE A CONTROLLER THAT WILL BE RESTRICTED BY ROLE&lt;br /&gt;    &gt; grails create-controller Secure&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2: Log4j config change - need read document careful.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;// log4j configuration&lt;br /&gt;log4j = {&lt;br /&gt;   appenders {&lt;br /&gt;       rollingFile name: 'homeLog',&lt;br /&gt;       fileName: '/var/log/home/full.log',&lt;br /&gt;       maxFileSize: 26214400,&lt;br /&gt;       maxBackupIndex: 10,&lt;br /&gt;       layout: pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss,SSS} %p %c{2} %m%n')&lt;br /&gt;   }&lt;br /&gt;   root {&lt;br /&gt;        error()&lt;br /&gt;        additivity = true&lt;br /&gt;   }&lt;br /&gt;   error  'org.codehaus.groovy.grails.web.servlet',  //  controllers&lt;br /&gt;          'org.codehaus.groovy.grails.web.pages' //  GSP&lt;br /&gt;&lt;br /&gt;   debug fileLog:'grails.app'&lt;br /&gt;   warn 'org.mortbay.log'&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3: Return Date format &lt;br /&gt;&lt;br /&gt;I do have date format issue after I upgrade to Grails 1.1. Ok, this is also new feature. Now grails is locale aware and will change the dateformat according to the user's locale. So you need add this to the config.goovy if you have any issue:&lt;br /&gt;&lt;br /&gt;grails.converters.json.date = 'javascript' // default or javascipt&lt;br /&gt;&lt;br /&gt;Or do something like this:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;import grails.converters.JSON;&lt;br /&gt;&lt;br /&gt;class BootStrap {&lt;br /&gt;&lt;br /&gt;     def init = { servletContext -&gt;&lt;br /&gt;         JSON.registerObjectMarshaller(Date) {&lt;br /&gt;            return it?.format("dd-MM-yyyy")&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;     def destroy = {&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4: Acegi issue - I run into the issue related Acegi for reDirect (sometimes) &lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;2009-04-29 10:06:27,875 [6216949@qtp0-1] ERROR errors.GrailsExceptionResolver  - java.lang.NullPointerException&lt;br /&gt;org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.NullPointerException&lt;br /&gt;        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:92)&lt;br /&gt;        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:234)&lt;br /&gt;        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1061)&lt;br /&gt;        at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:910)&lt;br /&gt;        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:892)&lt;br /&gt;        at groovy.lang.Closure.call(Closure.java:279)&lt;br /&gt;        at groovy.lang.Closure.call(Closure.java:274)&lt;br /&gt;        at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleAction(SimpleGrailsControllerHelper.java:363)&lt;br /&gt;        at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.executeAction(SimpleGrailsControllerHelper.java:243)&lt;br /&gt;        at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleURI(SimpleGrailsControllerHelper.java:203)&lt;br /&gt;        at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleURI(SimpleGrailsControllerHelper.java:138)&lt;br /&gt;        at org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController.handleRequest(SimpleGrailsController.java:88)&lt;br /&gt;        at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)&lt;br /&gt;        at org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet.doDispatch(GrailsDispatcherServlet.java:264)&lt;br /&gt;        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)&lt;br /&gt;        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)&lt;br /&gt;        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)&lt;br /&gt;        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To make sure it is this problem, temporary you can disable Acegi - set "active = false" in SecurityConfig.groovy.&lt;br /&gt;&lt;br /&gt;It looks like it's a filter - Grails implements these using one HandlerInterceptor (CompositeInterceptor) that iterates your configured filters:&lt;br /&gt;&lt;br /&gt;   at org.codehaus.groovy.grails.plugins.web.filters.CompositeInterceptor$-postHandle-closure1.doCall(CompositeInterceptor.groovy:48)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-3321162201432130065?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/3321162201432130065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=3321162201432130065' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3321162201432130065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3321162201432130065'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/04/update-to-grails-11.html' title='Upgrade to Grails 1.1'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1704774100627436897</id><published>2009-04-23T11:55:00.004-04:00</published><updated>2009-04-23T12:08:05.338-04:00</updated><title type='text'>Extjs based online Spreadsheet/Excel</title><content type='html'>After a while, extjs based online Spreadsheet/excel is released. You can view the demo @&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.feyasoft.com/"&gt;www.feyasoft.com&lt;/a&gt; -&gt; My Document -&gt; Right Click Mouse(New Spreadsheet)&lt;br /&gt;&lt;br /&gt;Currently it has the following features available:&lt;br /&gt;&lt;br /&gt;1: Increase columns by auto scroll down the mouse&lt;br /&gt;2: Cut/Copy/Paste&lt;br /&gt;3: Undo/Redo&lt;br /&gt;4: Add/edit/delete comments&lt;br /&gt;5: Save As&lt;br /&gt;&lt;br /&gt;There are several features on the list for process:&lt;br /&gt;&lt;br /&gt;1: Calculate (Summary, Average, Min, Max etc)&lt;br /&gt;2: Export as Excel/CSV&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1704774100627436897?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1704774100627436897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1704774100627436897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1704774100627436897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1704774100627436897'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/04/extjs-based-online-spreadsheetexcel.html' title='Extjs based online Spreadsheet/Excel'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-5869242005055243323</id><published>2009-03-19T23:13:00.005-04:00</published><updated>2009-03-26T16:27:05.499-04:00</updated><title type='text'>Build J2EE application with Extjs + Grails</title><content type='html'>&lt;span class="Apple-style-span" style=";font-family:Verdana;font-size:13;"  &gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;Running demo: &lt;a href="http://www.feyasoft.com"&gt;www.feyasoft.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For J2EE based web application, it is pretty popular to use light weight J2EE loose coupling concepts in business logic tier, and use Structs/Spring MVC/JSF as web framework in presentation tie. However, more and more customers require simple, quick, easy and affordable solution for their business - for example, how to quick build web-based J2EE application similar with Microsoft Outlook. We, J2EE application architecture/developer, need quick move forward to build Ajax-based rich interface J2EE application. Extjs + Grails are the right frameworks for build web application at the right time (2009 is the cut cost year everywhere).&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;Ext JS, a cross-browser JavaScript library for building Rich Internet Applications, owns an extensive library of super-high-quality widgets, an intuitive, extensible component model, and an easy-to-use API to create a full, rock-solid platform for JavaScript-based web apps. &lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;Grails is an open source web application framework which leverages the Groovy programming language (which is in turn based on the Java platform). It is intended to be a high-productivity framework by following the "coding by convention" paradigm, providing a stand-alone development environment and hiding much of the configuration detail from the developer. &lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;b id="ad.t"&gt;High Level Architecture Diagram&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;Figure 1 shows the basic high level architecture for Extjs/Grails-based RIA J2EE application. [1]&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_gx3yNfk96Ts/ScMKlCLCvyI/AAAAAAAAAPg/Dz0etjAe3XA/s1600-h/extjs_grails.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_gx3yNfk96Ts/ScMKlCLCvyI/AAAAAAAAAPg/Dz0etjAe3XA/s400/extjs_grails.jpg" alt="" id="BLOGGER_PHOTO_ID_5315103616581943074" border="0" /&gt;&lt;/a&gt;&lt;div&gt;&lt;span class="Apple-style-span" style=";font-family:Verdana;font-size:13;"  &gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;b id="ynhv"&gt;&lt;b&gt;Choice &lt;/b&gt;&lt;/b&gt;&lt;b id="bfi2"&gt;&lt;b&gt;widely adopted &lt;/b&gt;&lt;/b&gt;&lt;b id="nc8j"&gt;&lt;b&gt;3rd-party software&lt;/b&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;Open source solutions become widely adopted only if they're reliable and deliver value. Using those valuable open sources will buy us more time and better performance for the project. This is the reason we choice the following the 3rd-party software in this application. See table 1 for detail information [2]&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div id="ugqt" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;table id="e15o" class="zeroBorder"  style="border: 1px dotted gray; line-height: inherit;font-size:1em;" border="0" cellpadding="3" cellspacing="1" height="315" width="685"&gt;&lt;tbody id="x0gi"&gt;&lt;tr id="ecg5" style="text-align: left;"&gt;&lt;td id="q47f" style="border: 1px dotted gray;" width="35%"&gt;&lt;span style="font-weight: normal;"&gt;3rd-party Software&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;td id="i4g-" style="border: 1px dotted gray;" width="50%"&gt;&lt;span style="font-weight: normal;"&gt;Reason to choose&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="kdxa" style="text-align: left;"&gt;&lt;td id="gqez" style="border: 1px dotted gray;" width="35%"&gt;&lt;span style="font-weight: normal;"&gt;Extjs (www.extjs.com)&lt;/span&gt;&lt;/td&gt;&lt;td id="jdfj" style="border: 1px dotted gray;" width="50%"&gt;&lt;span style="font-weight: normal;"&gt;Extjs Ajax framework acts as a glue between browser and server, it enables us to create a rich and intuitive user interfaces for our application. Extjs provides Layout, Grid, Form, Tree, Menu etc which are widely used in our UI level. Furthermore, extjs provides great document/API.&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="fffo" style="text-align: left;"&gt;&lt;td id="da0b" style="border: 1px dotted gray;" width="35%"&gt;&lt;span style="font-weight: normal;"&gt;Grails (www.grails.org)&lt;/span&gt;&lt;/td&gt;&lt;td id="fpdb" style="border: 1px dotted gray;" width="50%"&gt;&lt;span style="font-weight: normal;"&gt;Open source web application framework help us to quick build server side logic, which based on spring framework.&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="ofu_" style="text-align: left;"&gt;&lt;td id="ds49" style="border: 1px dotted gray;" width="35%"&gt;&lt;span style="font-weight: normal;"&gt;Tomcat (tomcat.apache.org)&lt;/span&gt;&lt;/td&gt;&lt;td id="o01x" style="border: 1px dotted gray;" width="50%"&gt;&lt;span style="font-weight: normal;"&gt;Free application server.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="hh80" style="text-align: left;"&gt;&lt;td id="l.2j" style="border: 1px dotted gray;" width="35%"&gt;&lt;span style="font-weight: normal;"&gt;Apache (www.apache.org)&lt;/span&gt;&lt;/td&gt;&lt;td id="ho1a" style="border: 1px dotted gray;" width="50%"&gt;&lt;span style="font-weight: normal;"&gt;Load balance&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr id="fdv3" style="text-align: left;"&gt;&lt;td id="f1lr" style="border: 1px dotted gray;" width="35%"&gt;&lt;span style="font-weight: normal;"&gt;MySql (www.mysql.org)&lt;/span&gt;&lt;/td&gt;&lt;td id="qpx2" style="border: 1px dotted gray;" width="50%"&gt;&lt;span style="font-weight: normal;"&gt;Free database server.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;div id="zxm2" class="x-footer" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span style="font-weight: normal;"&gt;                                     Table 1  List of 3rd-party softwares&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;b&gt;Rich UI interface - extjs&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;By using extjs javascript framework, we can easy achieve nearly all of online ajax-based UI stuff.  Compare with DOJO (orthodoxy and stability), extjs has more UI widgets, pretty detail API document which will save lots of developer time. Except that you are fine for extjs commercial license.&lt;/div&gt;&lt;br /&gt;Extjs provides following widgets:&lt;br /&gt;&lt;br /&gt;&lt;ul id="oc86" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;li id="oc860" style="margin-top: 0px; margin-bottom: 0px;"&gt;Grid&lt;/li&gt;&lt;li id="oc861" style="margin-top: 0px; margin-bottom: 0px;"&gt;Layout&lt;/li&gt;&lt;li id="oc862" style="margin-top: 0px; margin-bottom: 0px;"&gt;Window&lt;/li&gt;&lt;li id="oc863" style="margin-top: 0px; margin-bottom: 0px;"&gt;Tree&lt;/li&gt;&lt;li id="oc864" style="margin-top: 0px; margin-bottom: 0px;"&gt;Form&lt;/li&gt;&lt;li id="oc865" style="margin-top: 0px; margin-bottom: 0px;"&gt;Menu&lt;/li&gt;&lt;li id="oc866" style="margin-top: 0px; margin-bottom: 0px;"&gt;and lots of active memeber with really useful plugin&lt;/li&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/ul&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span id="gplp"  style="font-size:100%;"&gt;&lt;span id="j4y5"  style="font-size:85%;"&gt;&lt;b id="k8df"&gt;Data Exchange&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;In tradition way, data exchange from backend to frontend are as following&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul id="l_cu" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;li id="ep-5" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span id="poix"  style="font-size:100%;"&gt;&lt;span id="poix0"  style="font-size:85%;"&gt;Object in database is transfered to DAO POJO object&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li id="vp6o" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span id="poix1"  style="font-size:100%;"&gt;&lt;span id="poix2"  style="font-size:85%;"&gt;DAO POJO object transfer data to MVC form object&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li id="hpa9" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span id="poix3"  style="font-size:100%;"&gt;&lt;span id="poix4"  style="font-size:85%;"&gt;Form object display results in page&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span id="poix5"  style="font-size:100%;"&gt;&lt;span id="poix6"  style="font-size:85%;"&gt;&lt;br /&gt;In Ajax-based application, data exchange can be something like this:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul id="d53t" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;li id="a9qz" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span id="poix7"  style="font-size:100%;"&gt;&lt;span id="poix8"  style="font-size:85%;"&gt;Object in database is transfered to DAO POJO object&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li id="x-21" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span id="poix9"  style="font-size:100%;"&gt;&lt;span id="poix10"  style="font-size:85%;"&gt;Render POJO object as JSON data to the UI level.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span id="poix11"  style="font-size:100%;"&gt;&lt;span id="poix12"  style="font-size:85%;"&gt;&lt;br /&gt;Grails provides great API to make data exchange between extjs and controller seamless.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;b id="ow8v"&gt;Grails Acegi plugin for Authentication and Autherization&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Grails based acegi security plugin allows developer to use the powerful of spring-based security, but it also gives&lt;span style="font-size:85%;"&gt; us the power to make config changes without having to deal with the complexity of using Spring Security directly.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;ul class="star" style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;li style="margin-top: 0px; margin-bottom: 0px;"&gt;Spring Security filters and Spring beans are registered in web.xml and the application context for you; customization is done in SecurityConfig.groovy&lt;/li&gt;&lt;li style="margin-top: 0px; margin-bottom: 0px;"&gt;Domain classes, Controllers, and CRUD GSPs for User and Role management and persistence&lt;/li&gt;&lt;li style="margin-top: 0px; margin-bottom: 0px;"&gt;Ajax-based login and Logout Controllers&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;span style="font-size:85%;"&gt;1: &lt;/span&gt;&lt;a id="vaw_0" href="http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html"&gt;&lt;i id="hyj_"&gt;Put JSF to work -- Build a real-world Web application with JavaServer Faces, the Spring Framework, and Hibernate&lt;/i&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;; Derek Yang Shen, JavaWorld.com;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;2: &lt;a href="http://www.extjs.com/" style="color: rgb(85, 26, 139);"&gt;http://www.extjs.com/&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;3: &lt;a href="http://www.grails.org/" style="color: rgb(85, 26, 139);"&gt;http://www.grails.org/&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;div style="margin-top: 0px; margin-bottom: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-5869242005055243323?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/5869242005055243323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=5869242005055243323' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/5869242005055243323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/5869242005055243323'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/03/build-j2ee-application-with-extjs.html' title='Build J2EE application with Extjs + Grails'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_gx3yNfk96Ts/ScMKlCLCvyI/AAAAAAAAAPg/Dz0etjAe3XA/s72-c/extjs_grails.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-8102846910385075917</id><published>2009-01-20T13:32:00.007-05:00</published><updated>2009-01-20T14:40:51.307-05:00</updated><title type='text'>Integrate Acegi(0.5.1) with Grails</title><content type='html'>Recently we try to integrate Acegi(0.5.1) into the grails. We follow the document:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://docs.codehaus.org/display/GRAILS/AcegiSecurity+Plugin+-+Basic+Tutorial"&gt;http://docs.codehaus.org/display/GRAILS/AcegiSecurity+Plugin+-+Basic+Tutorial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, this document is not updated with the latest Acegi. You need pay attention to several issue when you create role, requestmap. Otherwise, it will not work for your.&lt;br /&gt;&lt;br /&gt;When you create a role, the role name should include "ROLE" (case sensitive): i.e: ROLE_admin. And this is the quick steps to plugin acegi into your grails project:&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;1.1: Install the Acegi plugin&lt;br /&gt;&lt;br /&gt;&gt; grails install-plugin acegi&lt;br /&gt;&lt;br /&gt;1.2: CREATE THE USER, ROLE, AND REQUESTMAP DOMAIN CLASSES&lt;br /&gt;&lt;br /&gt;&gt; grails create-auth-domains User Role Requestmap&lt;br /&gt;&lt;br /&gt;1.3: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR USER, ROLE, AND REQUESTMAP DOMAIN CLASSES&lt;br /&gt;&lt;br /&gt;&gt; grails generate-manager&lt;br /&gt;&lt;br /&gt;1.4: OPTIONAL - CREATE CONTROLLERS AND GSPS FOR CAPTCHA, REGISTER, AND AN EMAILER SERVICE.&lt;br /&gt;&lt;br /&gt;&gt; grails generate-registration&lt;br /&gt;&lt;br /&gt;1.5: CREATE A CONTROLLER THAT WILL BE RESTRICTED BY ROLE&lt;br /&gt;&lt;br /&gt;&gt; grails create-controller Secure&lt;br /&gt;&lt;br /&gt;2.1: Create role&lt;br /&gt;&lt;br /&gt; http://localhost:8080/demo/role&lt;br /&gt; attention - And role name should be start with "ROLE" - i.e: ROLE_ADMIN, ROLE_USER&lt;br /&gt;&lt;br /&gt;2.2: Create user&lt;br /&gt;&lt;br /&gt; http://localhost:8080/demo/user&lt;br /&gt;&lt;br /&gt;2.3: create url request map&lt;br /&gt;&lt;br /&gt; http://localhost:8080/demo/requestmap&lt;br /&gt; please add the following url:&lt;br /&gt;&lt;br /&gt;    /user/** /role/** /adminpage/** /requestmap/**&lt;br /&gt;    ROLE_ADMIN&lt;br /&gt;&lt;br /&gt;2.4: login to admin page&lt;br /&gt;&lt;br /&gt; http://localhost:8080/demo/adminpage&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-8102846910385075917?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/8102846910385075917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=8102846910385075917' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/8102846910385075917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/8102846910385075917'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/01/integrate-acegi051-with-grails.html' title='Integrate Acegi(0.5.1) with Grails'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-2344079069529726293</id><published>2009-01-16T12:56:00.007-05:00</published><updated>2009-01-16T16:01:33.276-05:00</updated><title type='text'>Grails JasperReport plugin</title><content type='html'>Recently we start to play with Jasper plugin for Grails (version 1.0.4), and we did not have lucky to make it work - we use comment line "&lt;span style="color: rgb(102, 102, 204);font-family:courier new;" &gt;grails install-plugin jasper&lt;/span&gt;" (version 0.9).  We always end with this kind of error - my poor hair:&lt;br /&gt;&lt;pre&gt;at net.sf.jasperreports.engine.JRPropertiesMap.readObject(JRPropertiesMap.java:185)&lt;br /&gt;&lt;/pre&gt;After look around for a while, it seems the grails plugin jasper report library version is too old, and it somehow does not work under this version of Grails.&lt;br /&gt;&lt;br /&gt;After update to the latest version of jasperReport and iText&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;iText-2.1.4.jar&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;jasperreports-3.1.3.jar&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and put it into plugins/japser-0.9/lib, now I can generate the PDF file.&lt;br /&gt;&lt;br /&gt;And if you are using the latest iReport, you also need pay attention to the xml format of .jrxml. Please follow the example .jrxml to generated your .jasper file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-2344079069529726293?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/2344079069529726293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=2344079069529726293' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/2344079069529726293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/2344079069529726293'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2009/01/grails-jasperreport-plugin.html' title='Grails JasperReport plugin'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-168114802950216062</id><published>2008-12-30T23:37:00.014-05:00</published><updated>2008-12-31T10:26:50.263-05:00</updated><title type='text'>extjs + AIR installed in Vista SQLError 3122</title><content type='html'>I have built a small Extjs+AIR+SQLite project and installed it in the Vista system. I got the following error message when do create/Edit/delete.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;SQLError: 'Error #3122', details:'', operation:'execute'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span style="font-weight: normal;"&gt;This Extjs AIR application makes use of the local database (SQLite) and I was unable to update/create/delete a record; I was repeatedly getting error 3122 during the save operation. After looking up the error description I finally figured out it was because the database file was read-only. And the installed file was in the Vista application directory. &lt;/span&gt;&lt;/strong&gt;(Vista make this - it is not me, right? I think I already complain too much for IE - Vista is really good ??? / compare with IE - your know  I did not have enough sleep past 2 days)&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;AIR applications have privileges to write to any location on the user's hard drive; however, developers are encouraged to use the &lt;samp class="codeph"&gt;app-storage:/&lt;/samp&gt; path for local storage related to their application. Files written to &lt;samp class="codeph"&gt;app-storage:/&lt;/samp&gt; from an application are located in a standard location depending on the user's operating system:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;On Mac OS: the storage directory of an application is &lt;samp class="codeph"&gt;&lt;appdata&gt;/&lt;appid&gt;/Local Store/&lt;/appid&gt;&lt;/appdata&gt;&lt;/samp&gt;  where &lt;samp class="codeph"&gt;&lt;appdata&gt;&lt;/appdata&gt;&lt;/samp&gt; is the user's “preferences folder,” typically: &lt;samp class="codeph"&gt;/Users/&lt;user&gt;/Library/Preferences&lt;/user&gt;&lt;/samp&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt;&lt;p&gt;On Windows: the storage directory of an application is&lt;samp class="codeph"&gt; &lt;appdata&gt;\&lt;appid&gt;\Local Store\ &lt;/appid&gt;&lt;/appdata&gt;&lt;/samp&gt;where &lt;samp class="codeph"&gt;&lt;appdata&gt;&lt;/appdata&gt;&lt;/samp&gt; is the user's CSIDL_APPDATA “Special Folder,” typically:&lt;samp class="codeph"&gt; C:\Documents and Settings\&lt;user&gt;\Application Data&lt;/user&gt;&lt;/samp&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt;&lt;p&gt;On Linux: &lt;samp class="codeph"&gt;&lt;appdata&gt;/&lt;appid&gt;/Local Store/&lt;/appid&gt;&lt;/appdata&gt;&lt;/samp&gt;where &lt;samp class="codeph"&gt;&lt;appdata&gt;&lt;/appdata&gt;&lt;/samp&gt; is &lt;samp class="codeph"&gt;/home/&lt;user&gt;/.appdata&lt;/user&gt;&lt;/samp&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt; You can access the application storage directory via the &lt;samp class="codeph"&gt;air.File.applicationStorageDirectory&lt;/samp&gt; property. You can access its contents using the &lt;samp class="codeph"&gt;resolvePath()&lt;/samp&gt; method of the File class.&lt;br /&gt;&lt;br /&gt;Do not installed AIR project under Vista/program file folder if you need touch SQLite DB file.&lt;br /&gt;&lt;br /&gt;Hopefully anyone does not hit this stupid error like me. &lt;strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-168114802950216062?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/168114802950216062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=168114802950216062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/168114802950216062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/168114802950216062'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/12/extjs-air-installed-in-vista-error.html' title='extjs + AIR installed in Vista SQLError 3122'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-5125168358815403064</id><published>2008-12-23T17:10:00.005-05:00</published><updated>2008-12-23T17:22:40.675-05:00</updated><title type='text'>Javascript file Concatenation and Compression</title><content type='html'>Currently there are several way to do this, you can see this one:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;YUI Compressor&lt;/span&gt; &lt;br /&gt;[&lt;a href="http://www.julienlecomte.net/blog/2008/10/80/"&gt;http://www.julienlecomte.net/blog/2008/10/80/&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;The YUI Compressor uses a slightly modified version of the parser used in the Rhino JavaScript engine.However, it is Java based tool and you need compile/run etc. Actually it is the best mini tool I found so far.&lt;br /&gt;&lt;br /&gt;If you use Apatan/Eclipse, maybe you need think this one.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;JSConcatenation &lt;/span&gt;&lt;br /&gt;[&lt;a href="http://www.rockstarapps.com/pmwiki/pmwiki.php?n=JsLex.JSConcatenation"&gt;http://www.rockstarapps.com/pmwiki/pmwiki.php?n=JsLex.JSConcatenation&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;Using this tool, will make your easy to mini your file into any output as your like. Rockstarapps.com has an aptana 'feature' that you download via aptanas internal software update engine. It allows for many other things but I was only interested in the JS tools it offers.&lt;br /&gt;&lt;br /&gt;It is very straight forward, select files in the resources pane or better yet select your script tags right in an HTML document and "right click--&gt; rockstarapps --&gt;concatenate javascript". It produces an xyz.all.js file (with comments), a xyz.all.min.js file (without comments, linebreaks and spaces) an xyz.all.ycomp.js file (minified and yui compressed), AND it even includes a xyz.all.ycomp.js.gz (Gzipped).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-5125168358815403064?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/5125168358815403064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=5125168358815403064' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/5125168358815403064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/5125168358815403064'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/12/javascript-file-concatenation-and.html' title='Javascript file Concatenation and Compression'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-7289514282428701120</id><published>2008-12-15T11:35:00.017-05:00</published><updated>2008-12-16T09:27:07.526-05:00</updated><title type='text'>fileupload with Extjs + Grails issues</title><content type='html'>Recently when I played fileupload with extjs + grails, I have several issues and take a while to identified.&lt;br /&gt;&lt;br /&gt;1: In extjs, you need set: fileUpload: true in your formPanel. This will send multipart POST to the server side.&lt;br /&gt;&lt;pre name="code" class="javascript"&gt;&lt;br /&gt;var imagepath = new Ext.form.FileUploadField({&lt;br /&gt;    id: 'form-file',&lt;br /&gt;    emptyText: 'Select an image',&lt;br /&gt;    fieldLabel: 'Photo',&lt;br /&gt;    name: 'imagepath',&lt;br /&gt;    anchor: '90%',&lt;br /&gt;    buttonCfg: {&lt;br /&gt;        text: '',&lt;br /&gt;        iconCls: 'upload-icon'&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;var formPanel = new Ext.form.FormPanel({&lt;br /&gt;    id: 'formPanel',&lt;br /&gt;    fileUpload: true,&lt;br /&gt;    baseCls: 'x-plain',&lt;br /&gt;    labelWidth: 120,&lt;br /&gt;    url:posurl,&lt;br /&gt;    defaultType: 'textfield',&lt;br /&gt;    items: [name, imagepath, description]&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2: You'd better download the latest bug-fixed build (1.0.5) if you see error:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;[1884908] errors.&lt;b class="highlight"&gt;GrailsExceptionResolver&lt;/b&gt; &lt;/span&gt;&lt;br /&gt;&lt;span&gt;java.lang.NullPointerException &lt;/span&gt;&lt;br /&gt;&lt;span&gt;        at java.net.&lt;b class="highlight"&gt;URLDecoder&lt;/b&gt;.&lt;b class="highlight"&gt;decode&lt;/b&gt;(&lt;b class="highlight"&gt;URLDecoder&lt;/b&gt;.java:119) &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There's something fundamentally wrong about how Grails handles multipart POST requests right now (since rev. 7387), but it only happens on this setup:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    a HTTP POST multipart request is sent to the server;&lt;/li&gt;&lt;li&gt;    the next request is a GET (or maybe POST also) with query parameters (eg, a query string is present in the URL);&lt;/li&gt;&lt;li&gt;    Jetty (or the container) binds this next requext to the same thread that the multipart POST was bound to.&lt;/li&gt;&lt;/ul&gt;Latest build @:&lt;br /&gt;http://bamboo.ci.codehaus.org/download/GRAILS-GRAILS15/artifacts/build-1462/Distributions&lt;br /&gt;&lt;br /&gt;This build fixed above issue - 3460 [http://jira.codehaus.org/browse/GRAILS-3640]. Grails-1.1-beta1 does not fix this issue.&lt;br /&gt;&lt;br /&gt;3: Render&lt;br /&gt;&lt;br /&gt;For fileupload, ExtJs's formpanel is expecting JSON reply, typical HTTP 200 response is not valid and you will get error on the client side Javascript. Therefore, you need to specify the JSON response as normal "text/html" instead of "application/json" type.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-7289514282428701120?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/7289514282428701120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=7289514282428701120' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7289514282428701120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7289514282428701120'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/12/extjs-grails-fileupload.html' title='fileupload with Extjs + Grails issues'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-9216543748336129620</id><published>2008-11-27T00:58:00.039-05:00</published><updated>2009-03-19T23:13:03.337-04:00</updated><title type='text'>Integrate Grails with Extjs</title><content type='html'>&lt;div&gt;0/1 -&gt; C -&gt; C++ -&gt; Java -&gt; ? (Assume it is: Grails + extjs)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Extjs acts as front-end, grails works as back-end. Both Grails and Extjs can handle JSON very well. Grails has built-in support for JSON. This is not surprise that JSON will be communication tool between them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, in Grails official documentation, there is not enough statement for how to generate JSON. Here comes some of my example to create JSON with Grails (List, Create, Update, Delete), and this JSON data will be feed into extjs (i.e: extjs sexy part - grid).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Feeling: Grails saved me lots of time to write backend code - not need any config and I do not need write hibernate mapping, this is amazing. It really let developer focus on application business logic (Still remember 2000 when EJB come and said this - it really did not). Just Eclipse does not well support grails at this moment, hopefully it come soon.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See running demo: &lt;a href="http://www.feyasoft.com"&gt;www.feyasoft.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;0: Update with NetBeans IDE6.5 &lt;span style="font-style: italic; color: rgb(255, 0, 0);"&gt;[Update Dec 24]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Recently I played this with NetBeans IDE6.5. Seems this one better than Eclipse, you just download the latest Netbeans package (250 M - huge). And Netbeans already have grails plugin. And you can simple click run button to make grails project run. Worth to have a try - I guess I will stay in Netbeans for a while in grails project.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1: Quick setup&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Eclipse 3.4 + &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin"&gt;Eclispe Grail Plugin&lt;/a&gt; + &lt;a href="http://www.spket.com/"&gt;Spket for Extjs&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2: list in Grail controller and extjs&lt;/div&gt;&lt;div&gt;&lt;pre name="code" class="java"&gt;/**&lt;br /&gt;* Copyright (c) 2005 - 2008 FeyaSoft Corp. All Rights Reserved.&lt;br /&gt;*/&lt;br /&gt;import grails.converters.*&lt;br /&gt;&lt;br /&gt;import com.feyasoft.myActivity.domain.account.*&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* @author Fenqiang Zhuang&lt;br /&gt;* @Dec 1, 2008&lt;br /&gt;*&lt;br /&gt;* This file is used to define the account controller action&lt;br /&gt;* This will provides the service for UI level.&lt;br /&gt;* Most important actions are list, save, update, delete&lt;br /&gt;*/&lt;br /&gt;class AccountController {&lt;br /&gt;&lt;br /&gt;// the delete, save and update actions only accept POST requests - maybe not necessary&lt;br /&gt;def allowedMethods = [delete:'POST', update:'POST', create:'POST']&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Mapping url: http://localhost:8080/fileMgr/account/list&lt;br /&gt;*&lt;br /&gt;* This will lost of accounts in the system based on search result.&lt;br /&gt;* Return result will be in JSON format.&lt;br /&gt;*&lt;br /&gt;*/&lt;br /&gt;def list = {&lt;br /&gt; // log information&lt;br /&gt;log.info(params: params)&lt;br /&gt; if(!params.max) params.max = 20&lt;br /&gt;&lt;br /&gt; // get a list of result based on params.&lt;br /&gt;def accounts = Account.list(params)&lt;br /&gt;&lt;br /&gt;// return a bunch of json data with metadata.&lt;br /&gt;def json = [&lt;br /&gt;  metaData: [&lt;br /&gt;       totalProperty: 'totalCount',&lt;br /&gt;       root: 'results',&lt;br /&gt;       id: 'id',&lt;br /&gt;       fields: [&lt;br /&gt;            [name: "id", type: "int"],&lt;br /&gt;            [name: "firstname"],&lt;br /&gt;            [name: "lastname"],&lt;br /&gt;            [name: "username"],&lt;br /&gt;            [name: "email"]&lt;br /&gt;       ]&lt;br /&gt;  ],         &lt;br /&gt;     totalCount: accounts.size,&lt;br /&gt;     results: accounts&lt;br /&gt;]&lt;br /&gt;&lt;br /&gt;render json as JSON &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* * Mapping url: http://localhost:8080/fileMgr/account/save&lt;br /&gt;*&lt;br /&gt;* create account method - get passed parameter from extjs and call save() function&lt;br /&gt;* If everything ok, it will return success message for form.&lt;br /&gt;*/&lt;br /&gt;def create = {&lt;br /&gt; def account = new Account(params)&lt;br /&gt;&lt;br /&gt; // default error msg&lt;br /&gt; def json = [failure : "true", errorInfo : "Internal Error, please try again"]&lt;br /&gt;      &lt;br /&gt; // check whether something wrong in save&lt;br /&gt; if(!account.hasErrors()) {&lt;br /&gt;  // check username already exist or not&lt;br /&gt;  if (Account.findAllByUsername(account.username).size()&gt;0) {&lt;br /&gt;   json = [failure : "true", errorInfo: "This username already existed, please choose another one"]&lt;br /&gt;  } else if (account.save()) {&lt;br /&gt;      json = [success : "true", info : "You have success creat this account"]&lt;br /&gt;  } else {&lt;br /&gt;   def errors = "Error is: "&lt;br /&gt;   account.errors.allErrors.each {&lt;br /&gt;    errors = errors + it&lt;br /&gt;      }&lt;br /&gt;   json = [failure : "true", errorInfo: errors]&lt;br /&gt;  }      &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; // return json data&lt;br /&gt; render json as JSON&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* This will load existing account information based on id from UI.&lt;br /&gt;* Return back a json string.&lt;br /&gt;*&lt;br /&gt;* JSON like this:&lt;br /&gt;*&lt;br /&gt;* {"success":"true","data":[{"id":4,"class":"Account","createDate":new Date(1227909694000),&lt;br /&gt;* "email":"","firstname":"jj","lastModifiedDate":new Date(1227909694000),"lastname":"j",&lt;br /&gt;* "password":"kkkk","username":"llkl"}]}&lt;br /&gt;*/&lt;br /&gt;def load = {&lt;br /&gt; def account = Account.get(params.id)&lt;br /&gt;&lt;br /&gt; if(account) {&lt;br /&gt;  def json = [success: "true", data: [account]]&lt;br /&gt;  render json as JSON&lt;br /&gt; } else {&lt;br /&gt;  // default error msg&lt;br /&gt;     def json = [failure : "true", errorInfo : "Internal Error, please try again"]&lt;br /&gt;     render json as JSON&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* This will update the passed parameter from UI level&lt;br /&gt;* Called by the Edit.js file.&lt;br /&gt;*/&lt;br /&gt;def update = {&lt;br /&gt; def account = Account.get( params.id )&lt;br /&gt;&lt;br /&gt; // default error msg&lt;br /&gt; def json = [failure : "true", errorInfo : "Internal Error, please try again"]&lt;br /&gt;      &lt;br /&gt; if(account) {&lt;br /&gt;     account.properties = params&lt;br /&gt;     if(!account.hasErrors()) {&lt;br /&gt;      if (account.save()){&lt;br /&gt;          json = [success : "true", info : "You have success update this account"]&lt;br /&gt;      } else {&lt;br /&gt;       def errors = "Error is: "&lt;br /&gt;       account.errors.allErrors.each {&lt;br /&gt;        errors = errors + it&lt;br /&gt;          }&lt;br /&gt;       json = [failure : "true", errorInfo: errors]&lt;br /&gt;      }&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; // return json data&lt;br /&gt; render json as JSON&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* Delete this related account by id - passed by&lt;br /&gt;*/&lt;br /&gt;def delete = {&lt;br /&gt;def json = [failure : "true", errorInfo : "Internal Error, please try again"]&lt;br /&gt;    &lt;br /&gt; // check whether del parameter is passed - if yes, delete first&lt;br /&gt; if (params.delData != null) {&lt;br /&gt;  def jsonArray = JSON.parse(params.delData)&lt;br /&gt;  jsonArray.each {&lt;br /&gt;   log.info("start to delete account with id: ${it.id}")&lt;br /&gt;   def delAccount = Account.get(new Long("${it.id}"))&lt;br /&gt;   if (delAccount) {&lt;br /&gt;    delAccount.delete()&lt;br /&gt;    json = [success : "true", info : "You have success delete this account"]&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;render json as JSON&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Here is the extjs side code:&lt;br /&gt;&lt;/div&gt;&lt;pre name="code" class="javascript"&gt;    feyaSoft.account.List = function() {&lt;br /&gt;&lt;br /&gt;Ext.QuickTips.init();&lt;br /&gt;&lt;br /&gt;// define default rowsPerPage = 10;&lt;br /&gt;var myPageSize = 20;&lt;br /&gt;&lt;br /&gt;var accountCM = new Ext.grid.ColumnModel([&lt;br /&gt;new Ext.grid.RowNumberer(),&lt;br /&gt;{id: 'id', header: "Identify", dataIndex: 'id', width: 150, hidden: true},&lt;br /&gt;{header: "First Name", dataIndex: 'firstname',width: 150},&lt;br /&gt;{header: "Last Name", dataIndex: 'lastname',width: 150},&lt;br /&gt;{header: "Username", dataIndex: 'username',width: 150},&lt;br /&gt;{header: "Email", dataIndex: 'email',width: 150}&lt;br /&gt;]);&lt;br /&gt;accountCM.defaultSortable = false;&lt;br /&gt;&lt;br /&gt;/************************************************************&lt;br /&gt;* connect to backend - grid - core part&lt;br /&gt;* create the Data Store&lt;br /&gt;*   connect with backend and list the result in page&lt;br /&gt;*   through JSON format&lt;br /&gt;************************************************************/&lt;br /&gt;this.dataStore = new Ext.data.JsonStore({&lt;br /&gt;url: 'account/list',&lt;br /&gt;remoteSort: true,&lt;br /&gt;fields: [] // initialized from json metadata&lt;br /&gt;});&lt;br /&gt;this.dataStore.setDefaultSort('lastname', 'ASC');&lt;br /&gt;&lt;br /&gt;/************************************************************&lt;br /&gt;* Define menubar now in here&lt;br /&gt;*   add and delete functions&lt;br /&gt;************************************************************/&lt;br /&gt;var menubar = [{&lt;br /&gt;text:'Add New Account',&lt;br /&gt;tooltip:'Add a new account information',&lt;br /&gt;iconCls:'addItem',&lt;br /&gt;handler: function(){&lt;br /&gt;    // add new user now - call another JS class&lt;br /&gt;    new feyaSoft.account.Create();&lt;br /&gt;}&lt;br /&gt;},'-',{&lt;br /&gt;text:'Archive',&lt;br /&gt;tooltip:'Archive the selected items',&lt;br /&gt;iconCls:'remove',&lt;br /&gt;handler: function(){&lt;br /&gt;    //new feyaSoft.util.DeleteItem({panel: 'listAccount-panel'});&lt;br /&gt;}&lt;br /&gt;}];&lt;br /&gt;&lt;br /&gt;var pagingbar = new Ext.ux.PagingToolbar({&lt;br /&gt;pageSize: myPageSize,&lt;br /&gt;store: this.dataStore,&lt;br /&gt;displayInfo: true,&lt;br /&gt;displayMsg: 'Displaying items {0} - {1} of {2}',&lt;br /&gt;emptyMsg: "not result to display"&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;/************************************************************&lt;br /&gt;* define grid panel now&lt;br /&gt;* For more detail parameters, you can find from extjs API&lt;br /&gt;************************************************************/&lt;br /&gt;feyaSoft.account.List.superclass.constructor.call(this, {&lt;br /&gt;id: 'list-account-panel',               &lt;br /&gt;ds: this.dataStore,&lt;br /&gt;cm: accountCM,&lt;br /&gt;viewConfig: {forceFit:true},                 &lt;br /&gt;tbar: menubar,&lt;br /&gt;bbar: pagingbar,&lt;br /&gt;height:400,&lt;br /&gt;width:800,&lt;br /&gt;frame: true,&lt;br /&gt;autoScroll:true&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;// trigger the data store load&lt;br /&gt;this.dataStore.load({params:{start:0, limit:myPageSize}});&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Ext.extend(feyaSoft.account.List, Ext.grid.GridPanel, {&lt;br /&gt;&lt;br /&gt;// reload datasource&lt;br /&gt;reload : function () {&lt;br /&gt;this.dataStore.load();&lt;br /&gt;},&lt;br /&gt;&lt;br /&gt;remove : function (row) {&lt;br /&gt;this.dataStore.remove(row);&lt;br /&gt;},&lt;br /&gt;&lt;br /&gt;deleteData : function (jsonData) {&lt;br /&gt;this.dataStore.load({params:{start:0, delData:jsonData}});&lt;br /&gt;}&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Some hints maybe help for your to use Grails:&lt;br /&gt;&lt;br /&gt;1: Get latest version Grail 1.0.4 and setup GRAIL_HOME in your ENV: http://grails.org/&lt;br /&gt;&lt;br /&gt;2: Create a grails project through Eclipse.&lt;br /&gt;&lt;br /&gt;3: Update&lt;br /&gt;&lt;br /&gt;You do not need create tables - using dbCreate="create" for first time and grails will create DB table for us (you do need create database name). Go to:&lt;br /&gt;grails-app/conf/DataSource.groovy file, you need update:&lt;br /&gt;&lt;pre name="code" class="java"&gt; dataSource {&lt;br /&gt;pooled = true&lt;br /&gt;driverClassName = "com.mysql.jdbc.Driver"&lt;br /&gt;username = "root"&lt;br /&gt;password = "XXXXXX"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;development {&lt;br /&gt;dataSource {&lt;br /&gt;    dbCreate = "update" // one of 'create', 'create-drop', 'update' - first time, please use 'create'&lt;br /&gt;    url = "jdbc:mysql://localhost:3306/demo?tcpKeepAlive=true&amp;amp;useUnicode=true&amp;amp;characterEncoding=UTF8"&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4: Run&lt;br /&gt;&lt;br /&gt;come to the project folder: cd yourProjectFolder // using cmd&lt;br /&gt;&lt;br /&gt;&gt; grails clean   &lt;--- sometimes compiled code are not cleaned and behavior weird - clean will help&lt;div&gt; &gt; grails run-app&lt;br /&gt;&lt;br /&gt;You can also run this through ant in Eclipse. However, I do not know how to stop Jetty under Eclipse (Finally I kill it through Ctrl + Alt + del and find task manager - kill all of Java running thread.).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-9216543748336129620?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/9216543748336129620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=9216543748336129620' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/9216543748336129620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/9216543748336129620'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/06/integrate-grails-with-extjs.html' title='Integrate Grails with Extjs'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-278589131297145638</id><published>2008-11-05T10:15:00.008-05:00</published><updated>2008-11-28T09:48:41.554-05:00</updated><title type='text'>Extjs based Calendar 1.0 release</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;After a while (6 month later), we finially have some time and move our calendar forward again. In this release 1.0, you will see the following feature:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Fully integrated in Ext&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;different views (day, week, month)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;create/delete/change entries -- contextMenu and doubleClick&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;drag and drop to shift entries&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Event overlaps&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;event south resizeable&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;edit entries in a window&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;colorable event&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;The project structure is still:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="font-style: italic; font-family:courier new;"&gt;Extjs + spring MVC Json View + Spring + hibernate + Mysql&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;To view demo, please visit: &lt;/span&gt;&lt;/span&gt;&lt;a href="http://www.feyasoft.com/"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: arial;"&gt;www.feyasoft.com&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-278589131297145638?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/278589131297145638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=278589131297145638' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/278589131297145638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/278589131297145638'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/11/extjs-based-calendar.html' title='Extjs based Calendar 1.0 release'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1908610857829460752</id><published>2008-10-20T09:21:00.009-04:00</published><updated>2008-12-11T10:02:33.836-05:00</updated><title type='text'>Adobe AIR + extjs for desktop application</title><content type='html'>&lt;div&gt;For building desktop application, there have .Net and Java Swing solution. However, there seems not that elegant for me. Recently we are trying to use following structure to build own desktop application:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-weight: bold;"&gt;Adobe AIR (SQLite buildin) + extjs &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is the general steps we process to build extjs + AIR project:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;1: Download develop tool which will use to edit/package adobe air project (Adobe air and Aptana studio)&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.adobe.com/devnet/air/ajax/getting_started.html"&gt;http://www.adobe.com/devnet/air/ajax/getting_started.html&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2: Start Aptana and install plugin&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Click the icon (4th or 5th icon in second line): "Open Plugin View", you will find:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Adobe Air support&lt;/li&gt;&lt;li&gt;extjs support&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Install those 2 plugin.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3: Now start Aptana - create new project&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;File -&gt; New -&gt; project -&gt; Adobe Air Project&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can create some example project - such as: Tasks. And you will find 2 important files: tasks.html and application.xml&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;4: Hit: Run -&gt; Run ...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You will see your example running ...&lt;br /&gt;&lt;br /&gt;5: Export/deploy air project.&lt;br /&gt;&lt;br /&gt;You need setup certificate. Every AIR application requires certificate signing in order to be built and deployed.See this link for more information:&lt;br /&gt;&lt;br /&gt;http://www.adobe.com/devnet/air/ajax/articles/building_on_air_in_aptana_05.html&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some problem ...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div  style="font-family:arial;"&gt;* If you see "&lt;span style="border-collapse: collapse; color: rgb(51, 51, 51);"&gt;&lt;span style="font-size:85%;"&gt;invocation forwarded to primary instance"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: collapse; color: rgb(51, 51, 51);font-family:Arial;" &gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:arial;"&gt;You need go to your task manager and kill manually ADL.EXE&lt;/span&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1908610857829460752?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1908610857829460752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1908610857829460752' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1908610857829460752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1908610857829460752'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/10/adobe-air-extjs-for-desktop-application.html' title='Adobe AIR + extjs for desktop application'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-7289557162578267273</id><published>2008-06-04T11:23:00.008-04:00</published><updated>2008-06-17T10:23:16.337-04:00</updated><title type='text'>DWR or Spring MVC + JSONView</title><content type='html'>To build extjs based application. At first glance, you will find that DWR is pretty neat. You do not need MVC level code and client side can talk direct to service layer. Seems this will save lots of time and code.&lt;br /&gt;&lt;br /&gt;Wait.... Is this really true? (perfect solution = time cosuming ?)&lt;br /&gt;&lt;br /&gt;After fight with DWR problem for a while, I decide move back to Spring MVC JsonView. &lt;br /&gt;&lt;br /&gt;Extjs have a pretty good interface to hanlde JSON data. By using DWR, you need decide whether you still use JSON data, or pass trhough object (maybe parameter). You need write your own reader to understand passed object. At least you need write: DWRTreeProxy, DWRListProxy, DWRComboProxy. True, you can copy those proxy from forum, there are lots of examples. However, those example does not have quality guarantee, and it drive me crazy to debug line by line. &lt;br /&gt;&lt;br /&gt;I try to save time when I move to DWR, finally I found I spent more time that using Spring MVC + JsonView.&lt;br /&gt;&lt;br /&gt;Suggestion: if you know really well for extjs and DWR, you can try using DWR. Jack said that he had a really success porject with Extjs + DWR. However, Jack is Jack. Otherwise, keep Extjs + JsonView. This will save your lots of time. (honestly, Extjs + JsonView already really beautiful, DWR seems a perfect solution, however it will take your long time if you are not as smart as Jack - oh ya, I am only 10% smart as Jack)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-7289557162578267273?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/7289557162578267273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=7289557162578267273' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7289557162578267273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7289557162578267273'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/06/dwr-or-spring-mvc-jsonview.html' title='DWR or Spring MVC + JSONView'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-4981002356889659006</id><published>2008-03-28T10:54:00.019-04:00</published><updated>2008-11-28T10:56:16.936-05:00</updated><title type='text'>Spring MVC JSON view</title><content type='html'>For Ajax-based web application, one of the most popular ways for message transfer is JSON (JavaScript Object Notation). JSON provides a pretty name/value pair data format which is easy to generate and parse.&lt;br /&gt;&lt;br /&gt;With the popular using Spring framework. It would be really useful to integrate Spring MVC view with JSON. Spring already provides several view resolvers, which enable us to render models in a browser, such as: JSPs, Velocity templates and XSLT views.&lt;br /&gt;&lt;br /&gt;To add JSON view to the Spring MVC, we need create a class: JSONView&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class JSONView implements View {&lt;br /&gt;private static final String DEFAULT_JSON_CONTENT_TYPE = "application/json";&lt;br /&gt;private static final String DEFAULT_JAVASCRIPT_TYPE = "text/javascript";&lt;br /&gt;private JSONObject jsonObject;&lt;br /&gt;&lt;br /&gt;public JSONView(JSONObject jsonObject) {&lt;br /&gt; super();&lt;br /&gt; this.jsonObject = jsonObject;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public JSONView() {&lt;br /&gt; super();&lt;br /&gt; this.jsonObject = null;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public String getContentType() {&lt;br /&gt; return DEFAULT_JSON_CONTENT_TYPE;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void render(Map model, HttpServletRequest request,&lt;br /&gt; HttpServletResponse response) throws Exception {&lt;br /&gt; if (this.jsonObject == null) {&lt;br /&gt;  this.jsonObject = JsonUtil.fromMap(model);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; boolean scriptTag = false;&lt;br /&gt; String cb = request.getParameter("callback");&lt;br /&gt; if (cb != null) {&lt;br /&gt;  scriptTag = true;&lt;br /&gt;  response.setContentType(DEFAULT_JAVASCRIPT_TYPE);&lt;br /&gt; } else {&lt;br /&gt;  response.setContentType(DEFAULT_JSON_CONTENT_TYPE);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; PrintWriter out = response.getWriter();&lt;br /&gt; if (scriptTag) {&lt;br /&gt;  out.write(cb + "(");&lt;br /&gt; }&lt;br /&gt; out.write(this.jsonObject.toString());&lt;br /&gt; if (scriptTag) {&lt;br /&gt;  out.write(");");&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And this is fromMap function in JsonUtil&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public static JSONObject fromMap(Map model) {&lt;br /&gt; JSONObject jsonObject = new JSONObject();&lt;br /&gt;&lt;br /&gt; try {&lt;br /&gt;  Iterator&lt;string&gt; ite = model.keySet().iterator();&lt;br /&gt;  while (ite.hasNext()) {&lt;br /&gt;   String key = ite.next();&lt;br /&gt;   jsonObject.put(key, model.get(key));&lt;br /&gt;  }&lt;br /&gt; } catch (Exception e) {&lt;br /&gt;  log.error("call fromMap failed ");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return jsonObject;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And in the controller side, we can pass JOSNObject to create a JSONView. Or we can also pass MAP to create JSONView.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; Map&lt;string, string=""&gt; map = new HashMap&lt;string, string=""&gt;();&lt;br /&gt; map.put("success", "true");&lt;br /&gt; map.put("info", "Succeed create this audit object");&lt;br /&gt; return new ModelAndView(new JSONView(), map);&lt;br /&gt;&lt;/pre&gt; OR &lt;pre&gt;&lt;br /&gt; BaseSearchResult searchResult = auditService.getList(listAuditInfo);&lt;br /&gt; AuditUtil auditUtil = new AuditUtil(searchResult); &lt;br /&gt; return new ModelAndView(new JSONView(auditUtil.toJSONObject()));&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-4981002356889659006?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/4981002356889659006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=4981002356889659006' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/4981002356889659006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/4981002356889659006'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/03/spring-mvc-json-view.html' title='Spring MVC JSON view'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1801799746293881099</id><published>2008-02-28T08:24:00.011-05:00</published><updated>2008-03-31T13:14:30.347-04:00</updated><title type='text'>FeyaSoft MyActivity</title><content type='html'>After awhile, FeyaSoft MyActivity 1.0 is released now. It includes the following features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;My Calendar&lt;/li&gt;&lt;li&gt;My Documents&lt;/li&gt;&lt;li&gt;My TimeSheet&lt;/li&gt;&lt;li&gt;My Task (1.1 release)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The main purpose for this application is try to make your daily activity smooth and easily. And it is pretty easy plugin to your existing system.&lt;br /&gt;&lt;br /&gt;To view it, please go to the following link self-register and login:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://feyasoft.com/myActivity"&gt;http://www.feyasoft.com/myActivity&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The whole system is built with: &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;color=blue;"&gt;EXTJS + Acegi Security + Spring MVC(JSON View) + Spring + Hibernate(Annotation) + mysql&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Simple, qualify and affordable. ENJOY&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1801799746293881099?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1801799746293881099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1801799746293881099' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1801799746293881099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1801799746293881099'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2008/02/feyasoft-myactivity.html' title='FeyaSoft MyActivity'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-8105334518806524973</id><published>2007-12-29T14:21:00.001-05:00</published><updated>2008-11-03T11:40:33.689-05:00</updated><title type='text'>Extjs Calendar</title><content type='html'>After fought for 2 weeks, extjs calendar Beta0.1 is released today. It has the following features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; create/delete/change entries  (one click for create new entry; double click for edit and delete entry)&lt;/li&gt;&lt;li&gt; drag and drop to shift entries&lt;/li&gt;&lt;li&gt; edit entries in a window (double click)&lt;/li&gt;&lt;li&gt; resize the entry in south direction&lt;/li&gt;&lt;/ul&gt;This design is based on the EXTJS ajax framework. To view the demo, please see the following link:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.feyasoft.com/" target="_blank"&gt;http://www.feyasoft.com&lt;/a&gt; -&gt;  click 'My Calendar' icon on the desktop.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-8105334518806524973?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/8105334518806524973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=8105334518806524973' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/8105334518806524973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/8105334518806524973'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/12/extjs-calendar.html' title='Extjs Calendar'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-899372264564639030</id><published>2007-12-02T09:17:00.000-05:00</published><updated>2007-12-02T09:34:08.196-05:00</updated><title type='text'>Ajax based (EXTJS) application authentication</title><content type='html'>For Ajax based authentication, it's not a whole lot different than providing a traditional web infrastructure. What we're aiming for is to guarantee our session is secure and there is an established and persistent authentication object for all requests. There are a number of ways to accomplish this.&lt;br /&gt;&lt;br /&gt;First is to secure the wire. This means whatever we do, make sure the user can never get to the website via regular HTTP and always uses HTTPS. It's pretty simple to setup Apache to do this.&lt;br /&gt;&lt;br /&gt;Next is the authentication mechanism. The objective here is to generate and cache a session object that is guaranteed to be correct between the web server and the web browser for the duration of that web browser's session or until a session timeout occurs. This can easily be provided in one of two ways: HTTP authentication or HTTP sessions.&lt;br /&gt;&lt;br /&gt;The positives of HTTP authentication is that it's standards based and provides transparent authentication after an initial authentication is complete. We get headers for the username, password, and realm for every invocation to the web service after this is completed. This includes invocations with our embedded ajax components. The negatives is that it's not secure, so we absolutely need to push it over HTTPS if you're going to use it. In addition, there's no authorization mechanism built in, so we need to roll own for authorization levels. And finally, we can't log out if using HTTP authentication. Once a user is authenticated, there's no means to unauthenticate them other than closing the browser and starting over.&lt;br /&gt;&lt;br /&gt;Session-based authentication provides similar functionality to HTTP authentication, but we need to manage the session information. It does not provide a means to do authorization levels either, requiring we to roll our authorization levels. The benefit of session-based authentication is that we can log out from a session by removing the session variable at the web server. The disadvantages of using session-based authentication is that we have to figure out a mechanism to store passwords in other than cleartext format. This is because we're not sent the username/password combo in the headers, but instead we get a sessionid for the established session.&lt;br /&gt;&lt;br /&gt;A basic rule of thumb, provided we're not doing persistent cookie session information, is that until a user establishes a known authentication session with web server, there are no credentials available with which to guarantee their access. Typically the ONLY place I need to make absolutely certain that authentication has happened is on the server, since that's where all of the data will be housed. The browser is just a window into that data.&lt;br /&gt;&lt;br /&gt;From a technical perspective, here's how a session-based authentication would work:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; User starts a brand new browser and connects to ajax-enabled app. &lt;/li&gt;&lt;li&gt; Application then posts some type of dialog box requiring a login to the server&lt;/li&gt;&lt;li&gt; The user enters their username/password into that dialog and clicks the login button&lt;/li&gt;&lt;li&gt; Javascript should hook the login button and send an ajax request to whatever login script/service/servlet/whatever is running on the server side&lt;/li&gt;&lt;li&gt; The server takes the parameters and passes them through whatever authentication system  using on the server.&lt;/li&gt;&lt;li&gt; If the credentials work, the server creates a sessionid storage area for this new sessionid and returns a positive response to the ajax client. Part of the http headers for this response is the sessionid for maintaining session information between the client and the server. In the sessionid storage area on the server, we can store whatever variables we want to store. &lt;/li&gt;&lt;li&gt; The HTTP stack in the browser maintains the sessionid for each successive invocation to the web server that it's talking to and ONLY for that web server. As long as the browser is running, the sessionid is maintained. Once the browser goes away, the sessionid goes away with it. There are known session hijacking hacks out there, but they can be averted by providing a bit more information within the variables attached to the sessionid on the server.&lt;/li&gt;&lt;li&gt; Each of the successive xmlhttprequest objects that ask for data from the server pass the sessionid with it. In our application on the server, the first thing we need do for EVERY invocation is validate that the sessionid is still valid. There are mechanisms in most server application frameworks to provide session expiration by a variety of means. We just need to validate their sessionid with whatever framework you're using. &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-899372264564639030?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/899372264564639030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=899372264564639030' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/899372264564639030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/899372264564639030'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/12/ajax-based-extjs-authentication.html' title='Ajax based (EXTJS) application authentication'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-4563699384009856897</id><published>2007-11-26T11:27:00.001-05:00</published><updated>2007-11-26T11:29:57.274-05:00</updated><title type='text'>Need JSF or using Ajax</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_gx3yNfk96Ts/R0r0AvgcR3I/AAAAAAAAAFI/QD9BGoHlpLQ/s1600-h/fra.JPG"&gt;&lt;img style="cursor: pointer;" src="http://bp2.blogger.com/_gx3yNfk96Ts/R0r0AvgcR3I/AAAAAAAAAFI/QD9BGoHlpLQ/s400/fra.JPG" alt="" id="BLOGGER_PHOTO_ID_5137186618559186802" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-4563699384009856897?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/4563699384009856897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=4563699384009856897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/4563699384009856897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/4563699384009856897'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/11/need-jsf.html' title='Need JSF or using Ajax'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_gx3yNfk96Ts/R0r0AvgcR3I/AAAAAAAAAFI/QD9BGoHlpLQ/s72-c/fra.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1382367694663999032</id><published>2007-10-26T13:43:00.000-04:00</published><updated>2007-11-19T10:05:41.256-05:00</updated><title type='text'>Light J2EE Application High Level Architecture Diagram</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_gx3yNfk96Ts/RzXbmxnTWeI/AAAAAAAAAFA/4TZir6xPBTE/s1600-h/hla.gif"&gt;&lt;img style="cursor: pointer;" src="http://bp1.blogger.com/_gx3yNfk96Ts/RzXbmxnTWeI/AAAAAAAAAFA/4TZir6xPBTE/s400/hla.gif" alt="" id="BLOGGER_PHOTO_ID_5131248809658243554" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;For Web Application, industry are pretty close agree to use light J2EE (Spring + hibernate) loose coupling concepts in business logic tier. However, there are not clear blueprint for presentation tie. Do we still need use thin-client or rich-client? I believe it is time to move (at least think) rich client. In here, I introduce a model for thick client:&lt;br /&gt;&lt;br /&gt;1: Download Client-side application to user browser. (For example: extjs)&lt;br /&gt;2: Client-side logic flow&lt;br /&gt;3: Data exchange through AJAX in JSON format (client-server event driver)&lt;br /&gt;&lt;br /&gt;For thin client,  we can not respect "data" exchange between client and server. Maybe it just a kind of "String" exchange. For thick client, it is real data (JSON).&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;Reference&lt;/span&gt;:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;1: &lt;a href="http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html"&gt;&lt;span style="font-style: italic;"&gt;Put JSF to work -- Build a real-world Web application with JavaServer Faces, the Spring Framework, and Hibernate&lt;/span&gt;&lt;/a&gt;; Derek Yang Shen, JavaWorld.com;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1382367694663999032?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1382367694663999032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1382367694663999032' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1382367694663999032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1382367694663999032'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/10/light-j2ee-application-high-level.html' title='Light J2EE Application High Level Architecture Diagram'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_gx3yNfk96Ts/RzXbmxnTWeI/AAAAAAAAAFA/4TZir6xPBTE/s72-c/hla.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1995850478840987513</id><published>2007-09-18T15:09:00.000-04:00</published><updated>2007-09-18T15:21:17.645-04:00</updated><title type='text'>Improve pages performance - 2 cents</title><content type='html'>&lt;ul style="text-align: left;"&gt;&lt;li&gt;Reduces the number of HTTP requests - Reducing the number of components to be downloaded.&lt;/li&gt;&lt;li&gt;Moving stylesheets to the document HEAD - makes pages load faster.&lt;/li&gt;&lt;li&gt;Move scripts from the top to as low in the page as possible - enable progressive rendering.&lt;/li&gt;&lt;li&gt;Avoid CSS expression.&lt;/li&gt;&lt;li&gt;Reduce DNS lookup.&lt;/li&gt;&lt;li&gt;Avoid page redirect.&lt;/li&gt;&lt;li&gt;Clean Scripts code - remove duplicate code.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1995850478840987513?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1995850478840987513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1995850478840987513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1995850478840987513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1995850478840987513'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/09/improve-pages-performance-2-cents.html' title='Improve pages performance - 2 cents'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-985711897221658620</id><published>2007-08-19T18:07:00.000-04:00</published><updated>2007-08-19T18:45:58.635-04:00</updated><title type='text'>Javascript files Directory Structure</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_gx3yNfk96Ts/RsjAL9zW9sI/AAAAAAAAAEA/ic3z_BoQB6o/s1600-h/script.GIF"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp3.blogger.com/_gx3yNfk96Ts/RsjAL9zW9sI/AAAAAAAAAEA/ic3z_BoQB6o/s400/script.GIF" alt="" id="BLOGGER_PHOTO_ID_5100537889798158018" border="0" /&gt;&lt;/a&gt;Currently there does not exist any standard structure for javascript files directory. In here, I just follow the Java file structure and create a similar file structure for javascript.&lt;br /&gt;&lt;br /&gt;As you see, I create a dir 'javascript' which is used to hold all of JS files.  And I also create a project related dir 'FEYA' which is used to hold all of my JS file. Any 3rd-party JS lib are parallel to this dir.&lt;br /&gt;&lt;br /&gt;Under 'FEYA' dir, 'FEYA.js' is used to define namespace.  Any other my JS file will call it to define package. And here comes my example html code to include those JS files:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_gx3yNfk96Ts/RsjICNzW9vI/AAAAAAAAAEY/41YWc-O8wgk/s1600-h/html.GIF"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_gx3yNfk96Ts/RsjICNzW9vI/AAAAAAAAAEY/41YWc-O8wgk/s400/html.GIF" alt="" id="BLOGGER_PHOTO_ID_5100546518387455730" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_gx3yNfk96Ts/RsjG-9zW9tI/AAAAAAAAAEI/fl2-tMrzYBc/s1600-h/html.GIF"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-985711897221658620?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/985711897221658620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=985711897221658620' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/985711897221658620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/985711897221658620'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/08/javascript-files-directory-structure.html' title='Javascript files Directory Structure'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_gx3yNfk96Ts/RsjAL9zW9sI/AAAAAAAAAEA/ic3z_BoQB6o/s72-c/script.GIF' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-3028851133083784150</id><published>2007-07-24T16:35:00.000-04:00</published><updated>2007-08-19T17:56:14.672-04:00</updated><title type='text'>Javascript package/public/private method</title><content type='html'>Perhaps a very uncommon approach to developing web applications that require JavaScript is namespacing your scripts. And how to define a scope (public/private) to the method and variable. This blog introduces a simple singleton pattern for achieving this discipline.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_gx3yNfk96Ts/RqdF-c-EZFI/AAAAAAAAADw/ohXQ4vjynYk/s1600-h/package.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp2.blogger.com/_gx3yNfk96Ts/RqdF-c-EZFI/AAAAAAAAADw/ohXQ4vjynYk/s320/package.JPG" alt="" id="BLOGGER_PHOTO_ID_5091114842996368466" border="0" /&gt;&lt;/a&gt;First I define a base JS class which will be included in any page to define a package (or you can call it 'namespace'). See right figure for detail source code.&lt;br /&gt;&lt;br /&gt;Second, I will call this method in any JS class - define the package just like java class.&lt;br /&gt;&lt;pre&gt;/**&lt;br /&gt;* Copyright(c) 2006-2007 ...&lt;br /&gt;*/&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255); font-style: italic;"&gt;package("FEYA.util");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;* This JS is used to define a bunch of util class&lt;br /&gt;*&lt;br /&gt;* @author fzhuang&lt;br /&gt;* @Date July 26, 2007&lt;br /&gt;*/&lt;br /&gt;FEYA.util.common = function(){&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    &lt;span style="font-family:courier new;"&gt;// private variable/function. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;font-family:courier new;" class="co1" &gt;Not accessible from outside&lt;/span&gt;&lt;br /&gt;&lt;span class="kw2"&gt;    var&lt;/span&gt; count = &lt;span class="nu0"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;span class="kw2"&gt;    var&lt;/span&gt; increaseCount = &lt;span class="kw2"&gt;function&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;count++;&lt;span class="br0"&gt;}&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:mon;"&gt;&lt;span style="font-style: italic;"&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;// &lt;/span&gt;&lt;span class="co1"&gt;&lt;span style="font-style: italic;"&gt;Priviledged method. Can be called from outside&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;    return {&lt;br /&gt;   formatDate: function(value){&lt;br /&gt;      return value ? value.dateFormat('D, M d Y') : '';&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;}();&lt;br /&gt;&lt;/pre&gt;Third, I can call following public functions from any JS class. &lt;pre style="color: rgb(51, 102, 255);"&gt;FEYA.util.common.formatDate&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-3028851133083784150?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/3028851133083784150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=3028851133083784150' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3028851133083784150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/3028851133083784150'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/07/javascript-packagepublicprivate-method.html' title='Javascript package/public/private method'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_gx3yNfk96Ts/RqdF-c-EZFI/AAAAAAAAADw/ohXQ4vjynYk/s72-c/package.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-77092074361883265</id><published>2007-06-16T22:47:00.000-04:00</published><updated>2007-06-18T14:43:14.821-04:00</updated><title type='text'>YUI-Ext tutorial for List, create, update, delete</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_gx3yNfk96Ts/RnbRRpxSxZI/AAAAAAAAADc/AyJXYCDMGMs/s1600-h/myPost.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_gx3yNfk96Ts/RnbRRpxSxZI/AAAAAAAAADc/AyJXYCDMGMs/s320/myPost.JPG" alt="" id="BLOGGER_PHOTO_ID_5077475731107399058" border="0" /&gt;&lt;/a&gt;Today I posted the following tutorial in YUI-EXT, please see the link:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://extjs.com/learn/Tutorial:Using_Ext_grid_form_dialog_to_achieve_paging_list%2C_create%2C_edit%2C_delete_function"&gt;Using Ext grid + form + dialog to achieve paging list, create, edit, delete function&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This tutorial mainly focus on using EXT grid/form/dialog functions to achieve general paging action (list, create, update, delete). It provides a different pattern to build page instead of J2EE MVC pattern.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_gx3yNfk96Ts/RnbQpJxSxYI/AAAAAAAAADU/y38v_VTa7Zs/s1600-h/myPost.JPG"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-77092074361883265?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/77092074361883265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=77092074361883265' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/77092074361883265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/77092074361883265'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/06/yui-ext-tutorial-for-list-create-update.html' title='YUI-Ext tutorial for List, create, update, delete'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_gx3yNfk96Ts/RnbRRpxSxZI/AAAAAAAAADc/AyJXYCDMGMs/s72-c/myPost.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-9185849642946282792</id><published>2007-05-10T14:28:00.000-04:00</published><updated>2007-05-11T15:35:26.614-04:00</updated><title type='text'>Web 2.0 application: Ajax replace MVC framework</title><content type='html'>We have played Struts/JSF/Spring/hibernate for Enterprise application, doing transaction etc for a while.  Now it is time move to web 2.0 (readable) and face AJAX.&lt;br /&gt;&lt;br /&gt;In web application, Struts/JSF MVC framework are pretty popular. However, Ajax-based web application can make this process simpler. As the following figure shows, Ajax based application only need a simple servelet to transfer data. Compare with MVC framework, this is a small job. At the same time, a good Ajax Util framework will create rich GUI in the client browser with simple javascript/html code. In general Ajax can be separated as 3 parts:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_gx3yNfk96Ts/RkR19J6YgxI/AAAAAAAAAC8/_4XIuBGkQaI/s1600-h/webApp.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_gx3yNfk96Ts/RkR19J6YgxI/AAAAAAAAAC8/_4XIuBGkQaI/s400/webApp.jpg" alt="" id="BLOGGER_PHOTO_ID_5063301574564545298" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;First part is client-side Ajax, such as animation, drag-and-drop, rich editor etc. YUI, dojo, rico provide lots of great examples.&lt;br /&gt;&lt;br /&gt;Second part is the bridge between browser side and Java server side, like bunch of RPC frameworks, DWR, prototype, YUI etc.&lt;br /&gt;&lt;br /&gt;Third part is general Ajax Util framework (templates) which can be applied to most applications, such as search function, paging function, CRUD/List function etc. We can think them as glue tool between browser and server, and it will dramatically reduce code by using those utils. YUI extension provides great example for this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-9185849642946282792?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/9185849642946282792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=9185849642946282792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/9185849642946282792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/9185849642946282792'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/05/web-20-ajax-and-spring.html' title='Web 2.0 application: Ajax replace MVC framework'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_gx3yNfk96Ts/RkR19J6YgxI/AAAAAAAAAC8/_4XIuBGkQaI/s72-c/webApp.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1390129786656697775</id><published>2007-04-29T10:34:00.000-04:00</published><updated>2007-05-29T21:57:59.251-04:00</updated><title type='text'>JSON speed up Ajax</title><content type='html'>The JavaScript Object Notation, or JSON, is a lightweight syntax for representing data. JSON has structure with nesting of data elements, just as XML does. JSON is also text-based and use Unicode. It is just as readable by humans as XML is. Here comes a simple example for Json:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;   {"totalCount":2,&lt;br /&gt;"results":[{"bh":"100","sm":"hello"},{"bh":"101","sm":"me" }]}&lt;/blockquote&gt;&lt;/span&gt;The big different about JSON and XML is that JSON is a subset of JavaScript. I can use JavaScript's own compiler to do just that by calling eval. Parsing JSON is a one-liner! Moreover, navigating an object synthesized from JSON is identical to navigating any JavaScript object. It's far easier than navigating through the DOM tree.&lt;br /&gt;&lt;br /&gt;To create a JSON object in server side with Java. We can use the lib in "json.org". It provides a quick API to parse POJO and list etc. See the following example code:&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;&lt;blockquote&gt;public JSONObject toJSONObject() throws Exception {&lt;br /&gt;JSONObject json = new JSONObject();&lt;br /&gt;json.put("totalCount", totalCount);&lt;br /&gt;&lt;br /&gt;JSONArray jsonItems = new JSONArray();&lt;br /&gt;for (Iterator&lt;timesheetjson&gt; iter = results.iterator(); iter.hasNext();) {&lt;br /&gt;jsonItems.put(iter.next().toJSONObject());&lt;br /&gt;}&lt;br /&gt;json.put("results", jsonItems);&lt;br /&gt;&lt;br /&gt;return json;&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/timesheetjson&gt;&lt;/blockquote&gt;&lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;To parse JSON data from JS in serve side, please see the following example:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;JSONArray jsonArray = JsonUtil.getJsonArray(jsonString);&lt;br /&gt;// JsonUtil.getJsonArray(jsonString) just do this -&gt;&lt;br /&gt;//         jsonArray = new JSONArray(jsonString);&lt;br /&gt;&lt;br /&gt;// loop through - get from json and update&lt;br /&gt;for (int i = 0; i &lt; jsonArray.length(); i++) {     &lt;br /&gt;   JSONObject jsonObject = jsonArray.getJSONObject(i);     &lt;br /&gt;   String id = jsonObject.getString("id");       &lt;br /&gt;} &lt;/blockquote&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1390129786656697775?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1390129786656697775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1390129786656697775' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1390129786656697775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1390129786656697775'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/04/json-speed-up-ajax.html' title='JSON speed up Ajax'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-6761998862958114849</id><published>2007-04-28T10:00:00.000-04:00</published><updated>2007-06-08T13:17:34.061-04:00</updated><title type='text'>YUI extension</title><content type='html'>Jack Slocum launch YUI extension 1.0 recently in extjs.com. It provides a strong framework for Ajax project. YUI extension has the following interesting functions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Online Grid editor (really convenience one - JSON)&lt;/li&gt;&lt;li&gt;Dialogs (Message dialog, progress dialog etc)&lt;/li&gt;&lt;li&gt;Menu (drop menu)&lt;/li&gt;&lt;li&gt;Tree&lt;/li&gt;&lt;li&gt;Resizable&lt;/li&gt;&lt;li&gt;Layout&lt;/li&gt;&lt;/ul&gt;EXTJS.com is very well documented and follows great OO principles and &lt;span class="caps"&gt;GUI&lt;/span&gt; design patterns.  Furthermore, it provides really great example to show those functions. Although, the example is never enough for cover every cases.&lt;br /&gt;&lt;br /&gt;Here comes one of my examples:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_gx3yNfk96Ts/Rj8n1p6YgtI/AAAAAAAAACc/SdBwpWsXyFU/s1600-h/untitled2.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 589px; height: 239px;" src="http://bp3.blogger.com/_gx3yNfk96Ts/Rj8n1p6YgtI/AAAAAAAAACc/SdBwpWsXyFU/s400/untitled2.JPG" alt="" id="BLOGGER_PHOTO_ID_5061808308925006546" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-6761998862958114849?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/6761998862958114849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=6761998862958114849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/6761998862958114849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/6761998862958114849'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/04/yui-extension.html' title='YUI extension'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_gx3yNfk96Ts/Rj8n1p6YgtI/AAAAAAAAACc/SdBwpWsXyFU/s72-c/untitled2.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-8079652174038301333</id><published>2007-04-16T17:14:00.000-04:00</published><updated>2007-08-15T11:32:23.296-04:00</updated><title type='text'>Ajax Request Compare</title><content type='html'>&lt;span style=";font-family:arial;font-size:100%;"  &gt;Currently, there exists several non-commercial AJAX frameworks for request during the development of a dynamic call-center application.&lt;br /&gt;&lt;/span&gt;&lt;ul  style="font-family:arial;"&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Prototype&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Dojo&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Direct Web Remoting (DWR)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Yahoo! User Interface (YUI) Toolkit&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;EXT JS&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Google Web Toolkit (GWT)&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;span style="font-weight: bold;font-family:arial;font-size:100%;"  &gt;Prototype &lt;/span&gt;&lt;span style=";font-family:arial;font-size:100%;"  &gt;is one of the most popular AJAX frameworks around.&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;postMsg : function(url, actId) {&lt;br /&gt;  var myAjax = new Ajax.Request(url,{&lt;br /&gt;  method: 'post',&lt;br /&gt;  parameters: 'actId='+escape(actId),&lt;br /&gt;  onComplete:handlerResult&lt;br /&gt;});&lt;br /&gt;},&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;font-size:100%;"  &gt;Dojo &lt;/span&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family:arial;"&gt;is a popular, complete open source framework with broad support not only for Web widgets but also other important aspects of Web&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;application development such as interaction with backend systems.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;dojo.io.bind({&lt;br /&gt;  url: url,&lt;br /&gt;  method: "post",&lt;br /&gt;  content: {actId: "123456"},&lt;code&gt;&lt;br /&gt;  load: function(type, data, evt){/* callback code */ },&lt;br /&gt;  error: function(type, error){/* error handling callback */ },&lt;br /&gt;  mimetype: "text/plain"&lt;br /&gt;});&lt;br /&gt;&lt;/code&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;DWR &lt;/span&gt;&lt;span style="font-family:arial;"&gt;focus is making browser client/server interaction as simple and natural as possible.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;public class PhoneService {&lt;br /&gt; public String getCallerName(int callerNumber){...}&lt;br /&gt;}&lt;br /&gt;..script.. type="text/javascript" src="SVProvider/dwr/interface/PhoneService.js ..script..&lt;br /&gt;PhoneService.getCallerName(18003456700, processPBXResponse)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;YUI &lt;/span&gt;is an extremely rich, well documented, stable, and lush framework for AJAX-based development. YUI code is really professor feeling.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;var requestFromObject = YAHOO.util.Connect.asynRequest('post', uri ,&lt;br /&gt;                                                    callback , postData);&lt;br /&gt;var callback = {&lt;br /&gt;   success: handleSuccess&lt;br /&gt;   failure: handleFailure&lt;br /&gt;   argument: {callerName: "N/A"}&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Ext JS&lt;/span&gt;  is another very popular Ajax framework. It also provides a XHR wrapper allowing quickly and efficiently perform AJAX requests.&lt;br /&gt;&lt;pre class="source source-javascript"&gt;Ext.&lt;span class="me1"&gt;Ajax&lt;/span&gt;.&lt;span class="me1"&gt;request&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="br0"&gt;{&lt;/span&gt;&lt;br /&gt; url : &lt;span class="st0"&gt;'../listActivity.do'&lt;/span&gt; ,&lt;br /&gt; params : &lt;span class="br0"&gt;{&lt;/span&gt; action : &lt;span class="st0"&gt;'loadData'&lt;/span&gt; &lt;span class="br0"&gt;}&lt;/span&gt;,&lt;br /&gt; method: &lt;span class="st0"&gt;'GET'&lt;/span&gt;,&lt;br /&gt; success: &lt;span class="kw2"&gt;function&lt;/span&gt; &lt;span class="br0"&gt;(&lt;/span&gt; result, request &lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt;&lt;br /&gt;  Ext.&lt;span class="me1"&gt;MessageBox&lt;/span&gt;.&lt;span class="kw3"&gt;alert&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;'Success'&lt;/span&gt;, &lt;span class="st0"&gt;'Data return from the server: '&lt;/span&gt;+ result.&lt;span class="me1"&gt;responseText&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;br /&gt; &lt;span class="br0"&gt;}&lt;/span&gt;,&lt;br /&gt; failure: &lt;span class="kw2"&gt;function&lt;/span&gt; &lt;span class="br0"&gt;(&lt;/span&gt; result, request&lt;span class="br0"&gt;)&lt;/span&gt; &lt;span class="br0"&gt;{&lt;/span&gt;&lt;br /&gt;  Ext.&lt;span class="me1"&gt;MessageBox&lt;/span&gt;.&lt;span class="kw3"&gt;alert&lt;/span&gt;&lt;span class="br0"&gt;(&lt;/span&gt;&lt;span class="st0"&gt;'Failed'&lt;/span&gt;, &lt;span class="st0"&gt;'Successfully posted form: '&lt;/span&gt;+action.&lt;span class="me1"&gt;date&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;br /&gt; &lt;span class="br0"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="br0"&gt;}&lt;/span&gt;&lt;span class="br0"&gt;)&lt;/span&gt;;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-8079652174038301333?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/8079652174038301333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=8079652174038301333' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/8079652174038301333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/8079652174038301333'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/04/ajax-frameworks-compare.html' title='Ajax Request Compare'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-6973671856444010783</id><published>2007-04-02T10:10:00.000-04:00</published><updated>2007-04-03T16:11:14.202-04:00</updated><title type='text'>JSF, Spring, iBatis integrate</title><content type='html'>Recently I created an application with JSF, Spring and iBatis. It seems pretty easy to integrate them together. Following list the system environment:&lt;br /&gt;&lt;ul style="font-style: italic;"&gt;&lt;li&gt;Tomcat - 5.5.23&lt;/li&gt;&lt;li&gt;Java - 1.5&lt;/li&gt;&lt;li&gt;JSF - 1.2&lt;/li&gt;&lt;li&gt;Spring - 2.0.3&lt;/li&gt;&lt;li&gt;iBatis - 2.3.0&lt;/li&gt;&lt;li&gt;database - Oracle&lt;/li&gt;&lt;/ul&gt;The system includes 3 simple configure file: applicationContext.xml, face-config.xml and sql-config.xml.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_gx3yNfk96Ts/RhEUnWgMErI/AAAAAAAAABs/0jP5DVht9Zo/s1600-h/jsf_xml.JPG"&gt;&lt;img style="cursor: pointer; width: 94px; height: 69px;" src="http://bp0.blogger.com/_gx3yNfk96Ts/RhEUnWgMErI/AAAAAAAAABs/0jP5DVht9Zo/s400/jsf_xml.JPG" alt="" id="BLOGGER_PHOTO_ID_5048839323547079346" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_gx3yNfk96Ts/RhETdGgMEqI/AAAAAAAAABk/P7UpoCG3XTk/s1600-h/spring_xml.JPG"&gt;&lt;img style="cursor: pointer; width: 96px; height: 69px;" src="http://bp3.blogger.com/_gx3yNfk96Ts/RhETdGgMEqI/AAAAAAAAABk/P7UpoCG3XTk/s400/spring_xml.JPG" alt="" id="BLOGGER_PHOTO_ID_5048838047941792418" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_gx3yNfk96Ts/RhEVi2gMEsI/AAAAAAAAAB0/UP7UVYvoZ5c/s1600-h/ibatis_xml.JPG"&gt;&lt;img style="cursor: pointer; width: 122px; height: 69px;" src="http://bp2.blogger.com/_gx3yNfk96Ts/RhEVi2gMEsI/AAAAAAAAAB0/UP7UVYvoZ5c/s400/ibatis_xml.JPG" alt="" id="BLOGGER_PHOTO_ID_5048840345749295810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;JSF have the following different features:&lt;strong&gt;&lt;/strong&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;span style="font-weight: normal; font-style: italic;"&gt;Swing-like object-oriented Web application development&lt;/span&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong style="font-weight: normal; font-style: italic;"&gt;Backing-bean management&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong style="font-weight: normal; font-style: italic;"&gt;Extensible UI component model&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong style="font-weight: normal; font-style: italic;"&gt;Flexible rendering model&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;span style="font-weight: normal; font-style: italic;"&gt;Extensible conversion and validation model&lt;/span&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;However, one JSF thing that I really do not like is its huge configure file. For a big project, it huge configure file will make maintanance pretty hard.&lt;br /&gt;&lt;br /&gt;A serviceLocator class is created in system to glue the JSF with Spring.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_gx3yNfk96Ts/RhEZj2gMEtI/AAAAAAAAAB8/hGDKxyLFxWU/s1600-h/serviceLocate.JPG"&gt;&lt;img style="cursor: pointer; width: 64px; height: 59px;" src="http://bp2.blogger.com/_gx3yNfk96Ts/RhEZj2gMEtI/AAAAAAAAAB8/hGDKxyLFxWU/s200/serviceLocate.JPG" alt="" id="BLOGGER_PHOTO_ID_5048844760975676114" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_gx3yNfk96Ts/RhEaNGgMEuI/AAAAAAAAACE/Ejx8SkPV3wo/s1600-h/web.JPG"&gt;&lt;img style="cursor: pointer; width: 82px; height: 59px;" src="http://bp3.blogger.com/_gx3yNfk96Ts/RhEaNGgMEuI/AAAAAAAAACE/Ejx8SkPV3wo/s200/web.JPG" alt="" id="BLOGGER_PHOTO_ID_5048845469645279970" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_gx3yNfk96Ts/RhEdpmgMEvI/AAAAAAAAACM/DQWgKUVMUDc/s1600-h/ibatis-exa.bmp"&gt;&lt;img style="cursor: pointer; width: 81px; height: 59px;" src="http://bp1.blogger.com/_gx3yNfk96Ts/RhEdpmgMEvI/AAAAAAAAACM/DQWgKUVMUDc/s200/ibatis-exa.bmp" alt="" id="BLOGGER_PHOTO_ID_5048849257806435058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Like other persistence layers, iBATIS strives to ease the development of data-driven applications by abstracting the low-level details involved in database communication, as well as providing higher-level ORM capabilities. iBatis SQL Maps is a straightforward data access tool, working at the SQL level like JDBC code, but externalizing SQL statements and their result and parameter mappings into an XML file. Above figure shows the simple example for iBatis.&lt;br /&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-6973671856444010783?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/6973671856444010783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=6973671856444010783' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/6973671856444010783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/6973671856444010783'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/04/jsf-spring-ibatis-integrate.html' title='JSF, Spring, iBatis integrate'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_gx3yNfk96Ts/RhEUnWgMErI/AAAAAAAAABs/0jP5DVht9Zo/s72-c/jsf_xml.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-1969876639006159179</id><published>2007-03-01T15:20:00.000-05:00</published><updated>2007-03-01T15:32:12.528-05:00</updated><title type='text'>Open JMS with Tomcat</title><content type='html'>In a loosely coupled and asynchronous communication, an application sends a message, and then continues program execution without waiting for a response. The sending program might not even know where or what the recipient is, because the communication between software components takes place via messaging. The Java Messaging Service (JMS) is the only messaging API supported by J2EE.&lt;br /&gt;&lt;br /&gt;OpenJMS, a SourceForge project, is a free open source implementation of Sun Microsystems' JMS API specification.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-1969876639006159179?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/1969876639006159179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=1969876639006159179' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1969876639006159179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/1969876639006159179'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/03/open-jms-with-tomcat.html' title='Open JMS with Tomcat'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-7435977762099930500</id><published>2007-02-06T11:10:00.000-05:00</published><updated>2007-02-06T11:27:45.163-05:00</updated><title type='text'>iBATIS vs Hibernate</title><content type='html'>&lt;span style="font-weight: bold;font-family:georgia;" &gt;iBATIS &lt;/span&gt;&lt;span style="font-family:georgia;"&gt;works well when you need to integrate with an existing database.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:georgia;" &gt;Hibernate &lt;/span&gt;&lt;span style="font-family:georgia;"&gt;works well when you control the data model.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:georgia;"&gt;iBATIS maps Java Objects to the results of SQL Queries, whereas Hibernate maps Java Objects directly to database tables, traditional Object-Relational Mapping. The benefits of Hibernate are that it automatically generates all the SQL for your and the cache invalidation can be more fine grained. iBATIS is more flexible especially if you are a strong SQL query writer. You have control over exactly how the SQL queries are written.&lt;br /&gt;&lt;br /&gt;Compared with Hibernate, iBATIS is more flexible, has a shorter learning curve, but can take more time to develop and maintain, since you have to write all your queries and if your object model changes you have to go through all your queries and make sure to make all the necessary changes to reflect the changes in your object model.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-7435977762099930500?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/7435977762099930500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=7435977762099930500' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7435977762099930500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7435977762099930500'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/02/ibatis-vs-hibernate.html' title='iBATIS vs Hibernate'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-7118788499051861275</id><published>2007-01-30T13:40:00.000-05:00</published><updated>2007-01-30T14:07:22.565-05:00</updated><title type='text'>DWR integrate with Spring</title><content type='html'>DWR is a Java open source library which allows you to write Ajax web sites.&lt;br /&gt;&lt;p&gt;DWR consists of two main parts:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_gx3yNfk96Ts/Rb-XIEA4zOI/AAAAAAAAAAg/ANQbu5radQQ/s1600-h/howitworks.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp1.blogger.com/_gx3yNfk96Ts/Rb-XIEA4zOI/AAAAAAAAAAg/ANQbu5radQQ/s320/howitworks.png" alt="" id="BLOGGER_PHOTO_ID_5025901873940974818" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;ul&gt; &lt;li&gt;A Java Servlet running on the server that processes requests and sends responses back to the browser.&lt;/li&gt;&lt;li&gt;JavaScript running in the browser that sends requests and can dynamically update the webpage.&lt;/li&gt; &lt;/ul&gt; &lt;span style="font-weight: bold;"&gt;Why DWR: &lt;/span&gt;&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;mostly used Ajax framework&lt;/li&gt;   &lt;li&gt;integrate best with Spring&lt;/li&gt;   &lt;li&gt;RPC style Ajax&lt;/li&gt;   &lt;li&gt;Java &lt;--&gt; Javascript marshalling (using Javascript objects)&lt;/li&gt;   &lt;li&gt;Support most browser&lt;/li&gt; &lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-7118788499051861275?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/7118788499051861275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=7118788499051861275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7118788499051861275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/7118788499051861275'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/01/dwr-integrate-with-spring.html' title='DWR integrate with Spring'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_gx3yNfk96Ts/Rb-XIEA4zOI/AAAAAAAAAAg/ANQbu5radQQ/s72-c/howitworks.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-116811153728724767</id><published>2007-01-06T14:25:00.000-05:00</published><updated>2007-01-30T14:28:13.311-05:00</updated><title type='text'>Yahoo YUI Calendar</title><content type='html'>Recently I start to look Yahoo YUI for rich UI. One feature is about Calendar. In general, YUI works pretty well with my application. However, one bug related to IE took me 2 days to figure it out.&lt;br /&gt;&lt;br /&gt;When I click any date in Calendar. It subscribe to YUI render:&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;YAHOO.example.calendar.cal1.selectEvent.subscribe(mySelectDate, YAHOO.example.calendar.cal1, true);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;YAHOO.example.calendar.cal1.addRenderer(txtDate1.value, YAHOO.example.calendar.cal1.renderCellStyleHighlight2);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;YAHOO.example.calendar.cal1.render();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:100%;"&gt;In my application, I need send new request to the server and get result for this specific date. It works well in Firefox, however, it does not always work in IE6. After dig for a while, there exist this code in YUI calendar.js:&lt;br /&gt;&lt;pre&gt;YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell)&lt;br /&gt;Exist: javascript:void(null) in href&lt;/pre&gt;    &lt;/span&gt;IE does not pass &lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-size:100%;"&gt;javascript:void(null) in href.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;code&gt;href="javascript: ", onclick="javascript:"&lt;/code&gt; There is no such thing as a JavaScript protocol on the web. Links use protocols to connect documents.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;span style="font-size:100%;"&gt;&lt;pre&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_gx3yNfk96Ts/Rb-bEkA4zQI/AAAAAAAAAA0/cMOGHy5f0n0/s1600-h/calendar.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_gx3yNfk96Ts/Rb-bEkA4zQI/AAAAAAAAAA0/cMOGHy5f0n0/s400/calendar.JPG" alt="" id="BLOGGER_PHOTO_ID_5025906211857943810" border="0" /&gt;&lt;/a&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-116811153728724767?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/116811153728724767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=116811153728724767' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116811153728724767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116811153728724767'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/01/yahoo-yui-calendar-and-tree.html' title='Yahoo YUI Calendar'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_gx3yNfk96Ts/Rb-bEkA4zQI/AAAAAAAAAA0/cMOGHy5f0n0/s72-c/calendar.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-116777488441159313</id><published>2007-01-02T16:54:00.000-05:00</published><updated>2007-01-03T11:10:50.500-05:00</updated><title type='text'>Authentication and authorization - Acegi and More</title><content type='html'>Most of our web application are based on the form-based authorization and authentication - role based access control. Form-based authentication is the most popular web authentication mechanism in use. It provides us with the greatest control over the look and fell of the “login screen”.&lt;br /&gt;&lt;br /&gt;Acegi provides a quick/simple/good solution for this. However, acegi also have some limitation:&lt;br /&gt;&lt;br /&gt;1: Authentication&lt;br /&gt;&lt;br /&gt;Acegi uses AuthenticationProcessingFilter. The AuthenticationProcessingFilter handles the Authentication Request Check (“logging into the application”). It uses the AuthenticationManager to do its work. One dsiadvantage is that we need create our login table based on the Acegi's wishes. And we also need access DB directly using SQL code.&lt;br /&gt;&lt;br /&gt;2: Authorization&lt;br /&gt;&lt;br /&gt;Acegi is based on the URL authorization. Secure URLs by role with regular expressions or ant-style pattern. First, role can not be added dynamically. Some actions (view and edit) use the same URLs, this bring problem for authorization.&lt;br /&gt;&lt;br /&gt;To fix the above problem, we can build self simple security system.&lt;br /&gt;&lt;br /&gt;Following list the tables relationship:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger/3049/1688/1600/823064/highArchitectur.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/x/blogger/3049/1688/400/45539/highArchitectur.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For each customer, it can create its own role and assign account to this role. For each service, there includes many features. And for each feature, it can be different privilege (verb: CRUD List etc). We can assign role to different privilege.&lt;br /&gt;&lt;br /&gt;In each button/link field, we need add a parameter "privilegeCode", for example: privilegeCode=editAccount. We just need write a filter, this filter will check privilegeCode and login user privilege. If login user has this privilege, continue. Otherwise, permission deny.&lt;br /&gt;&lt;br /&gt;Simple, easy and quick to fix the authorization issue in Acegi&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-116777488441159313?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/116777488441159313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=116777488441159313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116777488441159313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116777488441159313'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2007/01/authentication-and-authorization-acegi.html' title='Authentication and authorization - Acegi and More'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-116733728703342450</id><published>2006-12-28T15:21:00.000-05:00</published><updated>2006-12-28T16:11:36.136-05:00</updated><title type='text'>Acegi 1.0.3 - security framework</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Acegi &lt;/span&gt;is an open source security framework that allows us to keep business logic free from security code. Acegi Security provides comprehensive security services for J2EE-based enterprise software applications.&lt;br /&gt;&lt;br /&gt;Recently we decided to move security part from SecurityFilter to Acegi. It took me 3 days to finish switch. Seems Acegi integrate to our current system pretty well.&lt;br /&gt;&lt;br /&gt;Currently our environment is: Tomcat5.5, Spring2, mySQL5, Hibernate3, Java1.5. Following list some simple steps:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;web.xml&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger/3049/1688/1600/26000/acegi1.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/x/blogger/3049/1688/400/765051/acegi1.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;security-acegi-security.xml&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;filterInvocationDefinitionSource &lt;/span&gt;- httpSessionContextIntegrationFilter, authenticationProcessingFilter, exceptionTranslationFilter, filterSecurityInterceptor&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger/3049/1688/1600/767918/acegi2.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/x/blogger/3049/1688/400/993407/acegi2.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-116733728703342450?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/116733728703342450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=116733728703342450' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116733728703342450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116733728703342450'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/12/acegi-103-security-framework.html' title='Acegi 1.0.3 - security framework'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-116515496298561595</id><published>2006-12-03T09:09:00.000-05:00</published><updated>2006-12-09T15:29:01.680-05:00</updated><title type='text'>BIRT v.s. JasperReport</title><content type='html'>&lt;span style="font-weight:bold;"&gt;BIRT&lt;/span&gt; is an Eclipse-based open source reporting system for web applications, especially those based on Java and J2EE.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Jasper Report&lt;/span&gt; is a powerful open source Java reporting tool that has the ability to deliver rich content onto the screen, to the printer or into PDF, HTML, XLS, CSV and XML files.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;JasperReports&lt;/span&gt;&lt;br /&gt;- Easiest integrate to application and flexible from a developers standpoint.&lt;br /&gt;- Supports a large number of export formats.&lt;br /&gt;- Do not have free report designer tool. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Eclipse BIRT&lt;/span&gt;&lt;br /&gt;- Excellent report designer and charting support. I can get create reports in a matter of minutes with great ease.&lt;br /&gt;- Great support for reports with multiple datasources. However, it is also tedious to maintain extra datasource just for report.&lt;br /&gt;- Harder to integrate into currently application.&lt;br /&gt;&lt;br /&gt;Currently, when I deploy report to BIRT under tomcat environment. I need deploy it to a separate application. This application is totally used to handle all reports. For small application, it makes things complex and I am strong worry about its security. I also try to integrate BIRT report to my application, however it makes my WAR file pretty big (20M more). &lt;br /&gt;&lt;br /&gt;BIRT is still a relatively young project and there lots more work that needs to be done. Maybe I need wait for next BIRT release. &lt;br /&gt;&lt;br /&gt;Because my application is using &lt;span style="font-weight:bold;"&gt;spring &lt;/span&gt; framework. It does support a view to pretty easy integrate my JasperReport. This allow me to focus on my report design instead of other stuff. At the same time, code is pretty small and clean. So I decide to choose JasperReport as my report engine temporary.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pro Spring&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;/span&gt; has a good example shows how to integrate JasperReport into your application.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger/3049/1688/1600/63156/view.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/x/blogger/3049/1688/400/170978/view.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The order of this configure file is pretty important. First, it should be general viewResolver, then comes japserReportViewResolver.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-116515496298561595?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/116515496298561595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=116515496298561595' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116515496298561595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116515496298561595'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/12/birt-vs-jasperreport.html' title='BIRT v.s. JasperReport'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-116137794741048524</id><published>2006-10-20T16:59:00.000-04:00</published><updated>2007-04-23T09:40:01.837-04:00</updated><title type='text'>J2EE without EJB feature lists</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Tomcat &lt;/span&gt;- Application Server&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Spring 2.0&lt;/span&gt; - J2EE framework&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hibernate/iBatis&lt;/span&gt; - ORM&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;JSF/Spring/WebWork&lt;/span&gt; - Multi-Action Web Framework&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;JSP &lt;/span&gt;- View Template&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Dojo, YUI/Extension, Rico, Prototype&lt;/span&gt; - Rich Client Widgets&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Acegi&lt;/span&gt; - Authentication and authorization. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;SiteMesh&lt;/span&gt; - Web page layout and decoration framework. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Quartz&lt;/span&gt; - Enterprise job scheduler. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Log4j&lt;/span&gt; - Logging Tool&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;OSCache&lt;/span&gt; - Simple Cache and Web Cache solution&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Jasper Report&lt;/span&gt; - Report Engine&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Lucene&lt;/span&gt; - Search engine&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ExtremeTable&lt;/span&gt; - JSP Table Tag Libraries. &lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Junit&lt;/span&gt; - unit test&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-116137794741048524?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/116137794741048524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=116137794741048524' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116137794741048524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/116137794741048524'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/10/j2ee-without-ejb-feature-lists.html' title='J2EE without EJB feature lists'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-115834281699026907</id><published>2006-09-15T13:53:00.000-04:00</published><updated>2006-09-15T14:03:44.730-04:00</updated><title type='text'>AOP and OOP</title><content type='html'>&lt;span style="font-weight:bold;"&gt;AOP&lt;/span&gt; - Aspect Oriented Programming provides us the ability to interpose customer behavor before/after invocations on any object. This enable us to address crosscutting enterprise concerns that apply to multiple object.&lt;br /&gt;&lt;br /&gt;OOP works well in general, AOP is a complementing rather than competing with OOP. For example, if we have to apply the same transactional behavior to multiple objects and methods, we need cut/paste the same code into each method. AOP give us a better way to pack such concerns into &lt;span style="font-weight:bold;"&gt;ASPECTS&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-115834281699026907?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/115834281699026907/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=115834281699026907' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/115834281699026907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/115834281699026907'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/09/aop-and-oop.html' title='AOP and OOP'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-115204231119264884</id><published>2006-07-04T15:45:00.000-04:00</published><updated>2006-07-05T09:47:50.370-04:00</updated><title type='text'>How to bind and validate in MultiActionController</title><content type='html'>In Spring framework, it provides several controller in MVC model. Personaly, I like the &lt;span style="font-weight: bold;"&gt;MultiActionController &lt;/span&gt; best. And I do not like &lt;span style="font-weight: bold;"&gt;SimpleFormController&lt;/span&gt; because it only one "onSubmit" method. For WEB page, I do not think any page just have one button, i.e: "Save" or "Update". However, SimpleFormController have strong validator ability. But I still hate lots of configure in SimpleFormController.&lt;br /&gt;&lt;br /&gt;In Spring MultiActionController, it already provides &lt;span style="font-style:italic;"&gt;bind &lt;/span&gt;method, however, this method just throws Exception when it find the invalidate error message. To catch this error, we need write a new method to override it.&lt;br /&gt;&lt;br /&gt;The goal is to use both MultiActionController and SimpleFormController &lt;br /&gt;&lt;br /&gt;Solution: bind and validate in MultiActionController.&lt;br /&gt;&lt;br /&gt;In XML, you can write your MultiActionController as normal define.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3049/1688/1600/xml.1.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/3049/1688/400/xml.0.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now we need bind the form and validator it.&lt;br /&gt;&lt;br /&gt;I will use a save action as example:&lt;br /&gt;&lt;br /&gt;First create a bindObject method in your BaseContoller (extends MultiActionController)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;protected BindException bindObject(HttpServletRequest request,&lt;br /&gt;   Object command, Validator validator) throws Exception {&lt;br /&gt;    preBind(request, command);&lt;br /&gt;    ServletRequestDataBinder binder = createBinder(request, command);&lt;br /&gt;    binder.bind(request);&lt;br /&gt;&lt;br /&gt;    BindException errors = new BindException(command,&lt;br /&gt;    getCommandName(command));&lt;br /&gt;    if (validator.supports(command.getClass())) {&lt;br /&gt;       ValidationUtils.invokeValidator(validator, command, errors);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return errors;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now in the save action, you can use this method as normal.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public ModelAndView save(HttpServletRequest request,&lt;br /&gt;   HttpServletResponse response, PhoneInfo command) throws Exception {&lt;br /&gt;  ModelAndView addPhoneView = new ModelAndView(LIST_VIEW, "phones",&lt;br /&gt;    phones);&lt;br /&gt;  addPhoneView.addObject("phoneInfo", command);&lt;br /&gt;&lt;br /&gt;  // add validator and call bindobject to get the result&lt;br /&gt;  BindException errors = super.bindObject(request, command, new PhoneInfoValidator());&lt;br /&gt;  if (errors.hasErrors()) {&lt;br /&gt;   addPhoneView.addAllObjects(errors.getModel());&lt;br /&gt;   return addPhoneView;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  // otherwise --- save this object...&lt;br /&gt;  return addPhoneView;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this way, I can easy to fix my problem when I use MultiActionController. I can bind and validate any object as I like.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-115204231119264884?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/115204231119264884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=115204231119264884' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/115204231119264884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/115204231119264884'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/07/how-to-bind-and-validate-in.html' title='How to bind and validate in MultiActionController'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-115170017811996819</id><published>2006-06-30T16:42:00.000-04:00</published><updated>2006-06-30T16:42:58.243-04:00</updated><title type='text'>Hibernate ?</title><content type='html'>Hibernate is a good ORM tool. However, there also have some issue in here:&lt;br /&gt;&lt;br /&gt;1: Criteria API, QueryObject are not as strong as sql language. &lt;br /&gt;&lt;br /&gt;2: Lazy load or not... only define one time in XML&lt;br /&gt;&lt;br /&gt;3: POJO ? too much use ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-115170017811996819?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/115170017811996819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=115170017811996819' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/115170017811996819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/115170017811996819'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/06/hibernate.html' title='Hibernate ?'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-114927620048102283</id><published>2006-06-02T15:23:00.000-04:00</published><updated>2006-06-02T15:23:20.546-04:00</updated><title type='text'>RIM Blackberry and J2ME</title><content type='html'>Programming the BlackBerry With J2ME&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-114927620048102283?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/114927620048102283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=114927620048102283' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114927620048102283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114927620048102283'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/06/rim-blackberry-and-j2me.html' title='RIM Blackberry and J2ME'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-114797079317283469</id><published>2006-05-18T12:46:00.000-04:00</published><updated>2006-07-04T11:30:53.610-04:00</updated><title type='text'>Google Ajax</title><content type='html'>http://code.google.com/webtoolkit/&lt;br /&gt;&lt;br /&gt;Some good tool for Ajax&lt;br /&gt;&lt;br /&gt;prototype.js is a JavaScript library written by Sam Stephenson. This amazingly well thought and well written piece of standards-compliant code takes a lot of the burden associated with creating rich, highly interactive web pages that characterize the Web 2.0 off your back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-114797079317283469?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/114797079317283469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=114797079317283469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114797079317283469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114797079317283469'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/05/google-ajax.html' title='Google Ajax'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-114553613673709502</id><published>2006-04-20T08:28:00.000-04:00</published><updated>2006-07-04T11:27:23.056-04:00</updated><title type='text'>Spring lightweight?</title><content type='html'>Today, indeed Spring cannot be considered as “lightweight” when comparing it to other light solutions out there. this is mainly due to the vast amount of solutions it provides in almost all aspects of enterprise development. I guess “lightweight”, when taking it by its literal meaning, is somewhat inappropriate nowadays… perhaps “simple and comprehensive” is more suitable to describe Spring. But this term (I think) is not interpreted by its literal meaning. I think it’s still associated with its original meaning when it was compared with the heavy EJB containers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-114553613673709502?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/114553613673709502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=114553613673709502' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114553613673709502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114553613673709502'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/04/spring-lightweight.html' title='Spring lightweight?'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-114064296195925509</id><published>2006-02-22T16:16:00.000-05:00</published><updated>2006-02-22T16:16:02.036-05:00</updated><title type='text'>Jasper and Open Reports</title><content type='html'>In the end we compared Crystal reports with Jasper Reports, and Jasper was picked. Jasper is not only free, but also is proven in the Java world, and has a lot of users. It is customizable, since its Java and open source, and has support for using Collections or Lists of Business Objects, such as those populated via Hibernate.&lt;br /&gt;&lt;br /&gt;Once Jasper was chosen, I tested several GUI’s to help build the reports instead of editing them strictly in their native XML. JasperAssistant was found to be the best of all of them, and integrates seamlessly with Eclipse. If you are an Eclipse fan as I am, then you’ll love using JasperAssistant. It even allows you to preview the report against your database right in Eclipse.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-114064296195925509?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/114064296195925509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=114064296195925509' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114064296195925509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/114064296195925509'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/02/jasper-and-open-reports.html' title='Jasper and Open Reports'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-113742674229945875</id><published>2006-01-16T10:52:00.000-05:00</published><updated>2006-01-16T10:52:22.336-05:00</updated><title type='text'>Connecting Apache's Web Server to Multiple Instances of Tomcat</title><content type='html'>Connecting Apache's Web Server to Multiple Instances of Tomcat&lt;br /&gt;&lt;br /&gt;http://www.linuxjournal.com/node/8561/print&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-113742674229945875?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/113742674229945875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=113742674229945875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113742674229945875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113742674229945875'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/01/connecting-apaches-web-server-to.html' title='Connecting Apache&apos;s Web Server to Multiple Instances of Tomcat'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-113707418570635740</id><published>2006-01-12T08:56:00.000-05:00</published><updated>2006-01-12T08:56:26.133-05:00</updated><title type='text'>Quick Reference Card</title><content type='html'>http://www.digilife.be/quickreferences/quickrefs.htm&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-113707418570635740?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/113707418570635740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=113707418570635740' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113707418570635740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113707418570635740'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/01/quick-reference-card.html' title='Quick Reference Card'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-113701596273816119</id><published>2006-01-11T16:46:00.000-05:00</published><updated>2006-01-11T16:53:54.733-05:00</updated><title type='text'>Voice Application with J2EE</title><content type='html'>I'm convinced that J2EE lightweight container architecture is the right way to go for the majority of voice applications. However, there needs to be some tweaks in the way the UI tier utilizes it, compared to what we're used to seeing with HTML-based applications.&lt;br /&gt;&lt;br /&gt;The standard platform architecture for Voice Application is to have 100 or so browser instances sitting on a server. The browser is not located on the client, because the client is a POT (Plain Old Telephone). The caller dials up a computer with a Dialogic or NMS card, or a SIP gateway, and the call is routed to one of the browser instances running on a server. This may be the same server that's running the app server, or it may just be on the same LAN.&lt;br /&gt;&lt;br /&gt;So now the browser cache becomes much, much more important. If I have a few thousand phone calls coming in every hour to those 100 browsers, and they're all running the same application, the absolute worst thing I can do is a lot of dynamic page rendering. That would involve parsing the JSP into VoiceXML, and parsing the VoiceXML into runnable code, on every request.&lt;br /&gt;&lt;br /&gt;So, component libraries like Tapestry or JSF are out. MVC frameworks like struts could be okay, as long as they're redirecting to static VoiceXML pages, instead of forwarding to JSPs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-113701596273816119?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/113701596273816119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=113701596273816119' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113701596273816119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113701596273816119'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/01/voice-application-with-j2ee.html' title='Voice Application with J2EE'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-113699379295185800</id><published>2006-01-11T10:36:00.000-05:00</published><updated>2006-01-11T10:36:33.210-05:00</updated><title type='text'>Reusable Dialog Component (RDC) for voice application</title><content type='html'>A Reusable Dialog Component (RDC) is basically a JSP 2.0 tag, which generates VoiceXML at runtime. RDCs are part of the RDC Tag Library open source Jakarta project. Version 1.0 of the RDC Taglib was released in July 2005. The RDC Taglib projects implifies the development of server-side code in order to generate Voice XML. The RDC Taglib project includes a set of RDCs, which are a collection of JSP 2.0 tags that assist in the development of Voice applications. The RDC tags generate VoiceXML at runtime, which can execute on any VoiceXML 2.0 compliant platform. The RDC Taglib also provides a framework for implementing additional RDCs. The framework helps in orchestrating each individual RDC making sure the user data is collected, verified, and canonicalized. The collection of RDCs included in the Taglib project is made up of both, atomic and composite RDCs. Atomic RDCs collect a single piece of information from the user. For example, &lt;span class="pf"&gt;date, time&lt;/span&gt;, or &lt;span class="pf"&gt;zipCode&lt;/span&gt; are atomic RDCs. Composite RDCs collect multiple pieces of information from a user. These are usually done by using atomic RDCs or aggregating a composite with other atomic RDCs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-113699379295185800?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/113699379295185800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=113699379295185800' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113699379295185800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113699379295185800'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2006/01/reusable-dialog-component-rdc-for.html' title='Reusable Dialog Component (RDC) for voice application'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-113354112596349532</id><published>2005-12-02T11:32:00.000-05:00</published><updated>2005-12-05T13:32:41.293-05:00</updated><title type='text'>File transfer between .NET and J2EE</title><content type='html'>Web service seems a good solution for file transfer between .NET and J2EE platform. However, .NET environment is only support DIME format for attachment.&lt;br /&gt;&lt;br /&gt;Direct Internet Message Encapsulation (DIME) is a new specification for sending and receiving SOAP messages along with additional attachments, like binary files, XML fragments, and even other SOAP messages, using standard transport protocols like HTTP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-113354112596349532?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/113354112596349532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=113354112596349532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113354112596349532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113354112596349532'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/12/file-transfer-between-net-and-j2ee.html' title='File transfer between .NET and J2EE'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-113168096288650872</id><published>2005-11-10T22:46:00.000-05:00</published><updated>2005-11-10T22:50:53.333-05:00</updated><title type='text'>Session and sessionContext</title><content type='html'>&lt;p&gt;In the 2.0 version of the Servlet API, you could get hold of a HttpSessionContext object by calling getSessionContext() off an HttpSession. For example:&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;HttpSessionContext sessionContext = theSession.getSessionContext();&lt;/p&gt; &lt;p&gt;Although HttpSessionContext seems like a useful class for getting easy access to all client sessions, it appears Sun thought access to such private data was &lt;i&gt;&lt;b&gt;too easy&lt;/b&gt;&lt;/i&gt;. In version 2.1 of the Servlet API the HttpSessionContext class was deprecated for security reasons by Sun, with no plans for a replacement. In short, steer clear of HttpSessionContext!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-113168096288650872?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/113168096288650872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=113168096288650872' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113168096288650872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/113168096288650872'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/11/session-and-sessioncontext.html' title='Session and sessionContext'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112978093548784217</id><published>2005-10-19T23:55:00.000-04:00</published><updated>2005-10-20T00:05:35.010-04:00</updated><title type='text'>javap - The Java Class File Disassembler</title><content type='html'>Please note, it is a disassembler not the decomplier ;). What you can do with the disassembler? You may say.. yeah.. disassembler.. but I don't care about how the class file runs in byte codes.&lt;br /&gt;The reality is that if you want to do a performance tuning on your applications and your intension is to optimize it, then learning how to use javap is useful.&lt;br /&gt;&lt;br /&gt;It works much alike "java" command, with the "-c" option, it allows you to see in byte codes how the logical sequence of each methods called by the applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112978093548784217?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112978093548784217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112978093548784217' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112978093548784217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112978093548784217'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/javap-java-class-file-disassembler.html' title='javap - The Java Class File Disassembler'/><author><name>swnotes</name><uri>http://www.blogger.com/profile/14184554878663421150</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112974140928592049</id><published>2005-10-19T13:02:00.000-04:00</published><updated>2005-10-19T13:04:37.163-04:00</updated><title type='text'>print.google.com</title><content type='html'>Come here to view any book. You will be happy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112974140928592049?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112974140928592049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112974140928592049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112974140928592049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112974140928592049'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/printgooglecom.html' title='print.google.com'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112960115565465131</id><published>2005-10-17T22:05:00.000-04:00</published><updated>2005-10-18T11:22:27.860-04:00</updated><title type='text'>Lucene - text search engine</title><content type='html'>Apache Lucene is a high-performance, full-featured text search engine Information Retrieval (IR) library written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform. It lets you add indexing and searching capabilities to your applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112960115565465131?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112960115565465131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112960115565465131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112960115565465131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112960115565465131'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/lucene-text-search-engine.html' title='Lucene - text search engine'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112958208317754053</id><published>2005-10-17T16:02:00.000-04:00</published><updated>2005-10-17T16:48:03.183-04:00</updated><title type='text'>Jar, not just a tool to compress and wrap classes</title><content type='html'>Jar has been wildly used in Java land to compress class files, packages etc. It enables you to bundle mutiple files into one archive file. To me jar is pretty much like the tar, the command, which has been used in Unix and Linux. See what you can do with jar? The syntax is almost as the same as tar.&lt;br /&gt;E.g. in Unix and Linux   tar -tvf something.tar   ( reading the content of the tar file without extracting it)&lt;br /&gt;Where fir Jar,   jar -tvf something.jar   ( pretty much the same thing as tar)&lt;br /&gt;Jar files are also readable by using winzip or winrar, the windows based compression software can open any jar file with no problem. It compress or extract the jar files just like it does to other zip formatted files.&lt;br /&gt;&lt;br /&gt;But, there are even more you can do with jar, you can validate your jar files with manifest so when some one modify the jar without your permission, you will know.&lt;br /&gt;&lt;br /&gt;Check this article out :&lt;br /&gt;http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112958208317754053?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112958208317754053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112958208317754053' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112958208317754053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112958208317754053'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/jar-not-just-tool-to-compress-and-wrap.html' title='Jar, not just a tool to compress and wrap classes'/><author><name>swnotes</name><uri>http://www.blogger.com/profile/14184554878663421150</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112899428603938573</id><published>2005-10-10T21:29:00.000-04:00</published><updated>2005-10-12T14:33:04.830-04:00</updated><title type='text'>Farm Pickup</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3049/1688/1600/Picture%20078.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/3049/1688/320/Picture%20078.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112899428603938573?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112899428603938573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112899428603938573' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112899428603938573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112899428603938573'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/farm-pickup.html' title='Farm Pickup'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112880339317659310</id><published>2005-10-08T16:27:00.000-04:00</published><updated>2005-10-08T16:29:53.176-04:00</updated><title type='text'>Quick Solution for Existing Web Application Security</title><content type='html'>&lt;p class="MsoNormal"&gt;Web applications are becoming more popular software for the customer. As web application go online, security parts need to be pay attention to. Problems arise when the application can not distinguish between legitimate and illegitimate requests coming from a browser.&lt;/p&gt;     &lt;p class="MsoNormal"&gt;Through a Web browser, I touch my account information. I also touch your account information. Web application server need to validate whether I have permission to touch your account information. However, server side form date validation is really time consuming and sometimes it is nearly impossible, especially for existing web application system. &lt;/p&gt;     &lt;p class="MsoNormal"&gt;In this paper, an DES two-ways encryption/decryption are introduced in the form data validate in the web application. &lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;  &lt;/p&gt; &lt;p class="MsoNormal"&gt;Using GET/POST, some sensitive data are display in the user HTML forms or URL. For example:&lt;/p&gt;     &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: Courier;"&gt;&lt;a href="http://www.yourdomain.com/accounts/editAccount.do?aId=5"&gt;http://www.yourdomain.com/accounts/editAccount.do?aId=5&lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;     &lt;p class="MsoNormal"&gt;Anyone can easily change the aId value and submit the changed URL to the server. One solution for this is check this user permission on the server side. Another way, we also can check whether client changed the aId, I means the aId I passed and the aId I receive. &lt;/p&gt;     &lt;p class="MsoNormal"&gt;To see whether client changes the sensitive data, the DES encrypting algorithm is used in the system. The example code is list at the end of this paper[1]:&lt;/p&gt;     &lt;p class="MsoNormal"&gt;For the above URL, I encrypted the sensitive data with the DES algorithm before passing it to the remote client. Now the client browser get the following URL:&lt;/p&gt;     &lt;p class="MsoNormal"&gt;&lt;span style="font-size: 10pt; font-family: Courier;"&gt;&lt;a href="http://www.yourdomain.com/accounts/editAccount.do?aId=SMsDoJFsmlc=5"&gt;http://www.yourdomain.com/accounts/editAccount.do?aId=SMsDoJFsmlc=5&lt;/a&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;     &lt;p class="MsoNormal"&gt;As above example, the encrypt result is “&lt;span style="font-size: 10pt; font-family: Courier;"&gt;SMsDoJFsmlc=&lt;/span&gt;”, the original value is “&lt;span style="font-size: 10pt;"&gt;5&lt;/span&gt;”. When the client submit this URL to the server side, I get the encrypted aId from the request, call the decrypt(String) and get the original value. &lt;/p&gt;     &lt;span style="font-size: 12pt; font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;Now suppose we change the aId as something else, this will make the decrypt result and original data value does not match. We know the client changed the value and just reject the client request.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112880339317659310?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112880339317659310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112880339317659310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112880339317659310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112880339317659310'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/quick-solution-for-existing-web.html' title='Quick Solution for Existing Web Application Security'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112862139661390215</id><published>2005-10-06T13:56:00.000-04:00</published><updated>2005-10-06T16:34:05.656-04:00</updated><title type='text'>Securing the application with SecurityFilter</title><content type='html'>Enterprise-level business applications need rigorous security regulations with varying roles; each role also requires its own set of access control lists. These roles become more important in Web-based applications, which are accessible to a wider audience. In most cases, application security must control access to each attribute that's visible on the screen.&lt;br /&gt;&lt;br /&gt;When access to web applications needs to be restricted to certain users and groups, Tomcat provides its realm implementations. A realm groups a collection of web resources together and puts a protection mechanism around them that requires users who wish to access them to authenticate themselves, and for Tomcat to check their authorization. However, tomcat does not did enough for real application. Here comes SecurityFilter which built on the top of tomcat.&lt;br /&gt;&lt;br /&gt;SecurityFilter is a Java Servlet Filter that mimics container managed security. It provides robust security and automatic authentication services for web applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112862139661390215?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112862139661390215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112862139661390215'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/securing-application-with.html' title='Securing the application with SecurityFilter'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112854356309537385</id><published>2005-10-05T15:57:00.000-04:00</published><updated>2005-10-05T16:19:23.100-04:00</updated><title type='text'>Unit Testing with JUnit</title><content type='html'>JUnit provides the following features:&lt;br /&gt;&lt;br /&gt;It provides an API that allows us to create a repeatable unit test with a clear pass/fail result.&lt;br /&gt;&lt;br /&gt;It includes tools for running our tests and presenting the results.&lt;br /&gt;&lt;br /&gt;It allows multiple tests to be grouped together to run in a batch.&lt;br /&gt;&lt;br /&gt;It is very lightweight and simple to use. It takes little time to learn how it works.&lt;br /&gt;&lt;br /&gt;It is extensible. It's the de facto unit testing framework for Java. There is a large community pf developers using it. Many free extensions are available to help us use it in specific situation. Plus, countless articles and books on the subject are avaibale.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112854356309537385?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112854356309537385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112854356309537385' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112854356309537385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112854356309537385'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/unit-testing-with-junit.html' title='Unit Testing with JUnit'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112854126270139228</id><published>2005-10-05T15:39:00.000-04:00</published><updated>2005-10-05T15:50:46.116-04:00</updated><title type='text'>Page Decorate with SiteMesh</title><content type='html'>SiteMesh is a web-page layout and decoration framework and web- application integration framework to aid in creating large sites consisting of many pages for which a consistent look/feel, navigation and layout scheme is required.&lt;br /&gt;&lt;br /&gt;SiteMesh intercepts requests to any static or dynamically generated HTML page requested through the web-server, parses the page, obtains properties and data from the content and generates an appropriate final page with modifications to the original. This is based upon the well-known GangOfFour Decorator design pattern.&lt;br /&gt;&lt;br /&gt;SiteMesh can also include entire HTML pages as a Panel within another page. This is similar to a Server-Side Include, except that the HTML document will be modified to create a visual window (using the document's Meta-data as an aid) within a page. Using this feature, Portal type web sites can be built very quickly and effectively. This is based upon the well-known GangOfFour Composite design pattern.&lt;br /&gt;&lt;br /&gt;SiteMesh is built using Java 2 with Servlet, JSP and XML technologies. This makes it ideal for use with J2EE applications, however it can be integrated with server-side web architectures that are not Java based such as CGI (Perl/Python/C/C++/etc), PHP, Cold Fusion, etc...&lt;br /&gt;&lt;br /&gt;SiteMesh is very extensible and is designed in a way in which it is easy to extend for custom needs.&lt;br /&gt;&lt;br /&gt;http://www.opensymphony.com/sitemesh/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112854126270139228?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112854126270139228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112854126270139228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112854126270139228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112854126270139228'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/page-decorate-with-sitemesh.html' title='Page Decorate with SiteMesh'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112854018886469350</id><published>2005-10-05T15:19:00.000-04:00</published><updated>2005-10-05T15:28:01.783-04:00</updated><title type='text'>Web Application Framework Compare</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Apache Struts framework&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Pros:&lt;/span&gt;&lt;br /&gt;The “Standard” - lots of Struts jobs&lt;br /&gt;Lots of information and examples&lt;br /&gt;HTML tag library is one of the best&lt;ul&gt;          &lt;/ul&gt;&lt;span style="font-style: italic;"&gt;Cons:&lt;/span&gt;&lt;br /&gt;ActionForms - they’re a pain&lt;br /&gt;Can’t unit test - StrutsTestCase only does integration&lt;br /&gt;Project has been rumored as “dead”&lt;ul&gt;          &lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Spring MVC&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Pros:&lt;/span&gt;&lt;br /&gt;Lifecyle for overriding binding, validation, etc.&lt;br /&gt;Integrates with many view options seamlessly: JSP/JSTL, Tiles, Velocity, FreeMarker, Excel, XSL, PDF&lt;br /&gt;Inversion of Control makes it easy to test&lt;ul&gt;          &lt;/ul&gt;&lt;span style="font-style: italic;"&gt;Cons:&lt;/span&gt;&lt;br /&gt;Configuration intensive - lots of XML&lt;br /&gt;Requires writing lots of code in JSPs&lt;br /&gt;Almost too flexible - no common parent Controller&lt;ul&gt;          &lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;WebWork&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Pros:&lt;/span&gt;&lt;br /&gt;Simple architecture - easy to extend&lt;br /&gt;Tag Library is easy to customize - backed by Velocity&lt;br /&gt;Interceptors are pretty slick&lt;ul&gt;          &lt;/ul&gt;&lt;span style="font-style: italic;"&gt;Cons:&lt;/span&gt;&lt;br /&gt;Small Community&lt;br /&gt;Documentation only recently written, few examples&lt;br /&gt;Client-side validation immature&lt;ul&gt;          &lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Java Server Faces&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Pros:&lt;/span&gt;&lt;br /&gt;J2EE Standard - lots of demand and jobs&lt;br /&gt;Fast and easy to develop with&lt;br /&gt;Rich Navigation framework&lt;ul&gt;          &lt;/ul&gt;&lt;span style="font-style: italic;"&gt;Cons:&lt;/span&gt;&lt;br /&gt;Tag soup for JSPs&lt;br /&gt;Immature technology - doesn’t come with everything&lt;br /&gt;No single source for implementation&lt;ul&gt;          &lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112854018886469350?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112854018886469350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112854018886469350' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112854018886469350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112854018886469350'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/web-application-framework-compare.html' title='Web Application Framework Compare'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17500411.post-112853936993942067</id><published>2005-10-05T15:08:00.000-04:00</published><updated>2005-10-05T15:09:29.940-04:00</updated><title type='text'>Why use Hibernate?</title><content type='html'>One of the most complicated and time-consuming tasks of developing an enterprise application is writing the code to store and load data from a database at the appropriate times. Hibernate is the right tool to remedy this.&lt;br /&gt;&lt;br /&gt;Hibernate is a powerful, ultra-high performance object/relational persistence and query service for Java. Hibernate lets you develop persistent classes following common Java idiom - including association, inheritance, polymorphism, composition, and the Java collections framework. Hibernate allows you to express queries in its own portable SQL extension (HQL), as well as in native SQL, or with Java-based Criteria and Example objects.&lt;br /&gt;&lt;br /&gt;Hibernate allows us mapping an object model to a relational schema, keeping object model and database schema in sync. It also makes us easy persisting and retrieving an object from database.&lt;br /&gt;&lt;br /&gt;www.hibernate.org&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17500411-112853936993942067?l=ffzhuang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ffzhuang.blogspot.com/feeds/112853936993942067/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17500411&amp;postID=112853936993942067' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112853936993942067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17500411/posts/default/112853936993942067'/><link rel='alternate' type='text/html' href='http://ffzhuang.blogspot.com/2005/10/why-use-hibernate.html' title='Why use Hibernate?'/><author><name>ffzhuang</name><uri>http://www.blogger.com/profile/05641153781311806226</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
