星期三, 十月 13, 2004

如何用Java软件来开发射频身份识别自动识别方案?

Oct 12, 2004
原文

如何用Java软件来开发射频身份识别 自动识别方案



本文主要描述怎么使用Sun Java 系统RFID软件来开发RFID解决方案.同时帮助开发人员理解架构,设计和实现.
文章也包括的一个可以下载的应用例子,sampleRFID.同同文档一起的ReadME描述的如何同给定接口编码的细节,并且如何配置平台.

什么是RFID和Auto-ID?

射频身份识或RFID使用射频波来识别唯一对象的一种方法.RFID是对下一代条码技术的需求作出的反应.
用最简单的术语来说,RFID系统有标签(应答器)和阅读器(询问器)组成.RFID技术处理用射频通讯收集储存在标签里的远程信息.

储存在标签里的信息范围从一个表示数字到数K的数据可以被写入和读出,动态的信息比如温度的历史在标签中维护.

自动识别或Auto-ID是一个广泛的术语,包括数据数据的方法和无人工干预直接进入计算机系统.
技术传统上认为Auto-ID的部分包括条码,生物测定学,RFID,和声音识别技术.

Auto-ID 技术提供系列方法用来追踪任何物体,任何时间,任何地点.Auto-ID系统基于上面低花费的聪明标签和阅读器,及唯一的对象表示模式.Auto-ID的目标是可以替代UPC条码系统而使用不贵的RFID标签嵌入到产品包装里.或更加好的方式比如嵌入到产品里面.虽然条码不会很快消失.有许多应用如果使用RFID标签将变的更加复杂和增加成本,而使用条码就比较完美。在可见的将来,将是条码和RFID标签共存的时期.

Auto-ID网络由数个使用Auto-ID系统的贸易伙伴组用来追踪供应链上的项目.这将提供商业上空前的实时资产和任何地方的库存视图.并且能提供有重大意义的商标保护努力.Auto-ID网络提供的好处在于定位伪造,串改,恐怖主义和其他的要求的操作的有效性


标准

EPCglobal是Auto-ID的创造中心.它的标准内容基于EPCglobal网络采用的EPC技术.Epglobal 网络包括一组允许及时,自动标识和共享供应链项目信息的技术.EPCglobal网络使用射频标识(RFID)技术是供应链项目信息可见性成为可能.这个网络有5个基本元素组成:

* 电子产品代码 (EPC)
* ID系统(EPC 标签和阅读器)
* EPC 中间件
* 对象命名服务(ONS)
* 物理标记语言

EPC编号系统:
如同统一产品代码(UPC)或条码,EPC是EPC网络上的物理对象的基本标识.
EPC标识厂商,产品,版本和序列号.并且使用额外的数字组表示唯一项目.
EPC标签数据标准规范版本1.1定义了电子产品代码(EPC)在RFID芯片上的编码.也定义如何被EPC网络信息系统层使用的编码(比如RFID信息服务器).

EPC标签和阅读器和接口协议:
EPC标签是带天线的微芯片.EPC被保存在这个标签里,这是在制造过程就被应用了.
EPC标签使用射频标识(RFID)来传递他们的EPC到EPC阅读器.EPC阅读器同EPC标签通讯通过无线电波并且通过EPC中间件发送信息到本地商业信息系统.
这是Auto-ID阅读器协议规范1.0定义的关于阅读器和EPC中间件的通讯的标准协议.

阅读器管理规范扩展了阅读器协议规范,定义了在大的网络上如何管理RFID的标准.

标签可以分类为被动,主动和半被动的.被动标签没有电池及当有提示的时候简单"反射".而活跃标签自带电池并且是通讯发起者.
半被动标签有一个电池,但是也是属于"反射"通讯.它不会启动一个通讯.
可以想象被动和半被动标签作为一个用来传送光的镜子 ,当有光照在它们上面的时候.今天,EPCglobal网络集中精力在被动标签标准上.我们可以期望EPCNetwork关于积极标签的标准很快建立.

EPC中间件:
EPC 中间件过去也叫做Savant.它是关于实时事件管理,EPC数据过滤和收集规范的标准.它覆盖了新的EPCglobal规范,当前作为过滤和收集规范的参考.

EPC信息服务:
EPC信息服务允许用户同使用EPC的商业伙伴交换数据

对象命名服务(ONS):
给你能力来定位包含关于世界上特定任何地方EPC信息的服务器.商业信息系统需要一种方法匹配EPC和货物关联的信息.
ONS是提供通过指明在www上的计算机来提供自动的网络服务.它为包含产品属性及相关属性被维护的的IP地址制定了一个标准.

物理标志语言:(PML)
用做通用语言在EPCglobal网络中,用来定义物理对象的数据.PML的目标是提供一般收集,标准表达词汇和分布信息到
EPC网络可用的对象.PML 核心规范1.0定义了PML标准.

介绍Sun Java 系统RFID软件.

Sun Java系统RFID软件是Sun唯一RFID中件间平台提供提供基于广泛被接受的工业标准也包括在EPCglobal中定义的标准.
它为公司使用EPC网络提供了一个基础. 它的设计规范是提供一个高层次高可靠性和扩充能力的EPC网络同时可以简化同多个
已经存在的后台企业系统整合的任务

Sun java系统RFID软件负责在EPC阅读器和标签之间的EPC数据和事件的通讯和处理,及后台供应链系统ERP.和RFID软件包含
两个基本的部件:1).RFID事件管理 2)RFID信息服务器.两个都可以下载.这两个组件基于Jini 2.0,Rio 3.0.1,及Java Web Service Developer pack 1.3和Sun Application server 7构造.

*RFID事件管理器同EPC标签阅读器通讯来出来大量的EPC数据进入系统.事件管理器也同后台系统通讯并向RFID信息服务器记录
EPC数据和事件.RFID事件管理器是Jnin-Based的事件管理系统.它容易铺捉,过滤和保存由连接到网络上的RFID阅读器产生的EPC事件.
它的主要目标是同RFID阅读器的接口,收集EPC事件,过滤多余信息,并且产生送往迎来RFID信息服务器的相关事件或者其他
EPR软件以备处理.RFID事件管理器Jini服务通过Rio被管理,Rio是一个开源的Jini服务组件包容器.

*RFID信息服务器负责储存和聚集围绕给定的EPC事件关系的业务数据.RFID信息服务器J2EE应用用做一个接口来俘获和查询EPC
相关数据.EPC相关数据包括:来自事件管理器的检查数据也包括映射EPCS到较高级别的商业数据的信息.
RFID 信息服务器是典型的用来转换低级检查到高级商业功能.RFID信息服务器运行在Sun Java系统Application Server 7.
其他信息系统应用接口通过XML信息交换.信息系统支持HTTP和JMS信息输送.
信息系统保存所有数据到关系数据库中.

这两个组件扮演了关键的角色在EPCglobalo 定义的EPC网络中


Sun Java系统RFID软件技术描述

Sun Java 系统RFID事件管理器收集RFID阅读器的信息,过滤信息并且提供大量的信息到RFID信息服务器或第三方的ERP系统.

Figure 1 描述 RFID事件管理器和RFID信息服务器怎样适合EPC Global网络



Figure 1: Sun Java System RFID软件和EPCglobal网络

RFID事件管理器由控制工作站和一个或多个执行代理组成在图2中描述



Figure 2: Sun Java System RFID事件管理器架构

计算机系统可以运行一个或多个执行代理并且每个执行代理可以完成一个或多个工作量.每个执行代理在启动的时候向控制工作站
注册.

控制工作站保存可使用的执行代理注册,监视它们的状态,分配工作量并且帮助他们完成工作量.

一个执行代理包含一个Adapter,一个Logger和Filter组件.每个执行代理可以组成Adapter的馈给信息送到一个或多个filter或
logger,并且没个filter馈给信息给一个或多个logger.Adapter是个Java代码片同实际的RFID阅读器接口.

Sun Java系统RFID 事件管理器 来自被包装的预定义了编码的Adapter.它能理解EPC-顺从的RFID阅读器使用的指定的通讯协议.
这些阅读器 Adapter可以看做计算机系统里同周围外部设备通讯的设备驱动程序.
目前,没有标准的通讯协议可以被RFID阅读器使用来同消费它们的RFID事件的软件通讯.
RFID阅读器是独立的一片(典型的)硬件用来同RFID标签基于无线电频率通讯.
Adpater(适配器A)获得RFID标签的EPC并且产生一个事件包含时间戳和时间源(阅读器和天线发现标签).
事件被传送到处理事件的一组监听器.监听器是filter或logger.Filter可以平滑数据,扔掉先前探测信息或到其他
filter或logger的路由信息.过滤后的数据被传送作为一个事件到感兴趣的listener.Listener可以被其他有更多的数据的filter或logger作为一个连接器到第三方消费RFID信息的应用

The two tables below list the supported filters and loggers and their main functionality.
下列两个表列出了支持的filter和logger及它们主要的功能.

Table:1 Filters 由SunJava系统RFID事件管理器实现.
Filter Type Description
BandPass BandPass在阅读器EPC执行滤过器,来自阅读器的事件匹配EPC掩码被放行到listener,其他的则放弃.
Delta 报告标签进入和留下的视野
EPCFilter 同BandPass.
Smoothing Smoothing creates a union of EPC's discovered over the number of specified N cycles. If an EPC was discovered in cycle N, it is reported, if it hasn't been seen in more than the last N cycles, it is not reported. This is necessary because the RFID readers do not report tags with 100% tag accuracy.

Table 2: Loggers 由Sun Java系统RFID事件管理器实现.
名称 描述
FileLogger Logger that writes out PML Core to a file
HttpPmlLogger Logger thats write out PML Core to an HTTP connection
JMSLogger Logger that writes out PML Core to a JMS Queue or Topic
SocketLogger Creates a Socket connection and starts writing PML Core to the connection
SsocketLogger Creates a Server Socket connection and starts writing PML Core to the connection

The user configures the adapters, filters and loggers properties through an XML configuration file. The adapters, filters and loggers are tied to one another by use of a special tag in the configuration file. Figure 3 below illustrates the design and syntax of the XML configuration file. The dotted lines imply that the associated elements or components are optional. Zero or more of each can be present.


Figure 3: Illustration of Sun Java System RFID Event Manager Configuration File

The following attributes define the Adapters of the RFID Event Manager:

1. name: The unique name for the component.
2. classname: The name of the Java class that implements the component.
3. LogLevel: The LogLevel parameter specifies the detail of logging information to be generated by the Adapter. The settings follow java.util.logging conventions established in the J2SE release of the Java VM.
4. properties: A sequence of name value pairs.
5. outputs: a sequence of component names that will be registered as event listeners to this adapter. The outputs normally designate one or more filters, or loggers.

Some of the common properties include:

1. Reader Hostname
2. Reader EPC identifier
3. Log Level


Anatomy of an EPC
EPC can be represented as a URI (Uniform Resource Identifier) to enable the data exchange between software systems. EPC URI are based on the EPC Tag Data Standards defined by EPCglobal. These standards define completely that portion of EPC tag data that is standardized, including how that data is encoded on the EPC tag itself (that is, the EPC Tag Encodings), as well as how it is encoded for use in the information systems layers of the EPC Systems Network (the EPC URI or Uniform Resource Identifier Encodings). The EPC Tag Encodings include a Header field followed by one or more Value Fields. The Header field defines the overall length and format of the Values Fields. The Value Fields contain a unique EPC Identifier and optional Filter Value when the latter is judged to be important to enable effective and efficient reading of the EPC tags.

The EPC encoded in an RFID tag can identify the manufacturer, product, version and serial number, and also provides an extra set of digits to identify unique items.

For various industries, the EPC identifier specifies various coding schemes:

* General Identifier (GID)
* Serialized version of the EAN.UCC Global Trade Item Number (GTIN)
* EAN.UCC Serial Shipping Container Code (SSCC)
* EAN.UCC Global Location Number (GLN)
* EAN.UCC Global Returnable Asset Identifier (GRAI)
* EAN.UCC Global Individual Asset Identifier (GIAI)

Given EPC data, its header field indicates which coding scheme can be applied. The standard URI representation of EPCs has 4 categories:

1. URIs for pure identities (also called canonical forms) which contains only the EPC fields to identify a physical object. For example, a pure identity URI for GID can be "urn:epc:id:gid:10.1002.2" and a URI for GRAI can be "urn:epc:id:grai:0652642.12345.1234."
2. URIs for EPC Tags which represents the tag encodings. These URIs can be used by application software to write a tag. An example for a Serialized GTIN 64-bit encoding is "urn:epc:tag:sgtin-64:3.0652642.800031.400."
3. URIs for Raw Bit Strings which represent invalid bit-level patterns as a single decimal number. For example: "urn:epc:raw:64.20018283527919."
4. URIs for EPC Patterns. Each pattern URI refers to a set a EPCs for the EPC filtering purpose. For example: a pattern "urn:epc:pat:sgtin-64:3.0652642.[1024-2047].*" refers to any SGTIN Identifier 64-bit tag with Filter value as 3, Company Prefix as 0652642, Item Reference in the range from 1024 to 2047 and any Serial Number.

