`
kyo100900
  • 浏览: 639740 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【JSF专家Dennis Byrne】JSF反模式与陷井(三)完

阅读更多

终于到本文的最后一节了,本节内容主要讲JSF也是面对接口编程的,作者举了个简单的例子。然后在JSF安全问题上,使用了类似于ASP.NETviewstate概念的东东。最后谈到了头痛的Portlet程序开发问题,作者指出Portlet问题远不止这些,而且问题都出在Portlet本身,非常同情Portlet开发人员。

基于接口编程

JSF鼓励“包含与扩展”的设计原则。因此JSF组件模型广泛基于接口。下面的这个例子中,“ImplementationDependentManagedBean.java”却没有使用接口。好吧,我需要对它做些小小的修正。

import org.apache.myfaces.component.html.ext.HtmlInputHidden;
import org.apache.myfaces.component.html.ext.HtmlInputText;
import org.apache.myfaces.component.html.ext.HtmlOutputText;

public class ImplementationDependentManagedBean {

	private HtmlInputText input ;
	private HtmlInputHidden hidden ;
	private HtmlOutputText output ;

	/* 省略getters和setters方法 */

	public boolean recordTotal(ActionEvent event) {

		long total = ((Long)input.getValue()).longValue();
		total += ((Long)hidden.getValue()).longValue();
		total += ((Long)output.getValue()).longValue();

		return new JmsUtil().broadcastTotal(total);
	}

}

 

  

这个bean绑定了三个组件作为其属性,业务逻辑部分将这三个组件封装到一个action listener里去了。(action listener指的就是这里的recordTotal方法)。这三个类(这里指的是HtmlInputTextHtmlInputHiddenHtmlOutputText)都是MyFaces包自带的。这段代码中需要注意的是这个类的业务逻辑部分recordTotal方法只会调用每个组件的getValue方法。而通过JSFAPI,你又会发现这些组件的getValue方法又承继于它们的父类。因此我决定要重构一下代码,将这几个导入的包给换掉:

import javax.faces.component.ValueHolder;

public class RefactoredManagedBean {

   private ValueHolder input ;
   private ValueHolder hidden ;
   private ValueHolder output ;

   /* getters & setters ommitted */

   public boolean recordTotal(ActionEvent event) {

    long total = 0;

    for(ValueHolder valued : new ValueHolder[] {input, hidden, output})
         total += ((Long)valued.getValue()).longValue();

    return new JmsUtil().broadcastTotal(total);

   }
}

 

 

现在我要说一下,ValueHolderHtmlInputText, HtmlInputHidden HtmlOutputText父类实现的一个接口。通过这次重构,我们只要一个ValueHolder接口就可完成原本需要三个类(上面提到的HtmlInputText, HtmlInputHidden HtmlOutputText)才能完成的工作,代码也干净整洁。你会发现使用Polymorphism(多态)对于基于接口编程的业务逻辑代码整理是相当优雅的。(注:不论是JDK本身还是,目前主流的开源框架,接口,多态运用的非常广泛)

 

请记住,JSF的优点之一就是让你自由自在的在POJO里编写的你的业务逻辑,开发人员并不要实现任何接口或继承任何类!这一点并没有意味着我们失掉了面向对象的编程原则。当你有机会在基于标准的接口上编程的话,大胆去做吧。

 

最后,你有没有注意到recordTotal这个action listener JSF规范规定Actionlistener方法返回值要为void,但咱们这里却返回一个boolean。实际上MyFaces相对规范来说,宽松了点,但允许你这么做,但实际上还是会忽略返回值的。但尽量还是避免这样,因为根据JSF的实现参考来说,有返回值是应该抛异常的,也许别的JSF实现可能与MyFaces不同了吧。

 

 

View State(视图状态)加密

一个普遍的错误观念就是许多开发人员觉得View State加密根本不需要SSL很显然嘛,SSLView State加密根本没有共同点——它们在各自不同的网络协议中解决属于各自的问题,互不相干。

 

好,我们来再来举个例子。假设Manfred是个银行,Sean是个在线客户,而Mike是媒介。在使用普通的HTTP的情况下,Mike可以截取Sean发送给Mannfred的请求,偷偷记下Sean的密码,然后再转发给Manfred。这一系列动作对于ManfredSean任何一方来说,都是神不知,鬼不觉的。

 

 

 

如果在网络传输层上ManfredSean使用了SSL的话,就可以有效阻止Mike窃取他们之间的信息。

 SSL提供的是点到点的安全保障,这样从Sean发送到Manfred的请求就不会被Mike截取了。但如果应用程序在客户端保存状态的话,SSL就法保证一定是安全的了。当使用客户端状态保存时,JSF会创建一个数据结构,它是一个控件树的序列化Base64编码,用来表示绑定组件的响应状态值,这个数据结构就是view state,并且此时view state是被序列化和加密过的,然后隐藏在的一个HTML hidden字段中。 HTML表单提交时,它会将view state的值作为一个HTTP参数传到服务器后台。JSF利用该参数的值,进行反序列化,解密等逆向操作来还原先前的视图是的状态值。这对所有的JSF实现来说都是一个很大安全性挑战,因为Sean是可以自由的改变view state值的(因为它只是一个隐藏的hidden字段)。 我强烈推荐在你的产品中使用view state加密,因为这样可以防止web客户端被恶意篡改view state的值。我也建议在开发和功能测试阶段关闭view state加密(因为Base64编码后的数据量很大,反序列化或解密操作估计有性能损耗)。要想使用view state加密,去好好看看你使用的JSF实现文档吧。

 

 

Portlet问题

我有点同情Portlet开发人员。确实,他们总是在邮件列表或论坛上不断的提出一个接一个问题,而这些问题本身来自Portlet,与他们无关。如果一定要说有这么一批人不得不对标准低头,被迫屈服的话,那非Portlet开发人员莫属了。(同情中………………

 

有些JSF API在基于Portlet的应用程序中表现的行为是不同的。如果你的Portlet应用程序运行在一个普通的Servlet容器里,那么有一些假设需要去避免。现在假设下面的这段代码在Servlet容器里运行的好好的:

 

FacesContext ctx = FacesContext.getCurrentInstance();
ExternalContext externalContext = ctx.getExternalContext();
ServletRequest request = (ServletRequest) externalContext.getRequest();
String id = request.getParameter("id");

 

 

如果现在你想运行Portlet应用程序,就必须取消显式的javax.servlet.ServletRequest or javax.servlet.ServletResponse进行转换。在Portlet应用程序中,ExternalContext.getRequest 返回的是一个javax.portlet.PortletRequest,结果可想而知,当然会抛出ClassCastException异常。我这里有一个通用的好办法,也可以获取request中的属性值,请看:

 

FacesContext ctx = FacesContext.getCurrentInstance();
ExternalContext externalContext = ctx.getExternalContext();
externalContext.getRequestParameterMap().get("id");

 

 

 

(全文完)

9
7
分享到:
评论

相关推荐

    JSF框架中使用的设计模式介绍

    JSF框架充分利用了多种设计模式,这些模式有助于提高代码的可复用性、可维护性和可扩展性。以下是JSF框架中使用的一些关键设计模式的详细解释: 1. **Singleton模式**: Singleton模式确保一个类只有一个实例,并...

    JSF与hibernate整合的登陆

    **JSF与Hibernate整合** 的目的是将JSF的UI处理能力与Hibernate的数据访问能力结合起来,创建出既具有良好用户体验又能够高效处理数据的Web应用。在本项目中,“JSF与Hibernate整合的登陆”可能涉及到以下关键知识点...

    JSF Java Server Faces (JSF)框架

    JSF是一种用于构建Java Web 应用程序的标准框架(是Java Community Process 规定的JSR-127标准)。JSF(Java Server Faces)技术为开发基于网络用户界面的Java开发者提供了标准的编程接口API以及标签库。就像Struts框架...

    jsf实例jsf实例 JSF学习 JSF jar包 JSF

    jsf实例 JSF学习 JSF jar包 JSF jsf实例 JSF学习 JSF jar包 JSFjsf实例 JSF学习 JSF jar包 JSF jsf实例 JSF学习 JSF jar包 JSF

    JSF入门+JSF web实战+JSF2

    通过这三份资料的学习,开发者将全面了解JSF的各个方面,从基本概念到高级特性,从理论到实践,为成为JSF开发专家奠定坚实基础。在学习过程中,建议结合实际编程练习,以加深理解和提高应用能力。同时,JSF社区提供...

    JSF中文教程jsf

    **JSF框架的优势** 包括丰富的组件库(如PrimeFaces、IceFaces等)、MVC架构模式、易于测试和调试,以及良好的可扩展性。然而,它也有一些挑战,比如性能问题和学习曲线较陡峭。 **中文教程** 对于非英语背景的学习...

    JSF的工作方式 JSF架构 JSF模型 JSF事件类型

    JSF架构基于MVC(Model-View-Controller)模式,由以下核心组件组成: - **模型(Model)**:业务逻辑,通常由JavaBeans(也称为管理Bean)实现,存储和处理应用程序数据。 - **视图(View)**:用户界面,由JSF...

    拍卖系统jsf+ejb+jpa

    在IT行业中,`JSF(JavaServer Faces)`、`EJB(Enterprise JavaBeans)`和`JPA(Java Persistence API)`是三个重要的Java技术,常用于构建企业级的应用系统,特别是拍卖系统这样的业务流程复杂的场景。这里我们将深入...

    JSF上传 JSF大文件上传 JSF上传代码 JSF上传源代码

    为了实现JSF的大文件上传,开发者通常需要借助第三方库,如Apache Commons FileUpload或者PrimeFaces的FileUpload组件。这些组件提供了分块上传的能力,将大文件切割成小块进行传输,从而避免一次性加载整个文件到...

    JSF包,jsf包,JSF包,jsf包

    4. **MVC架构**:JSF遵循MVC模式,有助于分离关注点,提高代码可维护性。 5. **支持AJAX**:JSF 2.0及更高版本提供了内置的AJAX支持,可以实现部分页面更新,提升用户体验。 **jar包**:在给定的文件列表中提到了...

    jsf第一个例子 jsf架包 jsf实例

    它们与JSF页面通过EL(Expression Language)进行交互。 5. **EL(Expression Language)**:EL是用于获取和设置Managed Beans属性的简洁语法,常用于JSF页面中绑定组件的值。 6. **jsf架包**:JSF相关的库通常被...

    jsf入门列子和jsf与Tiles结合

    JavaServer Faces (JSF) 是一个用于构建用户界面的Java框架,主要应用于Web应用程序开发。JSF基于模型-视图-控制器(MVC)架构,提供了丰富的组件库和生命周期管理,使得开发者能够更加便捷地创建动态、数据驱动的...

    《JSF_实战》非常好的JSF学习书

    《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF学习书《JSF_实战》非常好的JSF...

    core jsf 1.2 jsf 核心

    JSF遵循MVC(Model-View-Controller)设计模式,将业务逻辑、视图呈现和用户交互分离开来,使得开发者能够更专注于各自领域的代码编写。JSF的核心组件包括UI组件、事件处理、数据绑定和转换验证。 ### 2. UI组件库 ...

    jsf分页 jsf分页 jsf分页

    综上所述,JSF分页是一个涉及前端UI和后端数据处理的复杂过程,但借助组件库和良好的设计模式,可以轻松实现高效且用户友好的分页功能。通过合理优化和灵活扩展,可以适应各种复杂的分页场景。在实际开发中,应根据...

    JSF 核心编程与入门

    JavaScript Server Faces(JSF)是Java平台上的一种用于构建Web应用程序的服务器端框架。它提供了一种组件化的开发方式,使得开发者可以使用可重用的UI组件来构建用户界面,极大地提高了开发效率。在这个主题中,...

    用jsf做的登录注册的组件

    1. **JSF架构**:JSF采用MVC(Model-View-Controller)设计模式,它提供了组件化UI开发的能力。模型负责业务逻辑,视图负责展示,控制器负责处理用户请求并更新模型。 2. **JSF组件**:JSF的核心是UI组件库,如`h:...

    JSF全套(JSF入门教+ LIB+ Ajax4JSF使用手册 )

    JavaScript Faces (JSF) 是Java平台上的一种用于构建用户界面的模型-视图-控制器(MVC)框架,它简化了Web应用程序的开发。本资源包包含了JSF从入门到进阶的多个方面,包括基础教程、核心组件库(LIB)、Ajax4JSF的使用...

Global site tag (gtag.js) - Google Analytics