《JSP实用教程(第2版)/耿祥义》错误之第四章例7

书上的源代码

//ListFile.java
package tom.jiafei;
import java.io.*;
class FileName implements FilenameFilter 
{  String str=null;
   FileName (String s)
   { str="."+s;
   }
   public  boolean accept(File dir,String name)
   { return name.endsWith(str);
   }              
}
public class ListFile
{  String extendsName=null;
   StringBuffer allFileName; 
   public void setExtendsName(String s)
   { extendsName=s;
   }
   public String getExtendsName()
   { return extendsName;
   }
  public StringBuffer getFileName()
  {  File dir=new File("d:/2000");
     FileName help=new FileName(extendsName);
     String file_name[]=dir.list(help);
     for(int i=0;i<file_name.length;i++)
     {  allFileName.append(file_name[i]+" ");
     }
     return allFileName;
  }  
}

file.jsp


<%@ page contentType="text/html;Charset=GB2312" %>
<%@ page import="tom.jiafei.*"%> 
<jsp:useBean id="file" class="tom.jiafei.ListFile" scope="page"/>
<HTML><BODY bgcolor=cyan><Font size=2>
<FORM action="" Method="post">
  输入文件的扩展名:<Input type=text name="extendsName">
  <Input type=submit value="提交">
</FORM>
  <jsp:setProperty name="file" property="extendsName" param="extendsName"/>
  <P>扩展名是 <jsp:getProperty name="file" property="extendsName"/> 的文件有:
  <BR><jsp:getProperty name="file" property="allFileName"/>
</BODY></HTML>

这个代码在写完之后肯定没有调试,实际调试的时候会提示allFileName这个属性找不到,无论JSP页中是否对这个属性用了getProperty,都会提示这个错误。

把getFileName改成getAllFileName之后正常,这里的正常是运行正常,实际上还有空指针异常没有处理,set方法也没写。

说到这里,就不得不提一下Java Bean 规范

附:Java Bean 规范下载地址

http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html

估计很多人没仔细看过这个规范,Java Bean事实上只规定了属性、事件和方法,属性又分为三种:简单属性、布尔属性和索引属性,而在该书介绍Java Bean的时候,人为的添加了很多自定义的方法,实际上是不符合规范的。规范中始终没有提到对这样的bean如何处理。而该书将添加了自定义的方法的Java Bean有时看做Java Bean,有时又作为普通的Java类处理,容易引起一些混乱。

再提一个错误,书中代码很多charset中的C全大写了,实际编译的时候不起作用,错了好几年也没改

再贴几个规范的原文,暂时用机器翻译一下,等有时间了自己再翻译一遍

2.2 Properties, events, and methods
The three most important features of a Java Bean are the set of properties it exposes, the set of methods it allows other components to call, and the set of events it fires. Properties are described in more detail in Section 7. Basically properties are named attributes associated with a bean that can be read or written by calling appropriate methods on the bean. Thus for example, a bean might have a “foreground” property that represents its foreground
color. This property might be read by calling a “Color getForeground()” method and updated by calling a “void setForeground(Color c)” method. The methods a Java Bean exports are just normal Java methods which can be called from other
components or from a scripting environment. By default all of a bean’s public methods will be exported, but a bean can choose to export only a subset of its public methods (see Section 8.5). Events are described in more detail in Section 6. Events provide a way for one component to notify other components that something interesting has happened. Under the new AWT event model an event listener object can be registered with an event source. When the event source detects that something interesting happens it will call an appropriate method on the event listener object.


2.2属性、事件和方法
一个Java Bean的三个最重要的特性是它使设置的属性,它允许其他组件的方法调用,并火灾事件的集合。属性是更详细地描述第七节。基本属性命名属性关联到一个bean可以读取或写入的bean调用适当的方法。因此例如,bean可能有一个“前景”属性,代表其前景颜色。这个属性可能被调用读“颜色getForeground()”方法和更新通过调用“空白setForeground(颜色c)”的方法。出口Java Bean的方法只是普通的Java方法,可以从其他调用从脚本组件或环境。默认情况下所有bean的公共方法将被导出,但bean可以选择出口只有一个子集的公共方法(见8.5节)。第6节事件更详细地描述。事件为一个组件提供了一种方法来通知其他组件,发生了一些有趣的事。根据新的AWT事件模型可以注册一个事件侦听器对象与一个事件源。当事件源检测到发生一些有趣的事情,它将调用适当的方法在事件监听器对象。


8.5 Design Patterns for Methods
By default, we assume that all public methods of a Java Bean should be exposed as external methods within the component environment for access by other components or by scripting languages.
By default, this includes any property accessor methods, and any event listener registry methods.


8.5设计模式的方法
默认情况下,我们假定所有公共方法的Java Bean应该暴露在组件外部方法环境访问由其他组件或脚本语言。
默认情况下,这包括任何属性访问器方法,任何事件侦听器注册方法。




A.3 Rules for a transitional bean developer
In order for a transitional bean to also be usable correctly in a full JDK 1.1 application builder,
a bean developer must follow these rules:
? The bean should be delivered in a bean JAR file.
? The bean should use the getFoo/setFoo patterns (see Section 8.3) for properties.
? All of the bean’s persistent state must be accessible via getFoo/setFoo properties. This
allows application builder tools to save and restore the beans state using the property
accessor methods. The one exception to this rule is that the bean can ignore state in
java.awt base classes.
? Any events the bean fires should use the new AWT event model and should use the
sunw.util.EventObject and sunw.util.EventListener interfaces to mark events and event
listeners. However in interacting with AWT, the bean must of necessity use the old
AWT event model to catch AWT events.
? If the bean is prepared in the future to use automatic serialization then it must inherit
from the sunw.io.Serializable marker interface.
? The bean can’t rely on any new 1.1 interfaces.