For further details, EPC TagData Standards Specification.

Anatomy of a PML message

The RFID Event Manager loggers output PMLCore XML messages, conformant to version 1.0 of the specification published by the Auto-ID Center. The specifications can be located here. The snippet below is a PML message sent by the Event Manager corresponding to a TagsIn event, ie, when a tagged item comes in view of an antenna. A similar event with a command TagsOut is sent when a tagged item goes out of view of an antenna.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!-- The root element of PML Core -->
<Sensor xmlns="urn:autoid:specification:interchange:PMLCore:xml:schema:1">
<!--The EPC of the reader specified in the RFID Event Manager configuration file for the Reader adapter -->
<ns1:ID xmlns:ns1="urn:autoid:specification:universal:Identifier:xml:schema:1">urn:epc:id:gid:1.1.3</ns1:ID>
<!-- The root element for an observation -->
<Observation>
<ns2:ID xmlns:ns2="urn:autoid:specification:universal:Identifier:xml:schema:1">4</ns2:ID>
<!-- The time when the observation was recorded by the RFID Event Manager -->
<DateTime>2004-05-27T15:36:25.758-07:00</DateTime>
<!--If the PML is generated from a Delta Event, the value of Command is either TagsIn or TagsOut -->
<Command>TagsIn</Command>
<!-- A tag observation -->
<Tag>
<!-- The EPC of the observed tag -->
<ns3:ID xmlns:ns3="urn:autoid:specification:universal:Identifier:xml:schema:1">urn:epc:id:gid:1.1.209</ns3:ID>
</Tag>
</Observation>
</Sensor>

The Sensor element is the main interchange element for PML Core messaging. This element is a composite element comprised of the following subordinate elements:

* ID element
* one or more Observation elements

The Sensor element captures sensor information. A sensor is considered any device that makes measurements and observations. Sensors in the EPC Network are identified by an identifier code. The default identification scheme should be the EPC.

The ID element follows EPC as the default identification scheme to uniquely identify sensors and tags. The use of other identification scheme is supported, but is not encouraged. The EPC is represented as a URI as specified in [EPC] or later versions of this specification.

Each Observation element contains data that are the result of a measurement by a particular sensor. Each observation must be labeled with date and time. It can also be equipped with a unique ID, and a reference to the kind of command that was issued to make the observation. The Observation element consists of the following:

* an optional ID element
* an optional Command element
* DateTime element
* zero or more Data elements
* zero or more Tag elements

The DateTime element captures the date and time when the observation was made. It is based on the [XSD] data type. The Command element can be used to specify the command that was issued to trigger the observation. The Tag element is a special kind of observed value introduced with recognition of the importance of automatic identifications in the EPC network. The tag entity represents any device that can be detected by a sensor. The Tag element consists of the following elements:

* ID element
* optional Data element
* zero or more Sensor elements

All ID elements follow the EPC as the default identification scheme to uniquely identify sensors and tags.

urn:epc:id:gid:1.1.3 is the unique ID of the Reader and Antenna encoded in the GID EPC scheme. A reader can have a unique EPC for each associated antennae, or if the EPC for each antennae is not specified, all antennae will inherit the reader EPC. If the unique EPC for each Reader-antenna is mapped to the location of the antenna, it can be used to track the location of the tagged item as it is scanned by the antenna. urn:epc:id:gid:1.1.209 is the unique EPC number of the tagged item read by the RFID reader represented in GID URI format.

RFID Implementation Hurdles

Theoretically, automating product scanning should make RFID simpler to operate than bar-code technology. However, in many ways, the technology's increased capabilities make it more challenging.

The most basic challenge is managing data. Unlike bar-code technology, where information is scanned only when someone passes a printed label in front of a reader, RF scanning is always on. Consequently, RFID systems must filter data that is constantly streaming in. Additionally, these systems must contend with physical factors that may interfere with RFID's use of radio waves. Warehouses and plants that have electric motors and metal obstructions can have electromagnetic interference. Product materials?liquids or metals?may absorb or reflect RF signals.

As with supply chain integration, RFID technology has the potential to allow suppliers, customers, and other firms in the industry access to critical competitive information. However, with RFID it could be used to gather the information clandestinely because it is so anonymous.

The IDs on passive RFID cards can easily be stolen using a sniffer and a power source without the knowledge or consent of the ID's owner. One major problem with passive RFID systems is that the power source comes from the receiver, not from within the RFID tag itself. This makes the tags cheaper and more robust, but it also makes them vastly less secure. Unless the encryption is very good, the RFID unique identifiers can be duplicated.

Future
To date, only the EPC Tag Data Standards Version 1.1 is finalized. The term Savant is deprecated. Savant standards 1.0 are in the process of being replaced by specifications and standards focused on Event Manager, Reader Management, Reader Protocol, Filtering and Collection, and EPCIS.

References

[XSD] XML Schema Part 2: Datatypes W3C Recommendation, 02 May 2001 http://www.w3.org/TR/xmlschema-2/

[EPC] Michael Mealling and Ken Traub, The URI Representation of the Electronic Product Code and Related Types , Working Draft Version, 12 August 2003 EPC Global http://www.epcglobalinc.com

EPC Tag Data Standards Version 1.1 http://www.epcglobalinc.com/standards_technology/EPCTagDataSpecification11rev124.pdf

PML Core specification 1.0 http://www.epcglobalinc.com/standards_technology/Secure/v1.0/PML_Core_Specification_v1.0.pdf

Auto-ID Savant Specification 1.0 http://www.epcglobalinc.com/standards_technology/specifications.html

Auto-ID Reader Protocol Specification 1.0 http://www.epcglobalinc.com/standards_technology/specifications.html

Sun Java System RFID Software Product Documentation http://docs.sun.com/db/coll/RFID_04q3

EPC and RFID: Enabling the Next Level of Business Efficiencies http://wwws.sun.com/software/solutions/rfid/index.html

The Sun RFID Test Center http://wwws.sun.com/software/solutions/rfid/testcenter/index.html

The Sun" EPC Network Architecture http://wwws.sun.com/software/solutions/rfid/EPCNetArch_wp021304a.pdf

The RFID Journal http://www.rfidjournal.com/

Acknowledgements
The author would like to thank Ricardo Labiaga of the RFID engineering team at Sun for his input, help and guidance in writing this paper.

About the Authors

Alka Gupta is a member of the Technical Staff at Sun Microsystems. She's responsible for working with Sun's ISV's and partners to help them adopt the emerging Sun technologies and platforms quickly and efficiently. Alka has been in this industry for nearly 10 years. Alka graduated from the Indian Institute of Technology (IIT), India.

Mayank Srivastava is a Software Engineering Manager in Market Development Engineering, at Sun Microsystems. In this capacity, Mayank's group responsibilities include providing help to ISVs to adopt Sun's technology and systems.

星期六, 十月 09, 2004

如何在Java网络程序中动态使用Proxy Server?

如何在Java网络程序中动态使用Proxy Server?

方法一:

设置HTTP:

System.setProperty("http.proxyHost","proxy-server-ip");//代理服务器IP
System.setProperty("http.proxyPort","proxy-server-port");//代理服务器端口


设置HTTPS:

System.setProperty("https.proxyHost","proxy-server-ip");
System.setProperty("https.proxyPort","proxy-server-port");


Java应用程序命令行

java -Dhttp.proxyHost=proxy-server-ip -Dhttp.proxyPort=proxy-server-port filename
或者:
方法二:
System.getProperties().put( "proxySet", "true" );
System.getProperties().put( "proxyHost", "some_proxy" );
System.getProperties().put( "proxyPort", "8080" );
java -DproxySet=true -DproxyHost=some_proxy -DproxyPort=8080 SomeClass

Sun提供的基于Java的RSS功能包.

http://java.sun.com/developer/technicalArticles/javaserverpages/rss_utilities/

星期五, 十月 08, 2004

IE和FireFox 1.0 对Div align 对齐方式的差异

KeyWords:div,align.FireFox,Iexporer
IE 6.0 sp1和FireFox 1.0默认
对齐的方式刚好相反。
IE如果不显示指定对齐方式,是右对齐。而FireFox 1.0是左对齐。
:).
是指包含的内容对齐的方式.
所以如果有多个
嵌套,最好指明对齐方式.
通过style的float属性来指明.
如:
<div align="right" id="friendlist" style="float: right;border: 1px dotted #eeeeee;width:95%; z-index:3;overflow-y: scroll;">
这样就指明了div的边为一个象素的虚线宽度为空间的95%.

如何在IE中使用XML和XSLT来表现数据.

<HTML>
<HEAD>
<TITLE>sample</TITLE>
<SCRIPT language = "javascript">
function init()
{

var basicinfo = new ActiveXObject("Msxml2.DOMDocument.4.0");
var employment = new ActiveXObject("Msxml2.DOMDocument.4.0");
var paycatagory = new ActiveXObject("Msxml2.DOMDocument.4.0");
var attendence = new ActiveXObject("Msxml2.DOMDocument.4.0");
var mainpage = new ActiveXObject("Msxml2.DOMDocument.4.0");

mainpage.async=false;
mainpage.validateOnParse=true;

basicinfo.async=false;
basicinfo.validateOnParse=true;


employment.async=false;
employment.validateOnParse=true;

paycatagory.async=false;
paycatagory.validateOnParse=true;

attendence.async=false;
attendence.validateOnParse=true;

// You can substitute other XML file names here.
try
{
mainpage.load("hello.xml");
errorValid(mainpage);

basicinfo.load("emp_M_Basicinfo.xml");
errorValid(basicinfo);

employment.load("emp_M_EmploymentInfo.xml");
errorValid(employment);

attendence.load("attendence.xml");
errorValid(attendence);

paycatagory.load("pay_M_CatagoryItem.xml");
errorValid(paycatagory);

}catch(e)
{
alert("error:");
}
//Display basicinfo nodeset
// alert(basicinfo.documentElement.childNodes.item(0).xml);

var xslt = new ActiveXObject("Msxml2.XSLTemplate.4.0");
var xsltTree= new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0");

xsltTree.async = false;
// You can substitute other XSLT file names here.
xsltTree.load("hello.xslt");
xslt.stylesheet = xsltTree

xslProc = xslt.createProcessor();

xslProc.input = mainpage
try
{
xslProc.addParameter("basicinfo",basicinfo.documentElement);//.selectNodes("/Results")
xslProc.addParameter("employment",employment.documentElement);
xslProc.addParameter("paycatagory",paycatagory.documentElement);
xslProc.addParameter("attendence",attendence.documentElement);
xslProc.addParameter("yourname","William Wang");
}catch(e)
{
alert(e);
}
xslProc.transform();

resTree.innerHTML = xslProc.output;

// Save the result of the XSL transformation

//htmlCode = xslProc.output
//fso=new ActiveXObject("Scripting.FileSystemObject")
//htmlFile=fso.CreateTextFile("sample.html",true)
//htmlFile.WriteLine(htmlCode)
//htmlFile.Close()
}
function errorValid(errorObject)
{
if (errorObject.parseError.errorCode != 0)
{
var strErrMsg = "Problem Parsing Style Sheet:\n"
+ " Error #: " + errorObject.parseError.errorCode + "\n"
+ " Description: " + errorObject.parseError.reason + "\n"
+ " In file: " + errorObject.parseError.url + "\n"
+ " Line #: " + errorObject.parseError.line + "\n"
+ " Character # in line: " + errorObject.parseError.linepos + "\n"
+ " Character # in file: " + errorObject.parseError.filepos + "\n"
+ " Source line: " + errorObject.parseError.srcText;
alert(strErrMsg);
}

}
</SCRIPT>
</HEAD>
<BODY onload = "init()" >
<div id="resTree"></div>
</BODY>
</HTML>

IE 6.0和FireFox 1.0 Pr 关于XMLHttpRequestS 对象引用的差异

XMLHttpRequest一个有价值的用途,就是在后台反复使用XMLHttpRequest的对象引用来从服务器获取数据.叫做round-trip模式.
但是IE6不能保存XMLHttpRequest的引用在变量中,这是需要注意的.
如果需要多次使用,必须每次都生成XMLHttpRequest的对象引用.如下代码.

sniffer代码:

var http;
if (window.XMLHttpRequest) //FireFox系列
{
http = new XMLHttpRequest();
http.onload =processReqChange;//注意:是onload事件
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
}else if (window.ActiveXObject)//IE
{
http = new ActiveXObject("Msxml2.XMLHTTP");
http.onreadystatechange = processReqChange;//注意:是onreadystatechange事件.
}

星期三, 十月 06, 2004

