JSF好像充满了争议,被很多Java大牛们所抱怨,而很多主流厂商却非常支持,毕竟是J2EE5的亲生儿子嘛。
而Ajax却是Web2.0的热门技术之一,N多客户问我,今天你们Ajax了没有?
Ajax4Jsf是结合这两样技术的一个开源项目,本周刚被Jboss从Exadel收购(合作?),闲暇时分,和一哥们一同试了把它的功能,现交个作业。
首先,A4J是开源的,而且文档比较齐全,demo丰富,它有个分支是G4J,即GWT4JSF,但是这次Jboss收购了之后好像没有在其官方网站上看到G4J的消息,如果大家感兴趣,The Server Side 上有说G4J的文章可以参考。
其次,A4J除了能很顺手的用手工编写Jsp的方式书写(废话),Exadel公司还出了一款功能强大的Eclipse Plugin:Exadel Studio Pro,现在也一并给了Jboss,并可以免费使用,而且将于今年夏天开源,感兴趣的朋友可以试用下。
现在让我们用一个注册页面的小例子,看看他的几个简单的功能:
1.根据鼠标事件,自动验证输入值并返回结果
效果1:验证中
![]()
效果2:验证错误
![]()
效果3:验证成功
![]()
功能很简单,代码也简单:
xml 代码
<t:column><a4j:region id="reg_email">
- <a4j:region id="reg_email">
- <t:panelGrid columns="4" cellpadding="0" cellspacing="0"
- border="0">
- <t:column width="12">
- <t:outputText value="电子邮件" />
- t:column>
- <t:column>
- <t:inputText value="#{loginBean.email}" id="email">
- <a4j:support
- actionListener="#{loginBean.processEmailValidation}"
- event="onblur" reRender="detail_mail">
- a4j:support>
- t:inputText>
- t:column>
- <t:column>
- <a4j:status for="reg_email">
- <f:facet name="start">
- <t:panelGrid border="1" cellpadding="0" cellspacing="0"
- columns="1" styleClass="bighei" bgcolor="#FFF200">
- <t:outputText value="验证中.." />
- t:panelGrid>
- f:facet>
- <f:facet name="stop">
- <a4j:outputPanel id="detail_mail">
- <t:panelGrid border="1" cellpadding="0" cellspacing="0"
- columns="1" styleClass="bighei" bgcolor="#FFF2E9"
- rendered="#{!loginBean.validEmail}">
- <t:outputText value="#{loginBean.validEmailStr}">t:outputText>
- t:panelGrid>
- <t:panelGrid border="1" cellpadding="0" cellspacing="0"
- columns="1" styleClass="bighei" bgcolor="#E2F5FF"
- rendered="#{loginBean.validEmail}">
- <t:outputText value="邮箱地址填写正确!">t:outputText>
- t:panelGrid>
- a4j:outputPanel>
- f:facet>
- a4j:status>
- t:column>
- t:panelGrid>
- a4j:region>
加粗的部分是a4j的一些页面片段,简单介绍一下:
xml 代码
- <a4j:support
- actionListener="#{loginBean.processEmailValidation}"
- event="onblur" reRender="detail_mail">
- a4j:support>
监听inputText 的鼠标事件onblur,并执行loginBean中的processEmailValidation方法,执行完毕后刷新id为"detail_mail"的标签区域。<a4j:status for="reg_email"></a4j:status><a4j:status for="reg_email"><a4j:outputpanel id="detail_mail"><a4j:status for="reg_email">监听reg_email定义的区域中的状态变化, 并通过<f:facet name="&lt;strong&gt;start</strong>"></f:facet><f:facet name="start"><f:facet name="start">和<f:facet name="stop"></f:facet><f:facet name="stop"><f:facet name="start"><f:facet name="stop">显示状态改变时,和改变后的页面。<a4j:outputpanel id="detail_mail"></a4j:outputpanel><a4j:outputpanel id="detail_mail"> </a4j:outputpanel></f:facet></f:facet></f:facet></f:facet></f:facet></a4j:status></a4j:outputpanel></a4j:status><a4j:status for="reg_email"><a4j:outputpanel><a4j:status for="reg_email"><f:facet name="start"><f:facet name="stop"><f:facet name="start"><f:facet name="stop"><a4j:outputpanel>中的内容比较简单,根据bean中的validEmail属性的值,决定显示那个panelgrid。这里应该有更简单的写法,不知道大家有没有发现?</a4j:outputpanel></f:facet></f:facet></f:facet></f:facet></a4j:status></a4j:outputpanel></a4j:status>
bean部分的验证代码更简单:
java 代码
- public void processEmailValidation(ActionEvent input) {
- if (ModelValidation.validateEmail(getEmail())) {
- try {
- userService.checkEmail(getEmail());
- setValidEmail(true);
- }
- catch (ReduplicateException e) {
- setValidEmail(false);
- setValidEmailStr("对不起,此email已被注册!");
- }
- }
- else {
- setValidEmail(false);
- setValidEmailStr("邮件地址格式错误!");
- }
- }
其中userService通过Ioc注入,与数据库交互,并进行一些简单的如长度等的验证。
2.验证码图片,并可通过点击图片自身来刷新
效果:
![]()
页面代码:
xml 代码
- <a4j:outputPanel id="detail_media">
- <a4j:commandLink reRender="detail_media">
- <a4j:mediaOutput element="img" cacheable="false"
- session="false" createContent="#{loginBean.paint}"
- value="#{paintData}" mimeType="image/jpeg" />
- a4j:commandLink>
- a4j:outputPanel>
java bean中代码:
java 代码
- public void paint(OutputStream out, Object data) throws IOException {
- if (data instanceof PaintData) {
- PaintData paintData = (PaintData) data;
-
- Random randomNumber = new Random();
- int outPutNumber_int = 0;
- while (outPutNumber_int < 1000) {
- outPutNumber_int = randomNumber.nextInt(9999);
- }
-
- int outPutLine = 0;
- outPutLine = randomNumber.nextInt(100);
- String outPutNumber_str = String.valueOf(outPutNumber_int);
- BufferedImage img = new BufferedImage(paintData.getWidth(),
- paintData.getHeight(), BufferedImage.TYPE_INT_RGB);
- Graphics2D graphics2D = img.createGraphics();
- graphics2D.setBackground(paintData.getBackground());
- graphics2D.setColor(paintData.getDrawColor());
- graphics2D.clearRect(0, 0, paintData.getWidth(), paintData
- .getHeight());
- graphics2D.drawLine(outPutLine, outPutLine, paintData.getWidth()
- - outPutLine, paintData.getHeight() - outPutLine);
- graphics2D.drawString(outPutNumber_str, 19, 16);
- ImageIO.write(img, "jpeg", out);
- }
- }
简单聊一下,中的paint方法得到图片的流。这个方法必须这样定义:public void paint(OutputStream out, Object data).出图片的方法很多,这里出个最简单的做例子。
页面则更为简单,除了之前说的
上面2个例子没有写任何js,java bean也没有做过多的更改,个人认为a4j还是比较容易与jsf结合的。而建立在a4j之上的richi faces组件有着更好的页面效果和更丰富的功能。
</a4j:region></t:column>