过渡规则bean开发人员
为了一个过渡bean也是可用的正确完整的JDK 1.1应用程序构建器,
bean开发人员必须遵循以下规则:
?bean应该在bean JAR文件。
?bean应该使用getFoo / setFoo模式(见8.3节)的属性。
?所有bean的持久状态必须通过getFoo / setFoo属性。这
允许应用程序生成器工具来保存和恢复使用的bean状态属性
访问器方法。这条规则的一个例外是,bean可以忽略状态
Java。awt基类。
?任何事件bean火灾应该使用新的AWT事件模型,应该使用
sunw.util。EventObject sunw.util。EventListener接口事件和事件
听众。然而在与AWT交互,bean必须使用旧的
AWT事件模型来捕捉AWT事件。
?如果bean是准备在未来使用自动序列化,那么它必须继承
sunw.io。可串行化的标记接口。
?bean不能依靠任何新的1.1接口。






A.4 Application builder responsibilities
To be able to use transitional beans to create JDK 1.0.2 conformant applets and applications,
an application builder tool must:
? Read in a bean from a JAR file.
? It must use its own reflection code to identify properties, events, and public methods,
following the rules defined in Section 8.
? Rather than using automatic serialization to store away a bean’s state it must use the
getXXX methods to read its state and generate some code to call setXXX methods to
revive the bean. If the bean inherits from a JDK 1.0.2 java.awt.* component class, then
it must generate code to restore the appropriate AWT state.




应用程序生成器的责任
能够使用过渡bean创建一致的JDK 1.0.2中applet和应用程序,
应用程序生成器工具必须:
?从一个JAR文件读取bean中。
?它必须使用自己的反射代码识别属性,事件,和公共方法,
在第8部分中定义的规则。
?而不是使用自动序列化存储bean的状态必须使用
getXXX方法阅读其状态并生成一些代码来调用setXXX方法
振兴bean。如果从JDK 1.0.2中java.awt bean继承。*组件类
它必须生成代码恢复相应的AWT状态。




8.3
8.3 Design Patterns for Properties
8.3.1 Simple properties
By default, we use design patterns to locate properties by looking for methods of the form:
public <PropertyType> get<PropertyName>();
public void set<PropertyName>(<PropertyType> a);
If we discover a matching pair of “get<PropertyName>” and “set<PropertyName>” methods
that take and return the same type, then we regard these methods as defining a read-write property
whose name will be “<propertyName>”. We will use the “get<PropertyName>” method
to get the property value and the “set<PropertyName>” method to set the property value. The
pair of methods may be located either in the same class or one may be in a base class and the
other may be in a derived class.
If we find only one of these methods, then we regard it as defining either a read-only or a writeonly
property called “<propertyName>”
By default we assume that properties are neither bound nor constrained (see Section 7).
So a simple read-write property “foo” might be represented by a pair of methods:
public Wombat getFoo();
public void setFoo(Wombat w);
8.3.2 Boolean properties
In addition, for boolean properties, we allow a getter method to match the pattern:
public boolean is<PropertyName>();
This “is<PropertyName>” method may be provided instead of a “get<PropertyName>” method,
or it may be provided in addition to a “get<PropertyName>” method.
In either case, if the “is<PropertyName>” method is present for a boolean property then we will
use the “is<PropertyName>” method to read the property value.
An example boolean property might be:
public boolean isMarsupial();
public void setMarsupial(boolean m);
8.3.3 Indexed properties
If we find a property whose type is an array “<PropertyElement>[]”, then we also look for
methods of the form:
public <PropertyElement> get<PropertyName>(int a);
public void set<PropertyName>(int a, <PropertyElement> b);
If we find either kind of pattern then we assume that “<propertyName>” is an indexed property
and that these methods can be used to read and/or write an indexed value.
Thus an indexed property “foo” might be represented by four accessor methods:
public Bah[] getFoo();
public void setFoo(Bah a[]);
public Bah getFoo(int a);
public void setFoo(int a, Bah b);


8.4 Design Patterns for Events
By default, we use the following design pattern to determine which events a bean multicasts.
We look for a pair of methods of the form:
public void add<EventListenerType>(<EventListenerType> a)
public void remove<EventListenerType>(<EventListenerType> a)
where both methods take the same “<EventListenerType>” type argument, where the
“<EventListenerType>” type extends the “java.util.EventListener” interface, where the first
method starts with “add”, the second method starts with “remove”, and where the “<EventListenerType>”
type name ends with “Listener”.
This design pattern assumes that the Java Bean is acting as a multicast event source for the
events specified in the “<EventListenerType>” interface.
So for example:
public void addFredListener(FredListener t);
public void removeFredListener(FredListener t);
defines a multicast event source.

8.4.1 Unicast event sources
As a special case, when we locate an event source using the design pattern described above we
check if the “add<EventListenerType>” method throws the java.util.TooManyListenersException.
If so, we assume that the event source is unicast and can only tolerate a single event
listener being registered at a time.
So for example:
public void addJackListener(JackListener t)
throws java.util.TooManyListenersException;
public void removeJackListener(JackListener t);
defines a unicast event source for the “JackListener” interface.

8.3和8.4暂时就不翻译了



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值