Sun终于决定开始整合EJB和JDO有关Persistence layer的表示逻辑了。

原文:Sun对Java社区的公开信
JDO专家组的两个专家将参加EJB 3。0的规范制定.并决定制定单一的POJO persistence Model.
如此一来,EJB和JDO起码在描述Persistence Model和操作技术粒度上保持了一致性.
很好。很大的一步.

星期五, 十月 01, 2004

如何让FireFox 右下角显示出来RSS的提示?

需要在网站也面里加入以下这行话:
<link rel="alternate" type="application/xml" title="RSS" href="http://www.journalspace.com/xml/wang.xml"><title>Technology and Humanist</title>
如何就可以了。

Java的未来:从老虎(Tiger)向野马(Mustang)和海豚(Dolphin)进发

“Tiger one of the most ambitious Java revisions to date”---TTS

Java的未来:从老虎(Tiger)向野马(Mustang)和海豚(Dolphin)进发

英语原文
Posted By: Dion Almaer on September 30, 2004 @ 10:01 AM
目前”老虎”已经发布了,人们很想知道Java的未来计划.Sun公司的Mark Reinhode说明了Java发布模式的改变.将不会有任何维护级别的版本发布.升级的发行版本将按照大约每2-3个月频率发布.
这样可以在发布的版本里同时包含修改的内容.

新的发行计划周期

呼!我可以听到Sun公司内部和外部为了这个令人惊异的产品发出的如释重负的呼出声.
我们希望你能对这个产品有良好的感受.正如我以前所说的,我认为Tiger是自JDK 1.1以来,我们所构造的JDK里质量最高的.

这里似乎应该是向前展望的时候了,并且对我们对J2SE的发布模式修改的一些细节说明.


目前有三种类型的版本发行模式

特征发行版本用大的数目来表示(1.3,1.4,1.5 5.0),包含了成千的错误修正和众多的新特征.
这一般需要间隔24-36个月.

维护发行版本,也叫做”点-点” 发行(1.4.1,1.4.2等等),包含了许多错误修订,但是没有的性API的特征.
这些需要8-10月的间隔.

升级发行版本,也叫做”下画线” 发行(1.4.2_01,1.5.0_01 5.0 update 1),这包含了非常少量的错误修正(一般大约100左右),重要是非常仔细的从客户所遇到的比较紧急的错误.Sun 每3-4个月发布一个版本.向前来讲,我们打算简化我们发行版本的增加的速率.

尤其是:

特征发行版本将每18-24月发布.这是为了平台适合开发人员社团更加快速的演进及同.NET的竞争需要.

将不会有更多的维护版本发布.从Tiger(5.0)开始,将不会有如同1.4.1和1.4.2那里包含1500-2000错误修正的版本.如果这样,将会发布一个5.1版本,但同样包含特别特征的升级发行.

升级发行版本每2-3个月发布一次.这样将尽可能重大错误及时休正发布给用户.

改变一个发行模型对我们而言不是一件轻松的.这是数月来同我们的合作伙伴会谈及社团开发人员会谈的结果.两外两个从这些改变获得好处是:

发布将更加准时.在J2SE工程师组织内部,长期以来我们总是在困难的选择之间角斗:使当前维护发布尽可能的完美对在下一个大的新的特征上工作.这种冲突造成了很多计划超出了时间.新的发布模型解决了这种紧张:J2SE工程师一般情况下总是在为下一个特征发行版本上工作.当他们要求休正错误的时候将在一个升级发行版本中.甚至是更加珍贵的非凡工作(比如性能的提高),都将在一个升级发行版本中完成,当然可能会有异常情况超出这个规则.

发行版本的采用将会提高.已存在的中等规模的版本发行有较大的采用瘴碍.在这种程度的改变许多用户有足够的信心在他们已经限定的所有程序中采用.换句话说,对待他们更像在测试术语中的特征发行.
大多数的用户有足够的信心不做太多的测试而顺便在更新发行版本中使用他们的应用.
现在他们能有更多的时间在两个特征发行版本之间.这些不是容易的改变.
我们目前仍然在描绘出更多细节之中,也许下一个两年不是非常精确的符合我上面描述的内容。
总的来说,我们认为提高关注和增加新的发布模型的灵活性将会给平台和Java社团更大的好处.

星期四, 九月 30, 2004

FireFox中的XML和XSLT的使用及SOAP的引用..

The XSLT/JavaScript Interface In Gecko
这里有几篇文章非常不错.关于在FireFox中的确XML/XSLT的引用.


Updating DHTML Web Pages for next generation browsers
SOAP in Netscape Gecko-based Browsers

Accessing Web Services In Netscape 7.1/Mozilla 1.4 Using WSDL Proxying

Groovy 1.0 beta 7增加了embed 使用的jar库

为了方便在java中调用Groovy,Groovy提供了D:\groovy-1.0-beta-7\embeddable下的groovy-all-1.0-beta-7.jar文件可以包含在Web Module或类似应用中.

Today 2004.9.30.groovy 1 beta 7发表

今天收到Email Notifier说groovy beta 7发布了.
不过看了看change log.文档没有加入,修改的几个BUG.我都没碰到.

有关ClassLoader的问题,也没有修改.

只是一个小小的版本改动.

星期三, 九月 29, 2004

利用XMLHttpRequest对象来提交数据.

Use the XMLHttpRequest Object to Post Data
When using XMLHttpRequest object, there is a way to post data in the same way that an HTML Form is posted.

All you need to do is add an HTTP header, and send the data the same way you'd send it on the QueryString.

Here's a JScript example for the client side, that submits form data to another page:


var objHTTP, strResult;
objHTTP = new ActiveXObject('Microsoft.XMLHTTP');
objHTTP.Open('POST',"OtherPage.asp",false);
objHTTP.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');

objHTTP.send("id=1&user="+txtUser.value+"&password="+txtPassword.value);

strResult=objHTTP.responseText;

星期一, 九月 27, 2004

欢迎你来到异次元空间!

Welcome to the 11th Dimension
自爱因斯坦之后,我们关于时空的最奇幻的构思.

我们处在一个最多11维的时空中.
自1995 Nova发表 Welcome to the 11th Dimension论文以来的进展有多少呢?实验室数据如何设计来证明这个理论呢?

有趣的思考.


图片来自:http://groups.msn.com/Realms-Of-Light/thedivinehologramofspirit.msnw





Nova
The Elegant Universe: Welcome to the 11th Dimension
"The Elegant Universe: Welcome to the 11th Dimension," shows how in 1995 Edward Witten of Princeton's Institute for Advanced Study, aided by others, revolutionized string theory by successfully uniting the five different versions into a single theory that is cryptically named "M-theory," a development which required a total of eleven dimensions. Ten...eleven...who's counting? But the new eleventh dimension is different from all the others, since it implies that strings can come in higher dimensional shapes called membranes, or " branes" for short. These have truly science-fiction-like qualities, since in principle they can be as large as the universe. A brane can even be a universe -- a parallel universe -- and we may be living on one right now. Branes might also explain why gravity is the weakest force, requiring all the matter in the Earth to produce a measly one g. According to this idea, gravity may be far more potent, but most of its strength is leaking into a parallel universe. Witten has described string theory as "a part of 21st-century physics that fell by chance into the 20th century." In fact, the theory is so far ahead of experimental technique that there is as yet no way to verify whether strings are real or a figment of some very creative imaginations. But scientists at the CERN atom-smasher on the French- Swiss border are working to test of one of the predictions of string theory. Scheduled to run later in this decade, this experiment may take an important step in showing that string theory is not just a crazy idea, but crazy reality. (CC) (D)

如何让Google机器人搜索自己的网站呢?

Knowledge website 1:
http://webdesign.about.com/cs/googleoptimization/
关于SEO(Search Engine Optimized)的话题很久了.
但是我不知道Googlebot关于robots.txt和<meta name="Googlebot" content="index,follow"/>
的优先级别顺序是怎样的?
所以需要测试.不过先把<meta>标志加入网页再说其他了.:)

星期五, 九月 24, 2004

B/S开发的新里程碑(B/S application Milestone)XMLHttpRequest

Dynamic HTML and XML: The XMLHttpRequest Object
动态HTML及XML:介绍XMLHttpRequest对象
(翻译:有增删:原文见:TaH Website
随着XML数据和Web服务的部署越来越普遍,你偶尔会觉的如果在HTML表现层不需要刷新页面而直接
得到XML数据来更新中间状态也是非常方便的.要感谢可爱的 XMLHttpRequest对象,可以在后台直接
提交或获得XML 数据,这扩展了Web Client的使用范围.
为了改变接受到的XML 数据并渲染成HTML内容,依赖于客户端DOM读取XML文档节点树组成用户最终
看见的HTML元素

历史和支持

Microsoft首先在IE 5 window版本用ActiveX技术实现了XMLHttpRequest对象.Mozilla 项目的工程
师们实现了兼容的本地版本Mozilla 1.0(及Netscape 7).Apple在Safari 1.2上完成了同样的工作.

包含W3C标准期望的相似的功能,DOM level 3载入及保存规范.同时随着支持XMLHttpRequest对象意味着这已经成为事实的标准.以后W3C的规范最终应该会支持它并且所有的browser都会支持的。

如何建立对象?

建立一个XMLHttpRequest对象要求根据不同的Browser用不同的方式来实例化对象.对Safari和
Mozila系列.简单调用对象的constructor功能就可以完成这个:
var req = new XMLHttpRequest();

对使用ActiveX的对象,通过传递对象名称来建立:
var req = new ActiveXObject("Microsoft.XMLHTTP");
两种构造方法都返回一个抽象对象的引用.它的方法控制所有的操作,同时他的属性从服务器返回的数据

对象方法

XMLHttpRequest对象在所有支持的环境中使用都非常简明,但是非常强大,列表所有的方法和属性

Table 1显示Safari 1.2,Mozilla及IE 5及以后的windows版本.

Table 1. 一般XMLHttpRequest对象方法







方法描述
abort() 停止当前请求
getAllResponseHeaders()返回一组标题头(标识及其值)字符串
getResponseHeader("headerLabel")返回指定头标识的字符串值
open("method", "URL"[, asyncFlag[, "userName"[, "password"]]])给一个等待状态的请求制定目标URL,方法及其它可选的属性
send(content)发送请求,另外可以附加提交的字符传或DOM对象数据
setRequestHeader("label", "value")跟随请求设定指顶的标题标识及其值.


在Table 1中显示的方法.open()和send()方法可能是你最常用的.
首先open(),用来设置一个将要用的操作场景.两个必须的参数是你将要请求的HTTP方法和连接的目
的URL.对于method参数,你可以设置"GET"接受基本数据.然后使用"POST"发送数据到服务器,尤其是数据可能大于512字节.URL可以是绝对或相对地址(不过可能引起Browser安全问题)

重要的第三个选项参数是Boolean值用来控制是否将来的事物是否异步.默认的行为是true既异步,
这表示脚本进程在调用send()后立即返回不要等待回应.如果你设置这个值为false,那么,脚本将等
到服务器返回数据为止.看起来似乎等待服务器返回数据再继续脚本进程是个好主意.但是这样做可能导致脚本因为网络或服务器问题而不能完成事务,导致脚本挂死.一个安全的主意是用send 异步操作方式,但把代码挂在onreadstatechange事件上是个好主意.
如下例:
var req;

function loadXMLDoc(url) {
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send(null);
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send();
}
}
}

注意:从服务器返回的数据必须保证Content-Type是:text/xml 内容设置为text/plain或text/html
不被request对象接受.

对象属性

Table 2. 所有属性都是只读的
Table 2. 常见 XMLHttpRequest对象属性










属性说明
onreadystatechange当每个状态改变时产生的事件
ReadyState对象状态整数0 = uninitialized1 = loading2 = loaded3 = interactive4 = complete
responseText服务器返回结果的字符串样本
responseXMLDOM规范的服务器返回结果
status Numericcode returned by server, such as 404 for "Not Found" or 200 for "OK"
statusTextString message accompanying the status code


使用onreadystatechang属性用来挂上函数来出去request对象状态改变事件.这样当对象状态改变的时候,就会调用函数处理.
你必须使用更多信息来确定挂上的回掉函数如何处理信息.判断readstate是多少或通过判断status或statusText来确定过程是成功或失败.成功为200或ok.

通过responseText或responseXML来处理服务器返回的结果
如下:
function processReqChange() {
// only if req shows "loaded"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
// ...processing statements go here...
} else {
alert("There was a problem retrieving the XML data:\n" +
req.statusText);
}
}
}

如果你关心timeout的服务器问题.你可以修改上面的loadXMLDoc函数保留处理时间戳.当超过可接受 限制的时候,调用abort()函数来放弃操作,然后给出警告既可.

安全问题

当在browser使用XMLHttpRequest对象时候,默认采用同一domain的安全规则.(共享同一"沙盒")
这会引起重要的安全问题.

