﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-闲人野居-随笔分类-web view技术</title><link>http://www.blogjava.net/zyl/category/14520.html</link><description>好好学习，天天向上</description><language>zh-cn</language><lastBuildDate>Wed, 02 Jan 2008 17:40:16 GMT</lastBuildDate><pubDate>Wed, 02 Jan 2008 17:40:16 GMT</pubDate><ttl>60</ttl><item><title>关于服务端生成js的构思</title><link>http://www.blogjava.net/zyl/archive/2008/01/02/extjs.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Wed, 02 Jan 2008 10:36:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2008/01/02/extjs.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/172279.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2008/01/02/extjs.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/172279.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/172279.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 研究了ext很久了，一直想为ext直接封装一个服务端组件。考虑到ext组件的构建都是需要使用js来完成，那么服务端生成的代码也就是js而不是html。<br />
&nbsp;&nbsp;&nbsp; 如果采取纯Ajax的方式，类似于Echo2的构造，不过这样对于Session可能是一个负担，同时可能会造成服务端的拥堵。不过使用纯Ajax有个好处，就是js只需要装载一次就行了。而如果使用各个不同的页面方式，则需要多次装载ext的js文件，这对于网络也是一个压力。<br />
&nbsp;&nbsp;&nbsp; 不过创建的初衷，此框架主要还是使用于内部网，这样对于性能方面的担心可以略过了。<br />
&nbsp;&nbsp;&nbsp; 设计流程如下：<br />
&nbsp;&nbsp;&nbsp; 类似于Jsf的请求流程,提供Lifecycle，基本上也就五个生命周期，apply request,process validators,update model,invokeAction,render ajax。<br />
&nbsp;&nbsp;&nbsp; 先不考虑其他的生命周期，先来处理render ajax部分。基本构思还是以render xml为主，主要的格式如下：<br />
&nbsp;&nbsp;&nbsp;&nbsp;  <br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">message&nbsp;</span><span style="color: #ff0000;">xmlns</span><span style="color: #0000ff;">="http://www.esoft.org/servermessage"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&nbsp; &lt;</span><span style="color: #800000;">lib</span><span style="color: #0000ff;">&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;</span><span style="color: #800000;">js&nbsp;</span><span style="color: #ff0000;">url</span><span style="color: #0000ff;">="widgets/ext-component"</span><span style="color: #0000ff;">/&gt;<br />
&nbsp; &lt;/</span><span style="color: #800000;">lib</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&nbsp; &lt;</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">Ext.QuickTips.init();</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">script</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&nbsp; &lt;</span><span style="color: #800000;">content&nbsp;</span><span style="color: #ff0000;">cid</span><span style="color: #0000ff;">="W9"</span><span style="color: #0000ff;">&gt;&lt;</span><span style="color: #800000;">div&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="W39"</span><span style="color: #0000ff;">/&gt;&lt;/</span><span style="color: #800000;">content</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&nbsp; &lt;</span><span style="color: #800000;">remove</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">Ext.get('W29').remove();</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">remove</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">message</span><span style="color: #0000ff;">&gt;</span></div>
<br />
lib 中主要用来装载ext的各个组件js,这样不需要一次装载。<br />
script，主要的执行js脚本<br />
content用于创建相应的html<br />
remove相应的删除js脚本<br />
<br />
为什么需要增加remove而不是把所有的脚本都放在script中。<br />
这是由于整个处理都在一个页面中，为了能按照顺序执行相应的脚本，remove的脚本需要优先执行，当两个组件不停的切换的时候。<br />
<br />
client 对于脚本的解析流程如下：<br />
首先分批装载js url<br />
当所有的js装载完成后<br />
执行remove 脚本<br />
遍历content,增加相应的html node<br />
执行script脚本。<br />
<br />
对于页面的生成，基本上没有什么问题。<br />
只是如果采用这种方式，可能目前来说只能依赖于ext这个框架，对于服务端的灵活性也就大打折扣，不过既然是为了ext而做的，那也就无所谓了。<br />
<br />
不知道各位对这种生成方式有什么不同意见，期待讨论。<br />
<img src ="http://www.blogjava.net/zyl/aggbug/172279.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2008-01-02 18:36 <a href="http://www.blogjava.net/zyl/archive/2008/01/02/extjs.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ext 之我见</title><link>http://www.blogjava.net/zyl/archive/2007/12/28/ext.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Fri, 28 Dec 2007 11:01:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/12/28/ext.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/171285.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/12/28/ext.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/171285.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/171285.html</trackback:ping><description><![CDATA[<div style="font-size: 14px; line-height: 30px;">&nbsp;&nbsp;&nbsp; 最近的这段时间，感觉Ext挺火的。接触Ext还是半年前的事情了，那时候就想对Ext进行封装，做一个服务端的Ajax框架出来。可由于身体的原因，还是搁浅了。<br />
&nbsp;&nbsp;&nbsp; 使用Ext是从1.1开始的，那时候觉得Ext，几乎已经简化了所有的客户端脚本。就算不会js，不会Ajax，使用Ext也可以很容易的搭建不错的页面。而且Ext在兼容性上面做的也算不错，至少我在ie 6,ie 7 ff和opera 9上运行demo的时候基本上没有什么问题。当然最主要的一个吸引我的因素是，和其他的框架相比，Ext的界面做的比较的出色，就美观而言，算是perfect了。<br />
&nbsp;&nbsp;&nbsp; 随着Ext 2.0的正式发布，关注Ext的人也越来越多。Ext变得越来越大众化，这是一件值得高兴的事情，毕竟使用Ext能够帮助简化不少的js代码，而且对于html代码的编写，是数量级的减少。<br />
&nbsp;&nbsp;&nbsp; 让数据和内容分离，一直是Ajax所提倡的，而Ext可以完全做到这些。Grid作为表示组件而Store作为数据存储，数据可以通过Reader来读取，包括xml和json，或者其它的自定义实现。<br />
&nbsp;&nbsp;&nbsp; 组件化，这是Ext最大的特色。所有的组件都继承Ext.Component这个基础类。而Ext.Component继承Ext.util.Observable，让组件事件的处理变得更为的强大和灵活。Ext可以模拟所有的桌面事件，如双击，拖拽，这些只有在桌面程序中才见到的，而这些事件的处理变得和桌面程序一样的简捷。<br />
&nbsp;&nbsp;&nbsp; 动画以及控件的resize和drag，这些比较难处理的js，在Ext中变得实在很简洁。基本的Window都有drag和resize行为，动画更是简单。当然这些功能只是次要的。不过在ria中，这些功能又都是不能缺少的。<br />
&nbsp;&nbsp;&nbsp; 当然Ext的诟病也不少，如性能，这个在浏览器中关键的因素。完整的Ext.js需要400多k，随着宽带的普及，以及Ajax技术的应用，这个应该不成为问题。真正的问题在于Ext都是使用js构建页面，其中的html代码，可能比较的繁琐，过多的div的使用，可能也会是一个灾难。如Ext.Button这个组件的表现层一样。当然Ext也提供了自定义的html模板功能，这个问题也就可能不是问题了。最后毕竟Ext只是一个客户端的组件实现，和服务端的集成，还需要自己实现。不过Ext在这个方面，也提供了很多的简化功能，如延迟装载，数据读取等。<br />
&nbsp;&nbsp;&nbsp; 当然，个人还是比较的看好Ext，希望这个框架能够越走越好。<br />
<br />
</div>
<img src ="http://www.blogjava.net/zyl/aggbug/171285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-12-28 19:01 <a href="http://www.blogjava.net/zyl/archive/2007/12/28/ext.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsf中的 国际化，验证和转换</title><link>http://www.blogjava.net/zyl/archive/2007/05/24/119705.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Thu, 24 May 2007 05:26:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/05/24/119705.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/119705.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/05/24/119705.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/119705.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/119705.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 这些东东，对于web框架来说，是必不可少的，来看看jsf是如何实现的。首先看一下国际化，默认的情况下，会选择默认的locale，以及相应的资源文件。当然可以通过以下方式进行配置：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">application</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">locale-config</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">default-locale</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">en</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">default-locale</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">supported-locale</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">en</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">supported-locale</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">supported-locale</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">es</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">supported-locale</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">locale-config</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">message-bundle</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">CustomMessages</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">message-bundle</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">application</span><span style="color: #0000ff;">&gt;</span></div>
<br>资源文件，也是和其他web应用一致。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">halloween</span><span style="color: #000000;">=</span><span style="color: #000000;">Every&nbsp;day&nbsp;is&nbsp;like&nbsp;Halloween.<br>numberOfVisits</span><span style="color: #000000;">=</span><span style="color: #000000;">You&nbsp;have&nbsp;visited&nbsp;us&nbsp;{</span><span style="color: #000000;">0</span><span style="color: #000000;">}&nbsp;time(s)</span><span style="color: #000000;">,</span><span style="color: #000000;">&nbsp;{</span><span style="color: #000000;">1</span><span style="color: #000000;">}.&nbsp;Rock&nbsp;on!<br>toggleLocale</span><span style="color: #000000;">=</span><span style="color: #000000;">Translate&nbsp;to&nbsp;Spanish<br>helloImage</span><span style="color: #000000;">=</span><span style="color: #000000;">../images/hello.gif</span></div>
<br><br>如果需要在页面中使用相应的bundle，需要使用以下的标记：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:loadBundle&nbsp;</span><span style="color: #ff0000;">basename</span><span style="color: #0000ff;">="LocalizationResources"</span><span style="color: #ff0000;">&nbsp;var</span><span style="color: #0000ff;">="bundle"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:outputText&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">="#{bundle.halloween}"</span><span style="color: #0000ff;">/&gt;</span></div>
<br><br>当然这是使用默认的locale设置，如果想动态切换locale，目前我的处理方式是这样的：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:loadBundle&nbsp;</span><span style="color: #ff0000;">basename</span><span style="color: #0000ff;">="messages_#{localeBean.locale}"</span><span style="color: #ff0000;">&nbsp;var</span><span style="color: #0000ff;">="msg"</span><span style="color: #0000ff;">/&gt;</span></div>
<br>当然localeBean.locale的值是动态更改的，可以为en,zh_CN，等等。<br>个人觉得和spring 的web framework相比，没有spring的那么灵活，不过基本上都能解决问题，凑合着用吧。<br><br>如果想在代码中使用，还是需要使用以下方法：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;String&nbsp;getMessageString(String&nbsp;name,&nbsp;Object<img src="http://www.blogjava.net/Images/dot.gif">&nbsp;params)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;str&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">""</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;FacesContext&nbsp;facesContext&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FacesContext.getCurrentInstance();<br>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;bundleName&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;facesContext.getApplication().getMessageBundle();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(bundleName&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Locale&nbsp;locale&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;facesContext.getViewRoot().getLocale();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResourceBundle&nbsp;bundle&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ResourceBundle.getBundle(bundleName,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;locale,&nbsp;getCurrentClassLoader(params));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;bundle.getString(name);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;str;<br>&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>&nbsp;&nbsp;&nbsp; 对于验证机制，基本的接口为Validator,只有一个方法validate。通常的验证机制，都是通过服务端来实现。如果想支持客户端支持，估计还得自己写一套接口去替换。不过看了其生命周期，觉得很难实现，除非脱离其生命周期。当然，这些使用ajax来处理，可能会减少服务端的通信负担。<br>&nbsp;&nbsp; 其默认的验证实现，包括以下几个：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;DoubleRange：</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:validateDoubleRange</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Length：</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:validateLength</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LongRange：</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:validateLongRange</span><span style="color: #0000ff;">&gt;</span></div>
<br>&nbsp;&nbsp; 从字面意思可以看出来。<br>&nbsp;&nbsp; 当然，每个组件都有默认的验证器required。只要设置其属性为ture，就会进行空值判断。<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; 对于组件来说，支持多个验证器。但是没有看到关联组件的验证器，需要自己实现。如password的是否一致<br><br>&nbsp;&nbsp; 类型转换，接口Converter，包括两个方法:<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Object&nbsp;getAsObject(FacesContext&nbsp;context,&nbsp;UIComponent&nbsp;component,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;value);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getAsString(FacesContext&nbsp;context,&nbsp;UIComponent&nbsp;component,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;value);</span></div>
<br>&nbsp;&nbsp; <br>&nbsp; 前者转化为对象，后者为用于页面输出。<br>&nbsp; 在进行验证前，都会先进行值转换。<br>&nbsp; 对于转换,内部已经提供了基本类型的实现，包括数字，日期，boolean型。<br>&nbsp; 当然Converter另外一个功能，就是提供格式化输出，支持NumberFormat和DateFormat的输出：<br>&nbsp; 包括：&lt;f:convertDateTime&gt;和&lt;f:convertNumber pattern="###,###.##;(###,###.##)"/&gt;其样式，完全采用相应的java样式。<br><br><br><br><br><img src ="http://www.blogjava.net/zyl/aggbug/119705.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-05-24 13:26 <a href="http://www.blogjava.net/zyl/archive/2007/05/24/119705.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>velocity 二 开发篇</title><link>http://www.blogjava.net/zyl/archive/2007/05/17/117957.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Wed, 16 May 2007 23:34:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/05/17/117957.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/117957.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/05/17/117957.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/117957.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/117957.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 先来看看velocity是怎么工作的？<br><br>在应用中使用velocity，一般需要以下的几个步骤：<br><br>    *   初始化Velocity,可以使用单例，或者运行期实例<br>    *   创建context对象，用于包括相应的变量<br>    *   在context中增加相应的数据<br>    *   选择模板<br>    *   合并模板，产生输出<br><br>&nbsp;&nbsp;<a href='http://www.blogjava.net/zyl/archive/2007/05/17/117957.html'>阅读全文</a><img src ="http://www.blogjava.net/zyl/aggbug/117957.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-05-17 07:34 <a href="http://www.blogjava.net/zyl/archive/2007/05/17/117957.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于velocity 一语法篇</title><link>http://www.blogjava.net/zyl/archive/2007/05/14/117215.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Mon, 14 May 2007 00:30:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/05/14/117215.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/117215.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/05/14/117215.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/117215.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/117215.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 一个古老而又强大的模版引擎。在模版引擎中,velocity中，应该属于最常用的，不管是在maven的项目模版，还是在源代码输出，甚至直接网页输出中，都可以看到其身影。当然，最近的freemarker大有平分天下之意。<br>&nbsp;&nbsp; 以前的时候，曾用velocity设计过一个自动代码的项目，在用的过程中，享受了其简单而又灵活的功能。后来由于，自动代码的项目一直没有什么进展，也就很少去关注velocity。这段时间，被jsf搞得焦头烂额，最后想起了velocity，看看能不能用其来实现替换jsf的标记库功能。于是又复习了一遍velocity。<br>&nbsp;&nbsp; 先来看看velocity的语法：vtl也就是velocity的基本语言.用过脚本语言的，对于这个应该会很容易上手，其实，基本上，语法可以分为变量和关键词。先来看看变量，变量使用$作为开头符号，$a 和${a}是一致的。类似于jstl中的变量定义。在模版中声明一个变量是很容易的，使用set关键字<br>&nbsp;&nbsp; #set( $foo = "Velocity" )。对于velocity中，感觉比较灵活的就是变量中，可以直接使用方法，和javabean属性一样方便使用：<br>&nbsp;&nbsp; 对于javabean 支持内置属性，如下：$customer.Address，$purchase.Total，$customer.Address.phone。不过好像不支持map语法，如：<br>a["key"]这种写法。但是可以使用方法代替：a.get("key")。而使用了方法，感觉就在使用java代码一样方便。当然变量中支持简单的表达式计算：$a+1等等<br>&nbsp;&nbsp; 有一点需要注意的是，如果变量没有解析，还是会输出$a这个变量，而不是空白，或者报错，这一点，不知道是方便还是不方便。<br>&nbsp;&nbsp; 语法中另外一个，就是关键字了，关键字使用#开头。<br>&nbsp;&nbsp; 其关键字也不多，只有少数的几个，但是已经足够用了。如前面的声明变量：#set<br>&nbsp;&nbsp; #if #elseif #else&nbsp; #end 这是最常用的条件判断，每个判断使用#end结尾<br>&nbsp;&nbsp; #if($a==1)true enough#{else}no way!#end<br><br>&nbsp;&nbsp; #foreach() #end用于循环输出<br>&nbsp;&nbsp; #foreach( $key in $allProducts.keySet() )<br>&nbsp;&nbsp;&nbsp; &lt;li&gt;Key: $key -&gt; Value: $allProducts.get($key)&lt;/li&gt;<br>&nbsp;&nbsp; #end<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; #include，用于包括一些资源文件，当然include是不会去解析资源文件，这和#parse不同<br>&nbsp;&nbsp; #include( "one.txt" )<br><br>&nbsp;&nbsp; #parse，用于解析并且包括相应的资源文件<br>&nbsp;&nbsp; #parse( "me.vm" )，和主文件共享相应的Context<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; #stop,用于停止执行解析，并返回，主要用于调试功能。<br><br>&nbsp;&nbsp; 基本上，使用以上的语法，可以定义出任何的模版了。当然，为了简化模版的定义，velocity特意推出了#macro这个强大的功能.<br>&nbsp;&nbsp; #macro，类似于宏定义，用于自定义相应的标记。<br>&nbsp;&nbsp; 如下定义了一段宏，用于输出表格中的列表<br>&nbsp;&nbsp; #macro( tablerows $color $somelist )<br>&nbsp;&nbsp;&nbsp; #foreach( $something in $somelist )<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;tr&gt;&lt;td bgcolor=$color&gt;$something&lt;/td&gt;&lt;/tr&gt;<br>&nbsp;&nbsp;&nbsp; #end<br>&nbsp;&nbsp; #end<br>&nbsp;&nbsp; <br>&nbsp;&nbsp; 在模版中，只需要使用#tablerows($color $somelist)就可以取代里面的代码了：<br>&nbsp;&nbsp; #set( $greatlakes = ["Superior","Michigan","Huron","Erie","Ontario"] )<br>&nbsp;&nbsp; #set( $color = "blue" )<br>&nbsp; &lt;table&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp; #tablerows( $color $greatlakes )<br>&nbsp; &lt;/table&gt;<br>&nbsp; <br>&nbsp;&nbsp; 而且#macro 支持内嵌语法，所以对于模版的定义，就变得更加的灵活而简单了。<br>&nbsp;&nbsp; <br><br><br><img src ="http://www.blogjava.net/zyl/aggbug/117215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-05-14 08:30 <a href="http://www.blogjava.net/zyl/archive/2007/05/14/117215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于jsf 的标记库</title><link>http://www.blogjava.net/zyl/archive/2007/05/09/116270.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Wed, 09 May 2007 12:33:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/05/09/116270.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/116270.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/05/09/116270.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/116270.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/116270.html</trackback:ping><description><![CDATA[<div style="font-size: 14px; line-height: 30px;">&nbsp; 对于标记库，不想再说些什么了。jsf可能最大的毛病都在这个标记库上面，首先定义的标记在jsp中，并不起到相应的输出功能，而只是用来增加相应得组件。在jsf中，最上层的组件为UIViewRoot，基本上所有的操作都是需要围绕着此组件。而标记库的存在，只是为了简化相应的操作。如下的标记：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:view</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:form</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:panelGrid</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif">.&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:panelGrid</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:form</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">f:view</span><span style="color: #0000ff;">&gt;</span></div>
<br>其实对应的java代码，如下：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">FacesContext&nbsp;context&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;FacesContext.getCurrentInstance();<br>UIViewRoot&nbsp;root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;context.getViewRoot();<br>HtmlForm&nbsp;form&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HtmlForm();<br>HtmlPanelGrid&nbsp;grid&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HtmlPanelGrid();<br>form.getChildren().add(grid);<br>root.getChildren().add(form);</span></div>
<br>也就是说没有标记库，我完全可以使用java代码完成。<br>&nbsp;&nbsp;&nbsp; 那么标记库的存在到底有没有意义，意义可能就在于简化相应的操作，想想html的属性是比较多的，如果每个都要用java代码去控制，那么可能对于应用来说，显得很不灵活，因为改代码毕竟没有改jsp来的快。而且代码需要重新编译。所以jsf的标记库存在也是有点意义的。<br>可是，现在的问题是，由于jsf本身就是规范，其实现也就会各有不同，对于每种实现都会带有自己的那一套标记库，随着标记库的增加，对于使用者来说，也是不堪忍受的重负。所以，有些时候，如果需要动态做一些配置，那么还是丢弃标记库，用java代码来完成吧。当然facelets，提供了一种方式，用于很灵活的扩展多个标记库，可是，看着那么多的标记，总是还有些头疼。<br><br>&nbsp;&nbsp;&nbsp; 其次，对于标记库来说，各个标记库的不兼容也是一个很大的问题。就拿jstl和jsf来说，jstl的变量声明，在jsf中肯定是没有办法解析的，同样jsf中的变量，在jstl中也不能认识。我指的是页面声明的变量，而不是session变量，如下的例子：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:dataTable&nbsp;</span><span style="color: #ff0000;">styleClass</span><span style="color: #0000ff;">="table-background"</span><span style="color: #ff0000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rowClasses</span><span style="color: #0000ff;">="table-odd-row,table-even-row"</span><span style="color: #ff0000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cellpadding</span><span style="color: #0000ff;">="3"</span><span style="color: #ff0000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value</span><span style="color: #0000ff;">="#{recordBean.records}"</span><span style="color: #ff0000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var</span><span style="color: #0000ff;">="record"</span><span style="color: #ff0000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;binding</span><span style="color: #0000ff;">="#{recordBean.recordData}"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">c:if&nbsp;</span><span style="color: #ff0000;">test</span><span style="color: #0000ff;">="${record}"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">c:if</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:dataTable</span><span style="color: #0000ff;">&gt;</span></div>
<br>在dataTable中声明了变量record，但是在jstl中是不会认识的。<br>&nbsp;&nbsp;&nbsp; 可能这个问题，facelets已经解决了，主要facelets把所有的Elcontext中的变量都结合在了一起，使用自身的FaceletsContext。<br>不过，如果我只是需要简单的功能，还需要使用facelets，那么也就有点大材小用了。况且facelets也只是提供了类似tiles的功能。<br>最后，想说的是，虽然jsf目前的ide支持，比其他框架多多了。可惜，人家都是建立在相应的标记库上的，如果你定义了自己标记库，人家不一定会认识。所以标记库的存在，对于jsf来说，也许并不一定是好事情，可能sun觉得如果把jsp抛弃了，有点可惜。所以在升级jsf的同时，也升级了相应得jsp规范。<br>&nbsp;&nbsp;&nbsp; 个人觉得，也许模版技术，可能也会是一种选择，看看velocity和freemarker，觉得其比jsp有优势多了。<br><br></div><img src ="http://www.blogjava.net/zyl/aggbug/116270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-05-09 20:33 <a href="http://www.blogjava.net/zyl/archive/2007/05/09/116270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于jsf 生命周期</title><link>http://www.blogjava.net/zyl/archive/2007/05/04/115316.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Fri, 04 May 2007 07:44:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/05/04/115316.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/115316.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/05/04/115316.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/115316.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/115316.html</trackback:ping><description><![CDATA[<span style="font-size: 14px; line-height: 30px;">&nbsp;&nbsp;&nbsp; 这是jsf 的分析系列第三篇，随着不断的深入，jsf的设计变得越来越清晰。当然，在目前的规范中，jsf还是很不完善的，这也就导致了为什么jsf还是不能成为目前的主流框架。先不去谈论这些弊端，还是先看看一下jsf具体是如何运作的。<br>&nbsp;&nbsp;&nbsp; 对于jsf规范，个人觉得和其他框架相比，最大的区别，可能在于jsf划分了web 请求的生命周期。like ejb一样，web 请求也是有生命周期的。虽然，在其他的框架中，也可以看到相关的生命周期，但还是没有jsf划分的清晰。也许，这也是jsf的一大特色。<br>&nbsp;&nbsp;&nbsp; 对于生命周期的执行，所有的操作都归结到Lifecycle这个接口。接口包括了两个主要的方法：<br>&nbsp;&nbsp;&nbsp; public abstract void execute(FacesContext context) throws FacesException;和<br>&nbsp;&nbsp;&nbsp; public abstract void render(FacesContext context) throws FacesException;<br>&nbsp;&nbsp; 前者是用来执行各个生命周期的阶段，也就是除了render之外的其他五个阶段，而且是按照相应的顺序执行。而render，是执行最后一个阶段，展示页面。可能有人不太理解，为什么不把两个方法合并成一个方法，刚开始，我也是这么认为。既然已经定义了相应的Phase，何必要把最后的render过程分离出来。看了sun 的RI实现类，发现在render之前需要进行context.getResponseComplete()判断，可能规范中，认为render是必须要执行的阶段，其他的阶段可以跳过，所以分离了相应的方法,同时在执行前,为了避免重复输出,需要对render过程进行特殊的处理.<br>&nbsp;&nbsp; 规范中定义了6个阶段，从下面的流程图中可以看到。<br><img alt=""  src="http://www.blogjava.net/images/blogjava_net/zyl/lct.GIF" height="768" width="524"><br>简单介绍一下每个阶段的工作：<br><br><span style="font-weight: bold;">RESTORE_VIEW：</span>查找原有的view ，恢复原有的状态，如果没有，则调用ViewHandler.createView，如果为post操作，则按照顺序执行各个阶段。<br>否则执行RENDER_RESPONSE阶段。<br><span style="font-weight: bold;">APPLY_REQUEST_VALUES：</span>读取客户端参数，处理各个组件的processDecodes方法，内部调用decode方法，由Renderer执行decode方法<br><span style="font-weight: bold;">PROCESS_VALIDATIONS：</span>执行组件的processValidators方法，对于UIInput执行validate方法，用于绑定值，调用convert,和validate<br><span style="font-weight: bold;">UPDATE_MODEL_VALUES:</span>执行组件的processUpdates方法，对于UIViewRoot，执行broadcastEvents和notifyPhaseListeners<br>所有的UIInput,执行updateModel方法。<br><span style="font-weight: bold;">INVOKE_APPLICATION：</span>调用UIViewRoot.processApplication方法。这一过程主要读取相应的action配置，如果存在action，则调用action，也就是调用应用逻辑。在执行完相应的逻辑后，查询action是否返回值，如果有，由navigationHandler去读取下一个view id。<br><span style="font-weight: bold;">RENDER_RESPONSE：</span>展示view，调用ViewHandler.renderView,展示view。<br><br>每个阶段定义定义的都比较清晰，有一点需要注意的是，在处理请求时，并不一定会执行每个阶段，可能其中会直接跳到最后的render response阶段。举例来说，如果validator时，存在错误信息，那么就会直接到render response阶段，而下一个阶段不会执行。<br><br><br></span><img src ="http://www.blogjava.net/zyl/aggbug/115316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-05-04 15:44 <a href="http://www.blogjava.net/zyl/archive/2007/05/04/115316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>了解jsf的架构二</title><link>http://www.blogjava.net/zyl/archive/2007/04/25/113562.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Wed, 25 Apr 2007 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/04/25/113562.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/113562.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/04/25/113562.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/113562.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/113562.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 接上一篇内容。这次主要分析一下jsf的相关组件包，也是jsf和structs主要不同的地方。jsf 规范中，对于组件的设计，和其他组件架构一样，分离表现层和模型层。对于组件的render由具体的Renderer来处理，这也达到了Model和View分离的原则。<br>&nbsp;&nbsp;&nbsp; component:所有的基本组件都在其中，如下的主要类图，对于各个组件就不一一详细介绍了。主要介绍一下几个接口：<br><img alt=""  src="http://www.blogjava.net/images/blogjava_net/zyl/1.GIF" height="573" width="1051"><br><br><br>StateHolder：用于表示在请求之间需要保存相应的状态信息,必须实现saveState和resotreState方法。<br>ValueHolder：用于支持本地值的保持，用于访问model数据，通过表达式，支持转换。<br>EditableValueHolder：用于表示那些可以编辑的组件值<br>ActionSource：由UIComponet实现，用于作为ActionEvent的事件源，支持默认的ActionListener调用<br>ActionSource2：这是最近的规范中增加的，提供了对于MethodExpression的支持。<br>ContextCallback：用于组件执行相应的回调<br>NamingContainer：标志接口，表示容器组件<br><br>&nbsp;&nbsp;&nbsp; convert:包括了主要的Convert接口，以及内置的Convert实现类，主要的作用用于在页面值绑定时，进行类型的转换工作<br>&nbsp;&nbsp;&nbsp; validator：主要的验证包，定义了通过的Validator接口，以及简单的几个验证类。默认情况下，jsf都是进行服务端验证，如果想需要客户端验证，暂时从规范中，还没有找出相应的解决方案。不过现在已经是Ajax时代了，使用异步的传输，从效果上已经接近于客户端之间验证。<br>&nbsp;&nbsp;&nbsp; event:主要的事件体系。个人觉得jsf的事件体系还是比较弱的。和强大的Swing事件体制相比，那简直差远了。而且jsf默认使用一个ActionListener来委派所有的客户端动作触发。大多数的调用都是使用MethodExpression来进行。<br>&nbsp;&nbsp;&nbsp; model:只是加强了对于DataTable的支持，以及SelectItems。<br>&nbsp;&nbsp;&nbsp; render：主要的展示包，当然只是提供规范，具体由实现类提供。对于Renderer，都需要一套RenderKit.而RenderKit由RenderKitFactory管理。ResponseStateManager，作为StateManager的帮助类，进行主要的State操作。<br>&nbsp;&nbsp;&nbsp; 基本上，规范也就这么些东东。从整体来看，并不算太复杂。可惜现在的jsf实现实在太多了，而且各个实现并不一定兼容，导致了jsf世界的庞大。<br>&nbsp;&nbsp;&nbsp; <br><br><br><img src ="http://www.blogjava.net/zyl/aggbug/113562.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-04-25 16:33 <a href="http://www.blogjava.net/zyl/archive/2007/04/25/113562.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>了解jsf的架构 一</title><link>http://www.blogjava.net/zyl/archive/2007/04/21/112484.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Sat, 21 Apr 2007 12:06:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/04/21/112484.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/112484.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/04/21/112484.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/112484.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/112484.html</trackback:ping><description><![CDATA[<span style="font-size: 14px; line-height: 30px;">&nbsp;&nbsp;&nbsp; 经过一段时间的学习，对jsf的认识也逐渐清晰。总结了一下jsf和structs的区别，首先在于分离了请求的处理。使用事件处理机制来代替原有的request分发。其次在页面的展示上，采用组件的概念，而不是到处散落的html标记。再有，jsf对于请求的生命周期重新进行了划分，对于每个阶段都可以派遣事件，这使得整个请求的处理比较的清晰。最后，jsf对于页面的流转使用Navigation系统来处理，这一点感觉和structs还是比较类似的，只是换了一个概念。<br>&nbsp;&nbsp;&nbsp; 从jsf的规范来看，jsf整个架构还是比较清晰，各个层次分的也挺明显。从总体上看，规范主要划分了application,context,lifecycle,render,component,validator,event,el几个部分，当然少不了主要的入口Servlet。有一点不太明白，大多数的类都是抽象类而不是接口，可能是为了规定层次吧，不允许多层次继承。下面简单以下介绍各个包的功能：<br>&nbsp;&nbsp; application:从定义上就可以看出来，这是应用级的。中间包括了Application主类，这是主要的程序入口，规范中最具有重量级的类，也是用来连接各个模块的。jsf规范使用工厂的模式,来创建相应的实现类.当然如果需要Application的实现，需要从ApplicationFactory中取得。除了Application类，其中还包括了ViewHandler，这个主要负责View的Renderer调配工作。而许多jsf实现框架，如果想定义自己的行为，一般上都会使用自身的ViewHandler，如facelets。NavigationHandler的工作，不用说已经很明显，就是用来负责页面之间的导航。包中，还包括了view状态管理类--StateManager,主要用于恢复view，以及保存view。目前一般使用Session来保存相应的view，当然也可以使用客户端来保存。其实，对于view状态的保存，非议还是挺多的，而且问题也比较多。<br>&nbsp; context：包括了主要的上下文环境类，如FacesContext和ExternalContext，前者是jsf的主要Context类，包括对message的管理，Application的取得，以及ResponseWrite的引用。后者主要类似于作为外部环境的引用类，如ServletContext和PortletContext.ResponseWriter,主要的服务端Writer，用于输出相应的html,xml内容，所有的Renderer都需要引用此类<br>&nbsp; lifecycle:这是jsf最大的特色，划分了请求的相应的处理阶段。规范中，只有两个类Lifecycle和LifecycleFactory。Lifecycle管理整个jsf请求的生命周期。通过指定的顺序执行相应的阶段。<br>&nbsp; webapp:定义了主要的Servlet，FacesServlet，主要的请求分发类，用于转换相应得faces为实际的资源。在规范中，Servlet并不是主要的初始化类，jsf 的初始化工作主要由具体的实现完成。在RI实现中，基本上由ConfigureListener完成初始化工作。而Servlet的任务只是简单的传递请求参数而已，以及调用相应的Lifecycle而已。<br>&nbsp; 这里主要讲了jsf 的整体架构包，下一篇主要分析一下jsf相关组件的包。<br><br>&nbsp; <br>&nbsp; <br><br><br><br></span><img src ="http://www.blogjava.net/zyl/aggbug/112484.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-04-21 20:06 <a href="http://www.blogjava.net/zyl/archive/2007/04/21/112484.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在eclipse中使用jetty</title><link>http://www.blogjava.net/zyl/archive/2007/04/12/jetty2.html</link><dc:creator>布衣郎</dc:creator><author>布衣郎</author><pubDate>Thu, 12 Apr 2007 05:42:00 GMT</pubDate><guid>http://www.blogjava.net/zyl/archive/2007/04/12/jetty2.html</guid><wfw:comment>http://www.blogjava.net/zyl/comments/110159.html</wfw:comment><comments>http://www.blogjava.net/zyl/archive/2007/04/12/jetty2.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/zyl/comments/commentRss/110159.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zyl/services/trackbacks/110159.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 在eclipse中使用jetty是非常简单的，对于其他的ide配置基本上都一致。以前如果想调试web服务，必须要在庞大的开发插件下进行，如myeclipse，其实只是需要简单的功能，然而却不得不接受许多不常用的功能。没有办法，现在有了jetty，如果你只想调试web服务而已，那么请离开那些庞大的开发插件。简单的事情，用简单的方式处理。<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; 首先创建一个web项目，我是采用maven 创建的，用了maven，就喜欢上了，而且正在享受其带来的方便。如下图的目录结构：<br><br><img alt="" src="http://www.blogjava.net/images/blogjava_net/zyl/1.gif" height="564" width="237"><br><br>&nbsp;&nbsp;&nbsp; 在web-inf中可以不需要放置jar文件，因为你是在eclipse中运行，自动会增加相应的classpath中的jar。只是需要把相应的jsp文件放置在webapp中。<br>&nbsp;&nbsp;&nbsp; 接着增加相应的jetty.jar，本来我是采用maven直接增加的，为了清晰的方式，采用手工增加。毕竟这些jar，我是不需要的。如下图<br><br><img alt="" src="http://www.blogjava.net/images/blogjava_net/zyl/2.gif" height="213" width="417"><br><br>&nbsp;&nbsp;&nbsp; 默认，我使用jsp2.1规范，如果需要jsp2.0，可以只增加相应的jsp2.0文件中的jar。<br>&nbsp;&nbsp;&nbsp; 接下来，就配置run application。增加一个java application run.如下图<br><br><img alt="" src="http://www.blogjava.net/images/blogjava_net/zyl/3.gif" height="249" width="589"><br><br>&nbsp;&nbsp;&nbsp; 记得勾上include libraries when...<br>&nbsp;&nbsp;&nbsp; 主要的main class:org.mortbay.xml.XmlConfiguration<br>&nbsp;&nbsp;&nbsp; 最后配置相应的参数：<br>&nbsp;&nbsp;&nbsp; program 参数为：etc/jetty-mywork-spring.xml，别忘了设置working directory为相应的jetty目录。如下图<br><br><img alt="" src="http://www.blogjava.net/images/blogjava_net/zyl/4.gif" height="338" width="565"><br><br>&nbsp;&nbsp;&nbsp; 最后记得不要忘了在etc/jetty-mywork-spring.xml，增加相应的web 应用。如何增加，参见上篇文章：<br><br>&nbsp;&nbsp;&nbsp; <a href="http://www.blogjava.net/zyl/archive/2007/04/09/jetty.html">http://www.blogjava.net/zyl/archive/2007/04/09/jetty.html
</a><br>
<br> <img src ="http://www.blogjava.net/zyl/aggbug/110159.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zyl/" target="_blank">布衣郎</a> 2007-04-12 13:42 <a href="http://www.blogjava.net/zyl/archive/2007/04/12/jetty2.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>