大多数browser支持通过http:协议来访问需要接受的对象.这意味着你不能使用在本地硬盘的测试页面.实际上,Mozilla要求你包装UniversalBrowserRead安全权限.而IE简单显示一个安全警告框,给你一个取消的机会.
以下是Mozilla包装安全授权的代码:
try
{
http.open("GET", "http://wang.journalspace.com", true);
}catch(e)
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
http.open("GET", "http://wang.journalspace.com", true);
http.onreadystatechange=function() {
if (http.readyState==4) {
alert(http.responseText);
document.getElementById('content').innerHTML=http.responseText;
}



许多年来,高级客户段开发人员经常想用一种清晰的方法来维护同服务器之间的"Connection".
这样能保证事务发生在后台.许多技术要求使用自刷新的frame或无脸的java applet技术.
在W3C标准依然在开发的时候.Microsft的XMLHttpRequest对象填充了这一空白,将鼓舞应用开发的
创新.

如何使用XMLHttpRequest和DIV来动态载入内容

这段代码为Mozilla运行.IE代码不同 .

红色的为关键代码。
<div id=content name="content" width=80% heigth=80% >
wait
</div>
<script>
var http;
http = new XMLHttpRequest();
try
{
http.open("GET", "http://wang.journalspace.com", true);
}catch(e)
{
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
//弹出安全限制对话框,要用户授权。
http.open("GET", "http://wang.journalspace.com", true);
http.onreadystatechange=function() {
if (http.readyState==4) {
alert(http.responseText);
document.getElementById('content').innerHTML=http.responseText;
}
}
document.getElementById('content').innerHTML="Wait...";
http.send('');
}

</script>

Signed Scripts in Mozilla

很好,对Mozilla(FireFox)如何获得Javascript信任给出了代码
http://www.mozilla.org/projects/security/components/signed-scripts.html

星期四, 九月 23, 2004

MySql如何增加一个新用户或改密码.

SET PASSWORD FOR root@"%" = PASSWORD('xxxxx');

GRANT ALL PRIVILEGES ON *.* TO ehrm@"myhost" IDENTIFIED BY 'xxxxx' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO ehrm@"%" IDENTIFIED BY 'xxxxx' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO ehrm@localhost IDENTIFIED BY 'xxxxx' WITH GRANT OPTION;

FLUSH PRIVILEGES;

利用IE6和Javascript同服务器交互

Use the XMLHttpRequest Object to Post Data
When using XMLHttpRequest object, there is a way to post data in the same way that an HTML Form is posted.

All you need to do is add an HTTP header, and send the data the same way you'd send it on the QueryString.

Here's a JScript example for the client side, that submits form data to another page:


var objHTTP, strResult;
objHTTP = new ActiveXObject('Microsoft.XMLHTTP');
objHTTP.Open('POST',"OtherPage.asp",false);
objHTTP.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');

objHTTP.send("id=1&user="+txtUser.value+"&password="+txtPassword.value);

strResult=objHTTP.responseText;

Javascript 同Regua参考资料

STRING MATCHING AND REPLACING IN JAVASCRIPT 1.2

http://developer.netscape.com/viewsource/angus_strings.html

及通过.prototype扩展Javascript的功能.
http://www.javascriptkit.com/javatutors/proto4.shtml

星期三, 九月 22, 2004

如何避免GroovyClassLoader Defect 不足.避免动态类占用内存资源.

在Java 使用Groovy经典代码:
GroovyShell _shell=new GroovyShell(new Binding());
String text="tax=0.4; return 1000*tax;";
for(int i=0;i<3000;i++)
{
System.out.println(_shell.evaluate(text,"textScript.groovy"));
}

通过使用GroovyShell.evaluate(String script,String fileName)可以避免同一段脚本,被GroovyShell生成多个动态类保存在cache里.

如何使用JAX-RPC使用Java Object 当做Web Service

JAX-RPC (http://java.sun.com/xml/jaxrpc/index.jsp)是一组Java API 为了使用基于XML的远程调用.
详细内容参考http://java.sun.com/developer/EJTechTips/2004/tt0824.html#1

星期二, 九月 21, 2004

如何利用Dynamic ClassLoader 来动态载入Class

以GroovyClassloader为例子:
import groovy.lang.GroovyShell;
import groovy.lang.Binding;
import groovy.lang.Closure;
import groovy.lang.Script;
import groovy.lang.*;


public class testGroovyMemoryLeak
{

public static void main(String[] args) throws Exception
{
String text="tax=0.4; return 1000*tax;";
ClassLoader parent = Thread.currentThread().getContextClassLoader();
GroovyObject groovyObject=null;
GroovyClassLoader loader=null;
Class groovyClass =null;
Object temp=null;
for(int i=0;i<3000;i++)
{
loader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
groovyClass = loader.parseClass(text);
groovyObject = (GroovyObject) groovyClass.newInstance();
temp = groovyObject.invokeMethod("run", args);
System.out.println("value="+temp);
temp=null;
loader=null;
System.gc();
}
}
}

星期一, 九月 20, 2004

Java Groovy 1.0 beta 6避免GroovyClassloader不能GC Class的问题

Groovy 1.0 beta 6 GroovyclassLoader使用Dynamic ClassLoader技术,
不能回收解析脚本动态产生的Scriptxxxx class.

原因是Groovy MetaClass使用了 static HashMap 来cache生成的class.

解决办法,模拟groovy 自己产生一个GroovyObject Arrays.
然后,把动态生成的GroovyObject放入数组,只生成一次,以后直接从数组中载入Class对象实例。

星期日, 九月 19, 2004

TTS Ask:What do you want in Next Java?

My Prioriry:

1.Better NullPointerException display(臭名远播的NPE问题)
display what name and property get Null
2.Dynamic class
通过申明生成动态类(如果Groovy加入很多问题就解决了)
3.改善ClassLoader behavior
JVM ClassLoader drive me madness.要求清晰简单的行为定义
4.Raw Socket Support
本地Socket支持。哈。这样大多数黑客(Cracker)软件就用Java development了。:)
5.XML/XSLT/XPATH支持.目前的JAXP使用太复杂了。典型的过度设计(over Designed)
6.discard setter 和getter 在Bean上的使用。
目前的沉闷的getter和setter对策略让人发疯。为什么不使用bean.propetyName直接引用呢?
7.Debug 功能要加强
包括#ifdef macro和JVM DUMP及Heap snapshot功能。Third Part module is argly.

What is Next Bigger Feature of Java?

自从接触了Groovy,最赞赏的特征是Closure(闭合)。
今天看到TSS上也有人赞赏加入Closure在下一个版本中。
自从J2SE 5.0发布后,支持Closure成了一个水到渠成的步骤。
因为AutoBox,AutoUnbox和Generetor泛型的支持已经为
J2SE支持Closure的自然加入了低层支持。
在C# 2中加入了匿名代理的功能,从设计角度来说,提供了基本相识的功能。
其实JVM只要在inner class的基础上加上Autobox和Generetor的提高。
基本上可以提供Closure的功能了。不过很多Closure可以提供的比如data Pine
依然无法提供。

所以最好重新设计Closure替代inner class.

原文:
http://www.theserverside.com/news/thread.tss?thread_id=28808

星期六, 九月 18, 2004

关于Java ClassLoader和Groovy Temporary Class Load and Unload

终于弄清了原因.

在Java 中通过GroovyShell或GroovyClassloader来调用存放在数据库中的脚本,Groovy 编译会产生大量的Scriptxxx,xxx表示顺序好的临时class,这些class根据java classloader的规范,就存放在cache中了。
所以一个循环调用Groovy script脚本,会引起内存为了保存这些临时class产生大量的空间。

为了避免ClassLoader对这些class的引用。
需要每次执行脚本时候,必须生成一个新的ClassLoader来调用,然后释放掉。

这样就可以让JVM回收这些空间了。
代码:

星期五, 九月 17, 2004

关于Java GC(Gargabe Collection)回收的机制

按:Groovy Shell似乎leak memory,所以找了一些JVM泄露泄露内存的资料.备查找.

The Truth About Garbage Collection


Garbage collection (GC) is probably the most widely misunderstood feature
of the Java platform. GC is typically advertised as removing all memory management
responsibility from the application developer. This just isn't the case. On the
other hand, some developers bend over backwards trying to please the collector,
and often wind up doing much more work than is required. A solid understanding
of the garbage collection model is essential to writing robust, high-performance
software for the Java platform.


This appendix provides an overview of the garbage collection mechanisms that will help you make intelligent choices about memory management issues. It also contains information to help you debug complex problems such as memory leaks.


A.1 Why Should You Care About Garbage Collection?



The cost of allocating and collecting memory can play a significant role in how
your software performs. The overall memory requirements of your software can
have a huge impact on the speed of your program when large RAM requirements
force the OS to use virtual memory. This often occurs when memory is allocated,
but not properly released. Although the JVM is responsible for freeing unused
memory, you have to make it clear what is unused. To write successful, large-scale
programs, you need to understand the basics of the GC mechanism.



A.2 The Guarantees of GC


The specification for the Java platform makes very few promises about how garbage
collection actually works. Here is what the
Java Virtual Machine Specification
(JVMS) has to say about memory management.


The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java virtual machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements.1


While it can seem confusing, the fact that the garbage collection model is not rigidly defined is actually important and useful-a rigidly defined garbage collection model might be impossible to implement on all platforms. Similarly, it might preclude useful optimizations and hurt the performance of the platform in the long term.



Although there is no one place that contains a full definition of required garbage collector behavior, much of the GC model is implicitly specified through a number of sections in the Java Language Specification and JVMS. While there are no guarantees about the exact process followed, all compliant virtual machines share the basic object lifecycle described in this chapter.


A.3 The Object Lifecycle



In order to discuss garbage collection, it is first useful to examine the object
lifecycle. An object typically goes through most of the following states between
the time it is allocated and the time its resources are finally returned to the system
for reuse.



  1. Created

  2. In use (strongly reachable)


  3. Invisible

  4. Unreachable

  5. Collected

  6. Finalized

  7. Deallocated



A.3.1 Created




When an object is created, several things occur:2



  1. Space is allocated for the object.

  2. Object construction begins.

  3. The superclass constructor is called.

  4. Instance initializers and instance variable initializers are run.


  5. The rest of constructor body is executed.



The exact costs of these operations depend on the implementation of the JVM, as
well as the implementation of the class being constructed. The thing to keep in
mind is that these costs exist. Once the object has been created, assuming it is
assigned to some variable, it moves directly to the in use state.


A.3.2 In Use



Objects that are held by at least one strong reference are considered to be in use.
In JDK 1.1.x, all references are strong references. Java 2 introduces three other
kinds of references: weak, soft and phantom. (These reference types are discussed
in
Section A.4.1.) The example shown in Listing A-1 creates an object and assigns
it to some variables.

public class CatTest {
static Vector catList = new Vector();
static void makeCat() {
Object cat = new Cat();
catList.addElement(cat);
}

public static void main(String[] arg) {
makeCat();
// do more stuff
}
}



Creating and referencing an object


Figure A-1 shows the structure of the objects inside the VM just before the makeCat method returns. At that moment, two strong references point to the Cat object.

Object reference graph




When the makeCat method returns, the stack frame for that method and any temporary variables it declares are removed. This leaves the Cat object with just a single reference from the catList static variable (indirectly via the Vector).


A.3.3 Invisible



An object is in the invisible state when there are no longer any strong references
that are accessible to the program, even though there might still be references. Not
all objects go through this state, and it has been a source of confusion for some developers.
Listing A-2 shows a code fragment that creates an invisible object.

public void run() {
try {
Object foo = new Object();
foo.doSomething();
} catch (Exception e) {
// whatever
}
while (true) { // do stuff } // loop forever
}

Invisible object



In this example, the object foo falls out of scope when the try block finishes. It might seem that the foo temporary reference variable would be pulled off the stack at this point and the associated object would become unreachable. After all, once the try block finishes, there is no syntax defined that would allow the program to access the object again. However, an efficient implementation of the JVM is unlikely to zero the reference when it goes out of scope. The object referenced by foo continues to be strongly referenced, at least until the run method returns. In this case, that might not happen for a long time. Because invisible objects can't be collected, this is a possible cause of memory leaks. If you run into this situation, you might have to explicitly null your references to enable garbage collection.


A.3.4 Unreachable



An object enters an unreachable state when no more strong references to it exist.
When an object is unreachable, it is a candidate for collection. Note the wording:
Just because an object is a candidate for collection doesn't mean it will be immediately
collected. The JVM is free to delay collection until there is an immediate
need for the memory being consumed by the object.


It's important to note that not just any strong reference will hold an object in memory. These must be references that chain from a garbage collection root. GC roots are a special class of variable that includes




  • Temporary variables on the stack (of any thread)

  • Static variables (from any class)

  • Special references from JNI native code


Circular strong references don't necessarily cause memory leaks. Consider the code in Listing A-3. It creates two objects, and assigns them references to each other.

public void buidDog() {
Dog newDog = new Dog();
Tail newTail = new Tail();
newDog.tail = newTail;
newTail.dog = newDog;
}

Circular reference



Figure A-2 shows the reference graph for the objects before the buildDog method returns. Before the method returns, there are strong references from the temporary stack variables in the buildDog method pointing to both the Dog and the Tail.

Reference graph before buildDog returns




Reference graph after buildDog returns




Figure A-3 shows the graph for the objects after the buildDog method returns. At this point, the Dog and Tail both become unreachable from a root and are candidates for collection (although the VM might not actually collect these objects for an indefinite amount of time).


A.3.5 Collected



An object is in the collected state when the garbage collector has recognized an
object as unreachable and readies it for final processing as a precursor to deallocation.
If the object has a finalize method, then it is marked for finalization. If it
does not have a finalizer then it moves straight to the finalized state.


If a class defines a finalizer, then any instance of that class must have the finalizer called prior to deallocation. This means that deallocation is delayed by the inclusion of a finalizer.



A.3.6 Finalized



An object is in the finalized state if it is still unreachable after its finalize
method, if any, has been run. A finalized object is awaiting deallocation. Note that
the VM implementation controls when the finalizer is run. The only thing that can
be said for certain is that adding a finalizer will extend the lifetime of an object.
This means that adding finalizers to objects that you intend to be short-lived is a
bad idea. You are almost always better off doing your own cleanup instead of relying
on a finalizer. Using a finalizer can also leave behind critical resources that
won't be recovered for an indeterminate amount of time. If you are considering
using a finalizer to ensure that important resources are freed in a timely manner,
you might want to reconsider.


One case where a finalize method delayed GC was discovered by the quality assurance (QA) team working on Swing. The QA team created a stress testing application that simulated user input by using a thread to send artificial events to the GUI. Running on one version of the toolkit, the application reported an OutOfMemoryError after just a few minutes of testing. The problem was finally traced back to the fact that the thread sending the events was running at a higher priority than the finalizer thread. The program ran out of memory because about 10,000 Graphics objects were held in the finalizer queue waiting for a chance to run their finalizers. It turned out that these Graphics objects were holding onto fairly substantial native resources. The problem was fixed by assuring that whenever Swing is done with a Graphics object, dispose is called to ensure that the native resources are freed as soon as possible.


In addition to lengthening object lifetimes, finalize methods can increase object size. For example, some JVMs, such as the classic JVM implementation, add an extra hidden field to objects with finalize methods so that they can be held in a linked list finalization queue.


A.3.7 Deallocated



The deallocated state is the final step in garbage collection. If an object is still unreachable
after all the above work has occurred, then it is a candidate for deallocation.
Again, when and how deallocation occurs is up to the JVM.


A.4 Reference Objects




Prior to the introduction of the Java 2 platform, all references were strong
references. This meant that there was no way for the developer to interact with the
garbage collector, except through brute force methods such as System.gc.


The java.lang.ref package was introduced as part of Java 2. Figure A-4 shows the class hierarchy for the classes in this package. This package defines reference-object classes that enable a limited degree of interaction with the garbage collector. Reference objects are used to maintain a reference to some other object in such a way that the collector can still reclaim the target object. As you might expect, the addition of these new reference objects complicates the concept of reachability as defined in the object lifecycle. Understanding this is important,
even if you don't intend to make direct use of this package. Some of the core class libraries use WeakReferences internally, so you might encounter them while using memory profilers to track memory usage.
Reference class hierarchy




A.4.1 Types of Reference Objects




Three types of reference objects are provided, each weaker than the last: soft,
weak, and phantom. Each type corresponds to a different level of reachability:



  • Soft references are for implementing memory-sensitive caches.

  • Weak references are for implementing mappings that do not prevent their keys
    (or values) from being reclaimed.



  • Phantom references are for scheduling pre-mortem cleanup actions in a more
    flexible way than is possible with the Java finalization mechanism.

    Going from strongest to weakest, the different levels of reachability reflect the
    lifecycle of an object:



    • An object is strongly reachable if some thread can reach it without traversing
      any reference objects.

    • An object is softly reachable if it is not strongly reachable but can be reached
      by traversing a soft reference.


    • An object is weakly reachable if it is neither strongly nor softly reachable but
      can be reached by traversing a weak reference. When the weak references
      to a weakly reachable object are cleared, the object becomes eligible for
      finalization.

    • An object is phantom reachable if it is neither strongly, softly, nor weakly
      reachable, it has been finalized, and some phantom reference refers to it.

    • An object is unreachable, and therefore eligible for reclamation, when it is not
      reachable in any of the preceding ways.

      A.4.2 Example GC with WeakReference



      You're likely to encounter special reference objects while using tools to look for
      memory leaks. Only strong references will directly interfere with garbage collection.
      If you find chains of objects linked by weak references, you should be able to
      ignore them from a GC perspective. (For additional information on the use of
      special reference objects, see the API documentation.)


      Figure A-5 shows a graph of objects in memory for a sample program. Let's say that the problem with this program is that the Dog objects are not being collected, leading to a memory leak. By using a memory profiler, you can find all the pointers to the Dog object and follow them back to their GC roots. There are two GC roots in Figure A-5, a static variable in class Kennel and a stack frame in a live thread. In this case, the WagTask thread is in an infinite loop, forcing the dog's tail to wag. The question is how to get rid of the Dog object.


      There are two references pointing to the Dog object, but only one of them is interesting from a GC perspective. The WeakReference from the dogCache is not important. The interesting reference is the reference from the Tail, which chains from a stack frame in a live thread. To free the Dog, and the associated Tail, you need to terminate the thread that is wagging the Tail. Once this thread is gone, everything falls into place. When an object that is pointed to by a WeakReference is collected, the WeakReference is automatically set to null. Figure A-6 shows the result of terminating the wag thread.

      Reference graph




      When the thread dies, its stack is removed. Now the only strong reference to the Dog is via the Tail, and this becomes a simple circular reference that isn't reachable from a GC root. The Dog, and by extension the Tail, are no longer strongly reachable through any references. They are only weakly reachable through the dogCache. When the collector discovers this (which it does on its own schedule), it might set the weak reference to null, making the Dog and Tail totally unreachable. They then become candidates for collection and will be removed at the collector's discretion.

      Results of garbage collection




      A.5 References on Garbage Collection



      Arnold, Ken, and James Gosling. The Java Programming Language, Second Edition, Addison-Wesley, Reading, MA, 1998.


      Gosling, James, Bill Joy, and Guy Steele. The Java Language Specification, Second Edition, Addison-Wesley, Reading, MA, 2000.


      Jones, Richard, and Rafael Lins. Garbage Collection: Algorithms for Automatic Dynamic Memory Management, John Wiley & Sons, New York, 1996.


      Lindholm, Tim and Frank Yellin. The Java Virtual Machine Specification, Second Edition, Addison-Wesley, Reading, MA, 1999.






      Tim Lindholm and Frank Yellin, The Java Virtual Machine Specification, Second Edition, Section 3.5.3. Addison-Wesley, 1999.



      James Gosling, Bill Joy, and Guy Steele, The Java Language Specification, Second Edition. Addison-Wesley, 2000.



God.James的精力也太充沛了吧?

http://radio.weblogs.com/
看看他参加了多少开源的项目:
ActiveCluster
ActiveMQ
ActiveSpace
axion
betwixt
commons
db
dom4j
groovy
geronimo
jaxen
jelly
jexl
maven
messenger
panoptes
picocontainer
saxpath
sql
spring
sysunit
taglibs
真是仰慕如黄河之水天上来,滔滔不绝啊.

星期四, 九月 16, 2004

一些Groovy重量级人物的blog及资源

http://weblogs.java.net/pub/wlg/1125/
这里有很多关于为什么选择Groovy做为JSR。而不是已经广泛应用的beanshell.或Python或Jruby.

http://justgroovy.org/学习Grooovy的网站.
http://radio.weblogs.com/0112098/2003/08/29.html#a399这是Groovy创建人之一的James的网站。
不过James的个人Email发送无法成功。试图联系不能成功。让人沮丧。
:(.

没办法,Java方面的支持的语言太多了。但从任何细节来说,IO层/数据层/thread.
我觉的Groovy支持的的确是Perfect.
算了,什么时候都要跟着老大Sun走。既然Sun选择了Groovy作为标准JSR。那么我们就学习Groovy了。它的确太伟大了。尤其是Closure(闭包)的概念。简直是天才之笔。
Closure来字数学理论。:)
可以在Google里查询closure.

感受Groovy(介绍伟大的Java Basic :)

Reference:http://www-900.ibm.com/developerWorks/cn/java/j-alj08034/

介绍 Java 平台的一种新标准语言
CTO, Vanward Technologies
2004 年 8 月

虽然 Java 语言因其严密性和扩展性的承诺而在整整一代程序员中胜出,但是 Groovy 预示了 Java 平台上的一个编程新时代,这种语言是以方便性、适宜性和敏捷性为出发点定义的。在新的 alt.lang.jre 专栏的第二期文章中,Andrew Glover 对提议添加到 Java 平台的标准编程语言作了非正式的介绍。

如果您在使用 Java 平台(block),不管时间长短,您都有可能听说过 Groovy。Groovy 是超级明星开发人员 James Strachan 和 Bob McWhirter 发明的,它是一种敏捷开发语言,完全以 Java 编程 API 为基础。Groovy 当前正处于 Java Specification Request 的开始阶段,它于 2004 年 3 月底获得批准。Groovy 还是一种脚本语言,有些人说它会永久性地改变您看待和使用 Java 平台的方式。

在其对 JSR 241 (请参阅 参考资料)的开放评论中,Groovy 的共同规范领导者 Richard Monson-Haefel 说他对 Groovy 的支持是建立在总有一天 Java 平台要包括一种敏捷开发语言这一信念上。与许多移植到 Java 平台的脚本语言不同,Groovy 是 为 JRE 而写的。在规范请求中(参阅 参考资料),Groovy 的制造者提出了“Java 不仅是一种编程语言,更是一个健壮的平台,可以有多种语言在上面运行和共存”(Monson-Haefel 语)的思想。

新 alt.lang.jre 专栏的这第二期文章的目的是让读者了解 Groovy。我首先回答关于这种新语言的一些最显然的问题(为什么需要它?),然后以代码为基础概述 Groovy 最令人兴奋的功能。

为什么需要另一种语言?
正如在 上个月的专栏 中介绍的,Groovy 不是与 JRE 兼容的惟一脚本语言。Python、Ruby 和 Smalltalk 就是成功地移植到 Java 平台上的三种脚本语言。对于一些开发人员,这带来了问题:为什么要另一种语言?毕竟,我们许多人已经将 Java 代码与 Jython 或者 JRuby 结合来快速开发应用程序,为什么还要学习另一种语言?回答是 您不一定要学习一种新语言以用 Groovy 编码。Groovy 与其他 JRE 兼容脚本语言的不同在于它的语法以及重用 Java 库。Jython 和 JRuby 共享它们前身(分别是 Python 和 Ruby)的外观,Groovy 让人觉得就像是 Java 语言,不过限制要少得多。
像 Jython 这样的语言是在它们的父语言库上建立的,而 Groovy 使用了 Java 开发人员最熟悉的功能和库 ?? 但是将它们放到了一个敏捷开发框架中。敏捷开发的基本宗旨是代码应该很好地适合范围广泛的任务,并可以不同的方式应用。Groovy 通过以下方式落实了这些宗旨:

* 使开发人员不用编译。
* 允许动态类型。
* 使合成结构容易。
* 使其脚本可以在普通 Java 应用程序中使用。
* 提供一个 shell 解析器。

这些特性使 Groovy 成为一种特别容易学习和使用的语言,不管您是有经验的 Java 开发人员还是刚接触 Java 平台。在下面几节中,我将详细讨论上述特性。

看呀,没有 javac!
像许多脚本语言一样,Groovy 不用为运行时编译。这意味着 Groovy 脚本是 在它们运行时 解释的,就像 JavaScript 是在观看 Web 页时由浏览器解释的一样。运行时判断会有执行速度的代价,这有可能使脚本语言不能用于对性能有要求的项目,但是无编译的代码在构建-运行周期中可以提供很多好处。运行时编译使 Groovy 成为快速原型设计、构建不同的实用程序和测试框架的理想平台。

例如,运行脚本 Emailer.groovyin Groovy 就是在命令行键入 groovy Emailer.groovy 这么容易。如果希望运行同样的 Java 文件(Emailer.java),显然必须键入额外的命令:javac Emailer.java,然后是 java Emailer。虽然这看起来可能有些微不足道,但是可以容易设想运行时编译在应用程序开发的更大上下文中的好处。

可以在稍后看到,Groovy 还允许脚本放弃 main 方法以静态地运行一个关联的应用程序。

动态 dynamo
像其他主流脚本语言一样,Groovy 不需要像 C++ 和 Java 语言这样的正式语言的显式类型。在 Groovy 中,一个对象的类型是在运行时动态发现的,这极大地减少了要编写的代码数量。首先可以通过分析清单 1 和 2 中的简单例子看到这一点。

清单 1 显示了在 Java 语言中如何将一个本地变量声明为 String。注意必须声明类型、名和值。
清单 1. Java 静态类型


String myStr = "Hello World";

在清单 2 中,您看到同样的声明,但是不需要声明变量类型。
清单 2. Groovy 动态类型


myStr = "Hello World"

您可能还注意到了,在清单 2 中我可以去掉声明中的分号。在定义方法及其相关的参数时动态类型有戏剧性的后果:多态具有了全新的意义!事实上,使用动态类型,不使用 继承就可以得到多态的全部能力。在清单 3 中,可以真正开始看到动态类型在 Groovy 的灵活性方面所起的作用。
清单 3. 更多 Groovy 动态类型


class Song{
length
name
}

class Book{
name
author
}

def doSomething(thing){
println "going to do something with a thing named = " + thing.name
}

这里,我定义了两个 Groovy 类,Song 和 Book,我将在后面对它们进一步讨论。这两个类都包含一个 name 属性。我还定义了一个函数 doSomething,它以一个 thing 为参数,并试图打印这个对象的 name 属性。

因为 doSomething 函数没有定义其输入参数的类型,只要对象包含一个 name 属性,那么它就可以工作。因此,在清单 4 中,可以看到在使用 Song 和 Book 的实例作为 doSomething 的输入时会有什么现象。
清单 4. 试验动态类型


mySong = new Song(length:90, name:"Burning Down the House")
myBook = new Book(name:"One Duck Stuck", author:"Phyllis Root")

doSomething(mySong) //prints Burning Down the House
doSomething(myBook) //prints One Duck Stuck

anotherSomething = doSomething

anotherSomething(myBook) //prints One Duck Stuck

除了展示 Groovy 中的动态类型,清单 4 的最后两行还揭示了创建对一个函数的引用有多容易。这是因为在 Groovy 中 所有东西 都是对象,包括函数。

关于 Groovy 的动态类型声明最后要注意的是,它会导致更少的 import 语句。尽管 Groovy 需要 import 以显式使用类型,但是这些 import 可以使用别名以提供更短的名字。

动态类型综述
下面两个例子将到目前为止讨论过的 Groovy 中的动态类型的内容放到一起。下面的 Java 代码组和 Groovy 代码组利用了 Freemarker(参阅 参考资料),这是一个开放源代码模板引擎。这两组代码都只是简单地用一个目录和文件名创建一个 Template 对象,然后将相应对象的内容打印到标准输出,当然,不同之处是每一组代码处理这项任务所需要的代码量。
清单 5. 简单的 TemplateReader Java 类


import java.io.File;
import java.io.IOException;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class TemplateReader {

public static void main(String[] args) {
try{
Configuration cfg = Configuration.getDefaultConfiguration();
cfg.setDirectoryForTemplateLoading(
new File("C:\\dev\\projects\\http-tester\\src\\conf"));

Template temp = cfg.getTemplate("vendor-request.tmpl");

System.out.println(temp.toString());
}catch(IOException e){
e.printStackTrace();
}
}
}

初看之下,清单 5 中的 Java 代码相当简单 ?? 特别是如果以前从来没见过脚本代码时。幸运的是,有清单 6 中的 Groovy 作为对比。现在这段代码很简单!
清单 6. 用 Groovy 编写的更简单的 TemplateReader


import freemarker.template.Configuration as tconf
import java.io.File

cfg = tconf.getDefaultConfiguration()

cfg.setDirectoryForTemplateLoading(
new File("C:\\dev\\projects\\http-tester\\src\\conf"))

temp = cfg.getTemplate("vendor-request.tmpl")

println temp.toString()

Groovy 代码只有 Java 代码的一半那么长,下面是原因:

* Groovy 代码只需要一半的 import 语句。还要注意,freemarker.template.Configuration 使用了别名 tconf,使得语法更短。

* Groovy 允许类型为 Template 的变量 tmpl 不声明其类型。

* Groovy 不需要 class 声明或者 main 方法。

* Groovy 不关心任何相应异常,使您可以不用导入 Java 代码中需要的 IOException。

现在,在继续之前,想一下您所编写的最后一个 Java 类。您可能不得不编写很多 import 并声明类型,并在后面加上同样数量的分号。考虑用 Groovy 编写同样的代码会是什么情况。可以使用简练得多的语法,不需要遵守这么多的规则,并且得到完全相同的行为。

想一下,如果您正好是刚刚开始……

特别灵活的语法
谈到语法,灵活性是更有效地开发代码的主要因素。很像其有影响的对手(Python、Ruby 和 Smalltalk),Groovy 极大地简化了核心库的使用和它所模拟的语言(在这里是 Java 语言)的构造。为了让您对 Groovy 语法的灵活性有一个大体概念,我将展示它的一些主要结构,即类、函数(通过 def 关键词)、闭包、集合、范围、映射和迭代器。


在字节码水平,Groovy 类是真正的 Java 类。不同之处在于 Groovy 将类中定义的所有内容都默认为 public,除非定义了特定的访问修饰符。而且,动态类型应用到字段和方法,不需要 return 语句。

在清单 7 中可以看到 Groovy 中类定义的例子,其中类 Dog 有一个 getFullName 方法,它实际上返回一个表示 Dog 的全名的 String。并且所有方法都隐式地为 public。
清单 7. 示例 Groovy 类:Dog


class Dog{
name

bark(){
println "RUFF! RUFF!"
}

getFullName(master){
name + " " + master.lname
}

obeyMaster(){
println "I hear you and will not obey."
}
}

在清单 8 中,推广到有两个属性 ?? fname 和 lname ?? 的类 DogOwner ,就是这么简单!
清单 8. 示例 Groovy 类:DogOwner


class DogOwner{
fname
lname

trainPet(pet){
pet.obeyMaster()
}

}

在清单 9 中,用 Groovy 设置属性并对 Dog 和 DogOwner 实例调用方法。现在很明显,使用 Groovy 类比 Java 类要容易得多。虽然需要 new 关键词,但是类型是可选的,且设置属性(它隐式为 public)是相当轻松的。
清单 9. 使用 Groovy 类



myDog = new Dog()
myDog.name = "Mollie"

myDog.bark()
myDog.obeyMaster()

me = new DogOwner()
me.fname = "Ralf"
me.lname = "Waldo"

me.trainPet(myDog)

str = myDog.getFullName(me)
println str // prints Mollie Waldo


注意在 Dog 类中定义的 getFullName 方法返回一个 String 对象,在这里它是 “Mollie Waldo”。
Def
除了像许多脚本语言那样将所有对象指定为第一类对象(见侧栏),Groovy 还让您创建 第一类函数,它本身实质上就是对象。它们是用 def 关键词定义的并在类定义之外。您实际上在 清单 3 中已经看到了如何用 def 关键词定义第一类函数,并在 清单 4 中看到使用了一个函数。Groovy 的第一类函数定义简单脚本时特别有用。

闭包
Groovy 中最令人兴奋和最强大的功能是支持闭包。闭包(Closure) 是第一类对象,它类似于 Java 语言中的匿名内部类。闭包和匿名内部类都是可执行的一段代码,不过这两者之间有一些细微的不同。状态是自动传入传出闭包的。闭包可以有名字。它们可以重复使用。而且,最重要且对 Groovy 同样成立的是,闭包远比匿名内部类要灵活得多!

清单 10 展示了闭包的强大。清单中新的和改进的 Dog 类包括一个 train 方法,它实际上执行创建了 Dog 实例的闭包。
清单 10. 使用闭包


class Dog{
action

train(){
action.call()
}
}

sit = { println "Sit, Sit! Sit! Good dog"}
down = { println "Down! DOWN!" }


myDog = new Dog(action:sit)
myDog.train() // prints Sit, Sit! Sit! Good dog

mollie = new Dog(action:down)
mollie.train() // prints Down! DOWN!

而且,闭包还可以接收参数。如清单 11 所示,postRequest 闭包接收两个参数(location 和 xml),并使用 Jakarta Commons HttpClient 库(参阅 参考资料)将一个 XML 文档发送给指定位置。然后这个闭包返回一个表示响应的 String。闭包定义下面是一个使用闭包的例子。事实上,调用闭包就像调用函数一样。
清单 11. 使用带参数的闭包


import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.methods.PostMethod

postRequest = { location, xml

clint = new HttpClient()
mthd = new PostMethod(location)
mthd.setRequestBody(xml)
mthd.setRequestContentLength(xml.length())
mthd.setRequestHeader("Content-type",
"text/xml; charset=ISO-8859-1")

statusCode = clint.executeMethod(mthd)
responseBody = mthd.getResponseBody()
mthd.releaseConnection()
return new String(responseBody)
}

loc = "http://localhost:8080/simulator/AcceptServlet/"
vxml = "blah blah blah"

str = postRequest(loc, vxml)
println str
集合
将对象组织到像列表和映射这样的数据结构中是一项基本的编码任务,是我们大多数人每天要做的工作。像大多数语言一样,Groovy 定义了一个丰富的库以管理这些类型的集合。如果曾经涉足 Python 或者 Ruby,那么应该熟悉 Groovy 的集合语法。如清单 12 所示,创建一个列表与在 Java 语言中创建一个数组很类似。(注意,列表的第二项自动装箱为一个 Integer 类型。)

清单 12. 使用集合


collect = ['groovy', 29, 'here', 'groovy']

除了使列表更容易处理,Groovy 还为集合增加了几个新方法。这些方法使得,如统计值出现的次数、将整个列表结合到一起、对列表排序变得非常容易。可以在清单 13 中看到这些集合方法的使用。
清单 13. 使用 Groovy 集合


aCollect = [5, 9, 2, 2, 4, 5, 6]

println aCollect.join(' - ') // prints 5 - 9 - 2 - 2 - 4 - 5 - 6
println aCollect.count(2) // prints 2
println aCollect.sort() // prints [2, 2, 4, 5, 5, 6, 9]

Maps

像列表一样,映射也是一种在 Groovy 中非常容易处理的数据结构。清单 14 中的映射包含两个对象,键是 name 和 date。注意可以用不同的方式取得值。
清单 14. 处理映射


myMap = ["name" : "Groovy", "date" : new Date()]

println myMap["date"]

println myMap.date

范围

在处理集合时,很可能会大量使用 范围(Range)。 范围 实际上是一个很直观的概念,并且容易理解,利用它可以包含地或者排除地创建一组有序值。使用两个点 (..) 声明一个包含范围,用三个点 (...) 声明一个排除范围,如清单 15 所示。
清单 15. 处理范围


myRange = 29...32
myInclusiveRange = 2..5

println myRange.size() // prints 3
println myRange[0] // prints 29
println myRange.contains(32) //prints false

println myInclusiveRange.contains(5) //prints true

用范围实现循环

在循环结构中,范围可以实现相当巧妙的想法。在清单 16 中,将 aRange 定义为一个排除范围,循环打印 a、b、c 和 d。
清单 16. 用范围实现循环


aRange = 'a'...'e'

for (i in aRange){
println i
}

集合的其他功能

如果不熟悉 Python 和其他脚本语言,那么您在 Groovy 集合中发现的一些其他功能会让您印象深刻。例如,创建了集合后,可以用负数在列表中反向计数,如清单 17 所示。
清单 17. 负索引


aList = ['python', 'ruby', 'groovy']

println aList[-1] // prints groovy
println aList[-3] // prints python

Groovy 还让您可以用范围分割列表。分割可获得列表的准确子集,如清单 18 所示。
清单 18. 用范围分割


fullName = "Andrew James Glover"

mName = fullName[7...13]

print "middle name: " + mName // prints James

集合类似于 Ruby

如果愿意的话,还可以将 Groovy 集合作为 Ruby 集合。可以用类似 Ruby 的语法,以 << 语法附加元素、用 + 串接和用 - 对集合取差,甚至还可以用 * 语法处理集合的重复,如清单 19 所示。 注意,还可以用 == 比较集合。 清单 19. Ruby 风格的集合 collec = [1, 2, 3, 4, 5] collec << acol =" ['a','b','c']" coll =" [10," coll2 =" [12," coll3 =" coll" difcol =" [1,2,3]" str = "uncle man, uncle man" val =" it" x ="="" basecolor =" baseColor;" lavacolor =" lavaColor;" liquidcolor =" liquidColor;" model =" model;" llamp =" new" mylamp =" new" basecolor = "Silver"> " + line
}

因为文件实质上是一系列行、字符等,所以可以相当简单地迭代它们。eachLine 方法接收一个闭包并迭代文件的每一行,在这里是 File-IO-Example.txt。 以这种方式使用闭包是相当强大的,因为 Groovy 保证所有文件资源都是关闭的,不考虑任何异常。这意味着无需大量 try/catch/finally 子句就可以进行文件 IO!

高级编译
Groovy 脚本实际上是字节码级别的 Java 类。因此,可以容易地用 groovyc 编译 Groovy 脚本。可以通过命令行或者 Ant 使用 groovyc 以生成脚本的类文件。这些类可以用普通 java 命令运行,只要 classpath 包括 groovy.jar 和 asm.jar,这是 ObjectWeb 的字节码操纵框架。要了解更多编译 Groovy 的内容,请参阅 参考资料。

最大 RegEx
如果一种语言没有正则表达式处理,则它是没价值的。Groovy 使用 Java 平台的 java.util.regex 库 ?? 但是做了少量基本的改变。例如,Groovy 使您可以用 ~ 表达式创建 Pattern 对象,用 =~ 表达式创建 Matcher 对象,如清单 25 所示。
清单 25. Groovy RegEx


str = "Water, water, every where,
And all the boards did shrink;
Water, water, every where,
Nor any drop to drink."

if (str =~ 'water'){
println 'found a match'
}

ptrn = ~"every where"

nStr = (str =~ 'every where').replaceAll('nowhere')

println nStr

您可能已经注意到了,可以在上述清单中定义 String、str,而无需为每一新行添加结束引号和 +。这是因为 Groovy 放松了要求字符串串接的普通 Java 约束。运行这段 Groovy 脚本会对匹配 water 的情况打印出 true,然后打印出一节诗,其中所有出现 “every where”的地方都替换为 “nowhere”
结束语
像所有婴儿期的项目一样,Groovy 是正在发展的语言。习惯于使用 Ruby 和 Python (或者 Jython)的开发人员可能会怀念 mixins、脚本导入(尽管可以将所需要的可导入脚本编译为相应的 Java 类)和方法调用的命名参数等这些功能的方便性。 但是 Groovy 绝对是一种发展中的语言。随着其开发人员数量的增加,它很有可能结合这些功能及更多功能。

同时,Groovy 有很多优点。它很好地融合了 Ruby、Python 和 Smalltalk 的一些最有用的功能,同时保留了基于 Java 语言的核心语法。对于熟悉 Java 平台的开发人员,Groovy 提供了更简单的替代语言,且几乎不需要学习时间。对于刚接触 Java 平台的开发人员,它可以作为有更复杂语法和要求的 Java 语言的一个容易的入口点。

像在本系统讨论的其他语言一样,Groovy 不是要替代 Java 语言,而是作为它的另一种选择。与这里讨论的其他语言不一样,Groovy 遵循 Java 规范,这意味着它有可能与 Java 平台上的 Java 语言具有同等重要的作用。

在本月这一期 alt.lang.jre 文章中,介绍了 Groovy 的基本框架和语法,以及它的一些高级编程功能。下个月将介绍在 Java 开发人员中最受欢迎的脚本语言: JRuby。
注释:Groovy主页在:http://groovy.codehaus.org/

Tiger 中的注释,第 1 部分: 向 Java 代码中添加元数据


作者/编者, O'Reilly Media, Inc
2004 年 9 月

注释,J2SE 5.0 (Tiger) 中的新功能,将非常需要的元数据工具引入核心 Java 语言。该系列文章分为两部分,在这第 1 部分中,作者 Brett McLaughlin 解释了元数据如此有用的原因,向您介绍了 Java 语言中的注释,并研究了 Tiger 的内置注释。

编程的一个最新的趋势,尤其是在 Java 编程方面,是使用元数据。简单地说,元数据就是关于 数据的数据。元数据可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。许多元数据工具,如 XDoclet(请参阅 参考资料),将这些功能添加到核心 Java 语言中,暂时成为 Java 编程功能的一部分。

直到可以使用 J2SE 5.0(也叫做 Tiger,现在是第二个 beta 版本),核心 Java 语言才最接近具有 Javadoc 方法的元数据工具。您使用特殊的标签集合来标记代码,并执行 javadoc 命令来将这些标签转化成格式化的 HTML 页面,该页面说明标签所附加到的类。然而,Javadoc 是有缺陷的元数据工具,因为除了生成文档之外,您没有固定、实用、标准化的方式来将数据用于其他用途。HTML 代码经常混入到 Javadoc 输出中这一事实甚至更进一步降低了其用于任何其他目的的价值。

Tiger 通过名为注释 的新功能将一个更通用的元数据工具合并到核心 Java 语言中。注释是可以添加到代码中的修饰符,可以用于包声明、类型声明、构造函数、方法、字段、参数和变量。Tiger 包含内置注释,还支持您自己编写的定制注释。本文将概述元数据的优点并向您介绍 Tiger 的内置注释。本系列文章的 第 2 部分 将研究定制注释。我要感谢 O'Reilly Media, Inc.,他们非常慷慨地 允许我在本文中使用我关于 Tiger 的书籍的“注释”一章中的代码示例(请参阅 参考资料)。

元数据的价值

一般来说,元数据的好处分为三类:文档编制、编译器检查和代码分析。代码级文档最常被引用。元数据提供了一种有用的方法来指明方法是否取决于其他方法,它们是否完整,特定类是否必须引用其他类,等等。这确实非常有用,但对于将元数据添加到 Java 语言中来说,文档编制可能是最不 相关的理由。Javadoc 已经提供了非常容易理解和健壮的方法来文档化代码。另外,当已经存在文档编制工具,并且在大多数时候都工作得很好时,谁还要编写文档编制工具?

编译器检查

元数据更重要的优点是编译器可以使用它来执行基本的编译时检查。例如,您将在本文后面的 Override 注释 中看到 Tiger 引入了一个这样的注释,用于允许您指定一种方法覆盖超类中的另一种方法。Java 编译器可以确保在元数据中指明的行为实际发生在代码级别。如果从来没有找出过这种类型的 bug,这样做似乎有点傻,但是大多数年龄很大的 Java 编程老手都曾经花费至少多个晚上来查明他们的代码为什么不能用。当最后认识到方法的参数有错,且该方法实际上没有 覆盖超类中的方法时,您可能更感到难受。使用元数据的工具有助于轻松地查明这种类型的错误,从而可以节省那些晚上来看长期进行的 Halo 联赛。
代码分析

可以证明,任何好的注释或元数据工具的最好功能就是可以使用额外数据来分析代码。在一个简单的案例中,您可能构建代码目录,提供必需的输入类型并指明返回类型。但是,您可能想,Java 反射具有相同的优点;毕竟,可以为所有这些信息内省代码。这从表面上看似乎是正确的,但是在实际中通常不使用。许多时候,方法作为输入接受的或者作为输出返回的类型实际上不是该方法想要的类型。例如,参数类型可能是 Object,但方法可能仅使用Integer。这在好些情况下很容易发生,比如在方法被覆盖而超类使用常规参数声明方法时,还有正在进行许多序列化的系统中也容易发生。在这两种情况中,元数据可以指示代码分析工具,虽然参数类型是 Object,但 Integer 才是真正需要的。这类分析非常有用,但也不能夸大它的价值。

在更复杂的情况下,代码分析工具可以执行所有种类的额外任务。示例 du jour 是 Enterprise JavaBean (EJB) 组件。甚至简单 EJB 系统中的依赖性和复杂性都非常令人吃惊。您具有了 home 接口和远程接口,以及本地接口和本地 home 接口,还有一个实现类。保持所有这些类同步非常困难。但是,元数据可以提供这个问题的解决放案。好的工具(还是要提一下 XDoclet)可以管理所有这些依赖性,并确保无“代码级”连接、但有“逻辑级”捆绑的类保持同步。元数据在这里确实可以发挥它的作用。

注释的基本知识

现在已经了解了元数据的好处,我将介绍 Tiger 中的注释。注释采用“at”标记形式 (@),后面是注释名称。然后在需要数据时,通过 name=value 对向注释提供数据。每次使用这类表示法时,就是在生成注释。一段代码可能会有 10 个、50 个或更多的注释。不过,您将发现多个注释都可能使用相同的注释类型。类型是实际使用的结构,在特定上下文中,注释本身是该类型的具体使用(请参阅侧栏 注释或注释类型?)。
注释分为三个基本种类:

* 标记注释没有变量。注释显示简单,由名称标识,没有提供其他数据。例如,@MarkerAnnotation 是标记注释。它不包含数据,仅有注释名称。

* 单一值注释与标记注释类似,但提供一段数据。因为仅提供很少的一点数据,所以可以使用快捷语法(假设注释类型接受此语法):@SingleValueAnnotation("my data")。除了 @ 标记外,这应该与普通的 Java 方法调用很像。

* 完整注释有多个数据成员。因此,必须使用更完整的语法(注释不再像普通的 Java 方法):@FullAnnotation(var1="data value 1", var2="data value 2", var3="data value 3")。

除了通过默认语法向注释提供值外,还可以在需要传送多个值时使用名称-值对。还可以通过花括号为注释变量提供值数组。清单 1 显示了注释中的值数组的示例。

Google Adsense公益广告问题之二

Google Adsense 的技术人员进一步解释了google Adsense如何产生广告

Our contextual advertising system automatically
identifies the meaning and language of a page based on a variety of
factors. Our technology takes into account elements such as linguistics,
keyword analysis, word frequency, font size, and the overall link
structure of the web. In general, adding the AdSense ad code to pages that
contain a majority of content in a supported language will allow you to
serve paid Google ads.

简单翻译来讲:

我们的上下文关联广告系统根据几个因素自动标志页面上内容含义。我们的计算元素包括
语言学,关键词分析,单词频率,字体尺寸以及全面的web结构.一般AdSense广告代码加入包含我们支持的语言内容的页面将允许你提供已付费的Google 广告。


看来Google的广告策略是内容为王啊。良好的内容。中英文混合,是呼唤广告的最佳策略。

星期三, 九月 15, 2004

Free Language Grammar Parser /免费的语言语法解析工具

http://sablecc.org/downloads.html

非常好的免费语言语法解析器.支持Java php等.
有时间好好看看.

星期二, 九月 14, 2004

Google Adsense公益广告问题/Google Adsense alternative ad and public service trouble

根据Adsense Help原因有几条,关键因素
Google发放广告的流程:
你申请了adsense帐户后,google蜘蛛程序会自动抓去你的站点,并分析关键词adword到数据库中。
以前是一周分析一次,现在是一天一次。然后根据关键词找到google的客户广告,并发放到你的站点上。
所以,推断产生公益广告的原因。
1.你的网站内容不够丰富(最关键)。
内容太少,google 蜘蛛程序无法定位你的站点的明确适合目标客户
2.站点最好中英文混合.
方便google 蜘蛛分析。
3.要经常更新。
4.http://www.google.com/addurl.html去在google里加入你的网站!!!

解决办法。
使用google alternate ads是一个途径,这只在你可以从两个公司获取利润的情况下才有意义,否则只能是弥补版面的美观。通过google_alternate_ad="";google_alternate_color="#11111";
同样可以隐藏掉公益广告美化版面。
发email: mailto:adsense-support@google.com 寻找帮助.

星期一, 九月 13, 2004

In java How to Get Embed Groovy Environment variable number?

在Java嵌入Groovy引擎后如何知道当前GroovyShell中环境中的变量.

Example:
Binding tempBind=_shell.getContext();
java.util.Map allenv=tempBind.getVariables();
java.util.Set keys=allenv.keySet();
java.util.Iterator keylist=keys.iterator();
while(keylist.hasNext())
{
Object index=keylist.next();
System.out.println(index+":"+allenv.get(index));
}

星期日, 九月 12, 2004

Maintenance release of JSF 1.1 now available

Maintenance release of JSF 1.1 now available

终于发布了新的版本,期待性能真的可以大大提高。

星期五, 九月 10, 2004

Groovy 中文 FAQ

QA使用Groovy Tips:
PreConditon:Groovy 1.0 Beta 6 jvm 1.4.2_04 windows XP

1. 如何声明一个Groovy 类似的方法或函数调用
Groovy没有明确的关键词类似Function或类似语法。
Groovy通过Closure块来实现常用功能库.
Example 1:
A={println “Hello,Wolrd”;
Println “String”.getBytes();
}
A();
Example 2:使用参数
ClosureA={
Name | println “你是”+Name;
}
ClosureA(“ Peter”);

2. 如何动态运行Groovy代码?
Q:如果把Groovy代码放在文件中或数据库中,或从用户输入,如何执行呢?
A:Groovy 代码放在文件中
可以通过CMI:groovy.bat 文件.groovy来运行.
如果是从Java语言中运行存放在文件中的groovy代码.必须用以下语法
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyShell;
import groovy.lang.Binding;
import groovy.lang.Closure;
// Create a class loader
GroovyClassLoader groovyLoader =
new GroovyClassLoader();
// Create the shell
GroovyShell shell =
new GroovyShell( groovyLoader, new Binding() );
如果定义的Groovy class就要用:
Class closureClass=grrovyLoader.loadClass(“groovy file.”);
如果groovy是业务逻辑代码:
GroovyShell shell = new GroovyShell( new Binding() );
shell.evaluate( new File( "GroovyXML4.groovy" ) );
// Get the calculateAmounts closure
Closure calc =
(Closure)shell.getVariable( "calculateAmounts" );
3. 如何判断一段Groovy代码是否语法正确?
Import groovy.lang.GroovyShell;
Import groovy.lang.Binding;
GroovyShell shell = new GroovyShell(new Binding());
String groovyScript=””;
try
{
shell.parse(groovyScript); //解析是否正确
}catch(Exception e)
{
return false;
}
return true;

4. 如何把字符串当作groovy代码看待?
GroovyShell shell =new GroovyShell(new Binding() );
codeString="import groovy.lang.*;
println 'this is test';
";
Script script = shell.parse(codeString);
script.run();

5. 用字符串构造groovy closure
codeString=”{ |basicinfo,employment,attendence| println “basicinfo:”+basicinfo;
println “employment:”+employment;
println “attendence”+attendence;
}
“;
block=shell.evaluate(codeString);
block("william","aaa",12);//Cool!!

6. 在Java中如何使用Groovy 对象?
GroovyShell _shell=new GroovyShell(new Binding());
//Test 1 From String 2 Closure Object
StringBuffer groovyCode=new StringBuffer().append("{"};
groovyCode.append("|name,sex,high|");//Parameter of Closure
groovyCode.append(" println \"你的名字:\"+name;");
groovyCode.append(" println \"性别:\"+sex;");
groovyCode.append(" println \"身高:\"+high;");
groovyCode.append(")");
Object[] params={new String("William"),new String("Male"),new Integer(10)};
Closure temp =(Closure) _shell.evaluate(groovyCode.toString());
temp.call(params);

7. 如何实现复杂对象传递.
Groovy中的Map对象为java.util.HashMap对象。
Map的初始化为[:]( list的初始化为[])

经典代码:
Query_SQL="select distinct contactphone,a.empid,businessrule from emp_M_basicInfo a inner join emp_M_SalaryBasicInfo a1,pay_M_catagoryitem b1 on a.factorycode=a1.factorycode and a.empid = a1.empid and a1.paycatagorycode=b1.paycatagorycode and a1.factorycode=b1.factorycode "
sql = Sql.newInstance("jdbc:mysql://localhost:3306/PCD","root","","org.gjt.mm.mysql.Driver");

rsetmap=[:]

sql.eachRow(Query_SQL,{rset|
metadata=rset.getMetaData();
tempmap=[:]

for ( index in 1..metadata.getColumnCount())
{
tempmap.put("${metadata.getColumnName(index).toLowerCase()}","${rset.getObject(index)}");
}
println tempmap
rsetmap.put(rset.getRow(),tempmap);
});
//println rsetmap.values().each{println it} //ok.
//println rsetmap.size();



testa=rsetmap.values();
try{
testa.each {println it.empid}
} catch(Exception e) {println "erro"+e.getMessage();}

星期六, 九月 04, 2004

关于JAVA几种embed解释语言的比较.

http://pnuts.org/~tomatsu/embedding.html

星期五, 九月 03, 2004

J2sdk 1.4 Matcher.matches()和String.matches(String Regex)的区别.

String.matches(String regex)是用来判断当前String符合regex描述的规则表示.并不表示在当前String中是否包含符合regex的结果.

微妙.

JDK 1.4中利用java.util.Regex来发现匹配的单词.

//发现factorycode单词.
//\\b 表示单词分界符号.

import java.util.regex.*;
String targetStr = "a.factorycode,b.empid afactorycodeb";
String RegexStr="\\bfactorycode\\b";
Pattern p = Pattern.compile(RegexStr);
Matcher m = p.matcher(targetStr);
while ( (m.find()) ) { System.out.println("find");}


JSP使用JSTL来动态switch 语言信息或标签(label)

/**
* 通过提交lang参数来动态切换语言包,注意红色部分,是技巧

*/
<c:choose>
<c:when test="${param.lang ne null}">
<c:set value="${param.lang}" var="lang" scope="request"/>
</c:when>
<c:otherwise>
<c:set value="zh" var="lang"/>
</c:otherwise>
</c:choose>
<%response.flushBuffer();%>
<fmt:setLocale value="${requestScope.lang}" scope="request" />
<fmt:setBundle basename="com.movalogic.resource.dictionary" scope="request" var="first"/>
<fmt:message key="HELLO_LABEL" bundle="${first}" />

BTW:由于Tomcat Container的 Cache原因.当使用JSTL setLocale设置语言后,当前browser显示的内容,就只能为这种语言,再次通过setLocale来设置语言,不起作用.
常见之法:修改 tomcat 系统web.xml中的有关JSP的编译部分,org.apache.jasper.servlet.JspServlet 设置其enablePooling=true
就可以避免setLocale多次不起作用了.

星期三, 九月 01, 2004

Password Masking in the Java Programming Language get by Java.sun.com

http://java.sun.com/developer/technicalArticles/Security/pwordmask/

星期二, 八月 31, 2004

如何在IE Javascript 中传递Node-seet到XSLT

目的: 在Javascript 利用Microsoft MXSML Engine来做XML/XSLT的ProtoTye开发.
传递一个XML的所谓.Result TRee Fragment 到XSLT 去处理.


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexxml/html/xml06192000.asp

例子:
关键处:MSXSL的DoMDocument的属性 .documentElement把一个node-set直接传递到XSLT中去处理.
MSXML:4.0 sp2.可能是个Bug.


<SCRIPT language = "javascript">
function init()
{

var basicinfo = new ActiveXObject("Msxml2.DOMDocument.4.0");
var employment = new ActiveXObject("Msxml2.DOMDocument.4.0");
var paycatagory = new ActiveXObject("Msxml2.DOMDocument.4.0");
var attendence = new ActiveXObject("Msxml2.DOMDocument.4.0");
var mainpage = new ActiveXObject("Msxml2.DOMDocument.4.0");

mainpage.async=false;
mainpage.resolveExternals = false;

basicinfo.async=false;
employment.async=false;
paycatagory.async=false;
attendence.async=false;

// You can substitute other XML file names here.
try
{
mainpage.load("hello.xml");

basicinfo.load("emp_M_Basicinfo.xml");

employment.load("emp_M_EmploymentInfo.xml");

paycatagory.load("pay_M_CatagoryItem.xml");
attendence.load("attendence.xml");
}catch(e)
{
alert("error:"+e.parseError);
}
//Display basicinfo nodeset
// alert(basicinfo.documentElement.childNodes.item(0).xml);

var xslt = new ActiveXObject("Msxml2.XSLTemplate.4.0");
var xsltTree= new ActiveXObject("Msxml2.FreeThreadedDOMDocument.4.0");

xsltTree.async = false;
// You can substitute other XSLT file names here.
xsltTree.load("hello.xslt");
xslt.stylesheet = xsltTree

xslProc = xslt.createProcessor();

xslProc.input = mainpage
try
{
xslProc.addParameter("basicinfo",basicinfo.documentElement);//.selectNodes("/Results")
xslProc.addParameter("employment",employment);
xslProc.addParameter("paycatagory",paycatagory);
xslProc.addParameter("attendence",attendence);
xslProc.addParameter("yourname","William Wang");
}catch(e)
{
alert(e);
}
xslProc.transform();

resTree.innerHTML = xslProc.output;

// Save the result of the XSL transformation

//htmlCode = xslProc.output
//fso=new ActiveXObject("Scripting.FileSystemObject")
//htmlFile=fso.CreateTextFile("sample.html",true)
//htmlFile.WriteLine(htmlCode)
//htmlFile.Close()
}
</SCRIPT>
</HEAD>
<BODY onload = "init()" >
<div id="resTree"></div>
</BODY>
</HTML>

星期五, 八月 20, 2004

j_Security_check 同Filter之间的矛盾

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=21795

如果通过Filter来解决某些问题,在用户验证之前,Filter将不会被激活.
这是一个问题.
因为,j_security_check 有"remember me"功能,这样很多DBCS的参数将在Filter之前被编码.

在Java里如何准确显示相除操作后的小数点位数

可以使用Formater族类.
一个常用的方法,使用BigDecimal类:

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class testDe
{
public static void main(String[] args)
{

BigDecimal b1 = new BigDecimal(3);
BigDecimal b2 = new BigDecimal(12);
System.out.println(b1.divide(b2,2,BigDecimal.ROUND_HALF_UP).doubleValue());
}
}

星期四, 八月 12, 2004

JAAS and Form-Authenticate Invalid direct reference to form login page Solution

Tomcat
臭名昭著的:Invalid direct reference to form login page 异常
完全解决方法.
PreCondition:
不要直接访问Login页面,让Tomcat Container自己在需要的时候调用Login页面

其他的Callbacker和其他相关问题,参考2004.3月文章.

出现Invalid direct reference to form login page 的关键原因在web.xml中的配置有问题.
注意的问题,千万不要遗漏下面几行:
<realm-name>FDS<realm-name>
<auth-constraint>
<role-name></role-name>
</auth-constraint>

完整的例子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>ehrm</display-name>
<description>ehrm JAAS</description>

<filter>
<filter-name>encodecontroler</filter-name>
<filter-class>com.goldpeak.ehrm.services.EncodeControler</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodecontroler</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet-name>FMEntryPoint</servlet-name>
<servlet-class>com.gp.framework.control.web.MainServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FMEntryPoint</servlet-name>
<url-pattern>/control/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>/control/security/login</welcome-file>
</welcome-file-list>

<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/control/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name></role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>

</security-constraint>

<login-config>
<auth-method>FORM</auth-method>
<realm-name>FDS</realm-name>
<form-login-config>
<form-login-page>/control/security/login</form-login-page>
<form-error-page>/config/error.jsp</form-error-page>
</form-login-config>

</login-config>
<!--security-role>
<description>A Funky User</description>
<role-name>FunkyUser</role-name>
</security-role-->

<env-entry>
<env-entry-name>DatabaseJNI</env-entry-name>
<env-entry-value>java:/MySqlDS</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

</web-app>

星期六, 八月 07, 2004

Google如何利用URLEncoder来处理事情。

红色的注释encodeURIComponent是关键。

<html><head><meta HTTP-EQUIV="content-type" CONTENT="text/html; charset=UTF-8">
<script>
function qs()
{
el=document.mainform.chinese;
if (window.RegExp && window.encodeURIComponent)
{
var qe=encodeURIComponent(el.value);
prompt("Transmit",qe);
window.location.href="http://www.google.com/search?q="+qe+"&sourceid=firefox&start=0&start=0&ie=utf-8&oe=utf-8";
}
}
// -->
</script>

<body>
<form name="mainform">
<input type="text" name="chinese"><input type="button" value="Trasmition" onclick="qs()">
</form>

星期二, 八月 03, 2004

常用词汇

YMMV:
----------------
"YMMV Net-language for 'your mileage may vary'. A warning that not everything described in a manual will work exactly the way it promised to. "

星期一, 八月 02, 2004

JAAS术语说明

[Subject]:JAAS 用术语Subject来引用请求访问的资源的实体.
[Principals]:主体(或委托人).
[credential]:凭证或信任装(可以是密码或数字签名)
一个Subject可以是一个用户或一种服务.由于一个实体可能有多个名字,
或Principals

http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/tutorials/glossary.html

Subjects, Principals, Authentication, and Credentials
To authorize access to resources, applications first need to authenticate the source of the request. The JAAS framework defines the term subject to represent the source of a request. A subject may be any entity, such as a person or service. A subject is represented by the javax.security.auth.Subject class.

Authentication represents the process by which the identity of a subject is verified, and must be performed in a secure fashion; otherwise a perpetrator may impersonate others to gain access to a system. Authentication typically involves the subject demonstrating some form of evidence to prove its identity. Such evidence may be information only the subject would likely know or have (such as a password or fingerprint), or it may be information only the subject could produce (such as signed data using a private key).

Once authenticated, a Subject is populated with associated identities, or Principals (of type java.security.Principal). A Subject may have many Principals. For example, a person may have a name Principal ("John Doe") and an SSN Principal ("123-45-6789"), which distinguish it from other Subjects.

In addition to associated Principals, a Subject may own security-related attributes, which are referred to as credentials. A credential may contain information used to authenticate the subject to new services. Such credentials include passwords, Kerberos tickets, and public key certificates. Credentials might also contain data that simply enables the subject to perform certain activities. Cryptographic keys, for example, represent credentials that enable the subject to sign or encrypt data. Public and private credential classes are not part of the core JAAS class library. Any class, therefore, can represent a credential.