星期四, 九月 23, 2004
利用IE6和Javascript同服务器交互
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参考资料
http://developer.netscape.com/viewsource/angus_strings.html
及通过.prototype扩展Javascript的功能.
http://www.javascriptkit.com/javatutors/proto4.shtml
星期三, 九月 22, 2004
如何避免GroovyClassLoader Defect 不足.避免动态类占用内存资源.
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
详细内容参考http://java.sun.com/developer/EJTechTips/2004/tt0824.html#1
星期二, 九月 21, 2004
如何利用Dynamic ClassLoader 来动态载入Class
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的问题
不能回收解析脚本动态产生的Scriptxxxx class.
原因是Groovy MetaClass使用了 static HashMap 来cache生成的class.
解决办法,模拟groovy 自己产生一个GroovyObject Arrays.
然后,把动态生成的GroovyObject放入数组,只生成一次,以后直接从数组中载入Class对象实例。
星期日, 九月 19, 2004
TTS Ask:What do you want in Next Java?
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?
今天看到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)回收的机制
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.
A.3.1 Created
When an object is created, several things occur:2
- Space is allocated for the object.
- Object construction begins.
- The superclass constructor is called.
- Instance initializers and instance variable initializers are run.
- 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 themakeCatmethod returns. At that moment, two strong references point to theCatobject.
Object reference graph![]()
When themakeCatmethod returns, the stack frame for that method and any temporary variables it declares are removed. This leaves theCatobject with just a single reference from thecatListstatic variable (indirectly via theVector).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 objectfoofalls out of scope when thetryblock finishes. It might seem that thefootemporary reference variable would be pulled off the stack at this point and the associated object would become unreachable. After all, once thetryblock 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 byfoocontinues to be strongly referenced, at least until therunmethod 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 thebuildDogmethod returns. Before the method returns, there are strong references from the temporary stack variables in thebuildDogmethod pointing to both theDogand theTail.Reference graph beforebuildDogreturns
![]()
Reference graph afterbuildDogreturns![]()
Figure A-3 shows the graph for the objects after thebuildDogmethod returns. At this point, theDogandTailboth 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 afinalizemethod, 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 itsfinalize
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 afinalizemethod 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 anOutOfMemoryErrorafter 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,000Graphicsobjects were held in the finalizer queue waiting for a chance to run their finalizers. It turned out that theseGraphicsobjects were holding onto fairly substantial native resources. The problem was fixed by assuring that whenever Swing is done with aGraphicsobject,disposeis 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 withfinalizemethods 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 asSystem.gc.
Thejava.lang.refpackage 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.Referenceobjects 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 useWeakReferencesinternally, so you might encounter them while using memory profilers to track memory usage.Referenceclass 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 theDogobjects are not being collected, leading to a memory leak. By using a memory profiler, you can find all the pointers to theDogobject and follow them back to their GC roots. There are two GC roots in Figure A-5, a static variable in classKenneland a stack frame in a live thread. In this case, theWagTaskthread is in an infinite loop, forcing the dog's tail to wag. The question is how to get rid of theDogobject.
There are two references pointing to theDogobject, but only one of them is interesting from a GC perspective. TheWeakReferencefrom thedogCacheis not important. The interesting reference is the reference from theTail, which chains from a stack frame in a live thread. To free theDog, and the associatedTail, you need to terminate the thread that is wagging theTail. Once this thread is gone, everything falls into place. When an object that is pointed to by aWeakReferenceis collected, theWeakReferenceis automatically set tonull.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 theDogis via theTail, and this becomes a simple circular reference that isn't reachable from a GC root. TheDog, and by extension theTail, are no longer strongly reachable through any references. They are only weakly reachable through thedogCache.When the collector discovers this (which it does on its own schedule), it might set the weak reference tonull,making theDogandTailtotally 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的精力也太充沛了吧?
看看他参加了多少开源的项目:
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及资源
这里有很多关于为什么选择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 :)
介绍 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 = "
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公益广告问题之二
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 /免费的语言语法解析工具
非常好的免费语言语法解析器.支持Java php等.
有时间好好看看.
星期二, 九月 14, 2004
Google Adsense公益广告问题/Google Adsense alternative ad and public service trouble
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?
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
星期五, 九月 10, 2004
Groovy 中文 FAQ
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
星期五, 九月 03, 2004
J2sdk 1.4 Matcher.matches()和String.matches(String Regex)的区别.
微妙.
JDK 1.4中利用java.util.Regex来发现匹配的单词.
//\\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
星期二, 八月 31, 2004
如何在IE Javascript 中传递Node-seet到XSLT
传递一个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之间的矛盾
如果通过Filter来解决某些问题,在用户验证之前,Filter将不会被激活.
这是一个问题.
因为,j_security_check 有"remember me"功能,这样很多DBCS的参数将在Filter之前被编码.
在Java里如何准确显示相除操作后的小数点位数
一个常用的方法,使用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
臭名昭著的: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>
星期三, 八月 11, 2004
星期六, 八月 07, 2004
Google如何利用URLEncoder来处理事情。
<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 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术语说明
[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.
星期六, 七月 31, 2004
Groovy快速打开一个文件
FileInputStream('foo.txt').using { ain |
while (true) {
line = ain.readLine()
if (line == null) break
print line
}
}
星期五, 七月 30, 2004
Groovy 一:Closure(闭合)关键词汇
"A closure is a chunk of groovy code that can be assigned to a variable, passed to other operations, and
executed."
所以Closure类似于Java的inner class,就是一大段代码可以将其赋予一个变量,传递给其他操作并且可以执行.
2.隐含的参数
每个Closure对象都有一个确省参数,应用关键词是"it".如:
c={
print it;}
c("print Groovy")
3.明显的参数
通过"|"管道符号来分开参数和可执行的语句.
如:
c={x|print x+":)";};
c("ok")
go
你可以同"|"管道符号把多个参数包围起来.
c = { | x, y, z |println x + y + z;};
c(1,2,10);
go
通过XSLT如何得到唯一的值(精彩例子)
1.一般在一组node()里得到唯一的代表node(),类似SQL Select Distinct 关键词的作用.
在XSLT是通过 node()[not(aixs=preceding::node/aixs)]类似的语法得到.
如:XML
<?xml version="1.0" encoding="UTF-8"?>
<xmldata>
<current_row>
<dept>70</dept>
<deptname>??部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB00660</empid>
<positioncode>490</positioncode>
<positiondesc>???</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>???</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>70</dept>
<deptname>??部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB10203</empid>
<positioncode>80</positioncode>
<positiondesc>文?</positiondesc>
<gradetype>10</gradetype>
<gradedesc>初?</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>??花</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>90</dept>
<deptname>人事部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB00404</empid>
<positioncode>50</positioncode>
<positiondesc>?堂</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>?定金</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>90</dept>
<deptname>人事部</deptname>
<section>10</section>
<sectionname>正常班</sectionname>
<empid>HMB10196</empid>
<positioncode>90</positioncode>
<positiondesc>司机</positiondesc>
<gradetype>40</gradetype>
<gradedesc>??</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>???</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>100</dept>
<deptname>生?部</deptname>
<section>130</section>
<sectionname>??合B班</sectionname>
<empid>HMB00481</empid>
<positioncode>360</positioncode>
<positiondesc>普工</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>??秀</namechin>
<nameeng/>
</current_row>
<current_row>
<dept>100</dept>
<deptname>生?部</deptname>
<section>130</section>
<sectionname>??合B班</sectionname>
<empid>HMB00891</empid>
<positioncode>360</positioncode>
<positiondesc>普工</positiondesc>
<gradetype>30</gradetype>
<gradedesc>工人</gradedesc>
<employmentstatus>002</employmentstatus>
<employmentstatusdesc>在职</employmentstatusdesc>
<namechin>邢巨芳</namechin>
<nameeng/>
</current_row>
</xmldata>
希望得到的结果如图:
最终得到的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>ok</title>
</head>
<link href="ehrm.css" rel="stylesheet" type="text/css"/>
<body>
<xsl:text disable-output-escaping="yes">
<![CDATA[
<script>
function folder(referen,objname)
{
var localobj=findObj(objname);
if(localobj.style.display=='none')
{
localobj.style.display='';
referen.style.backgroundImage='url(../images/image2/opengroup.gif)';}else{
localobj.style.display='none';
referen.style.backgroundImage='url(../images/image2/group.gif)';
}
}
// Example: obj = findObj("image1");
function findObj(theObj, theDoc)
{
var p, i, foundObj;
if(!theDoc) theDoc = document;
if( (p = theObj.indexOf("?")) > 0 && parent.frames.length)
{
theDoc = parent.frames[theObj.substring(p+1)].document;
theObj = theObj.substring(0,p);
}
if(!(foundObj = theDoc[theObj]) && theDoc.all) foundObj = theDoc.all[theObj];
for (i=0; !foundObj && i < theDoc.forms.length; i++)
foundObj = theDoc.forms[i][theObj];
for(i=0; !foundObj && theDoc.layers && i < theDoc.layers.length; i++)
foundObj = findObj(theObj,theDoc.layers[i].document);
if(!foundObj && document.getElementById) foundObj = document.getElementById(theObj);
return foundObj;
}
</script>
]]>
</xsl:text>
<xsl:apply-templates select="//xmldata"/>
</body>
</html>
</xsl:template>
<xsl:template match="xmldata">
<div id="Layer3" style="position:absolute; width:412px; height:300px; z-index:3; top: 141px; overflow-y: scroll; left: 26px;">
<table width="400" border="0" cellspacing="0">
<xsl:for-each select="current_row[not(dept = preceding-sibling::current_row/dept)]">
<xsl:variable name="deptv" select="dept"/>
<tr>
<td class="folder1" onMouseUp="with(findObj('dept{position()}'))if(style.display=='none'){{style.display='';this.style.backgroundImage='url(../images/image2/opengroup.gif)'}}else{{style.display='none';this.style.backgroundImage='url(../images/image2/group.gif)'}}">
<xsl:value-of select="deptname"/>/<xsl:value-of select="dept"/>(<xsl:value-of select="count(/xmldata/current_row/section[preceding-sibling::dept=$deptv])"/>)
</td>
</tr>
<tr>
<td class="subfolder1" id="dept{position()}">
<table width="373" border="0" cellspacing="0">
<xsl:variable name="section_row" select="//current_row[ dept = $deptv and not(section=preceding-sibling::current_row[dept=$deptv]/section)]"/>
<!--section group-->
<xsl:for-each select="$section_row">
<tr>
<td width="371" class="folder1" onMouseUp="with(findObj('{$deptv}group{position()}'))if(style.display=='none'){{style.display='';this.style.backgroundImage='url(../images/image2/opengroup.gif)'}}else{{style.display='none';this.style.backgroundImage='url(../images/image2/group.gif)'}}">
<xsl:value-of select="current()/sectionname"/>/<xsl:value-of select="current()/section"/>
</td>
</tr>
<tr>
<!--sss-->
<td class="subfolder1" id="{$deptv}group{position()}">
<table width="350" border="0" cellspacing="0">
<!--Employee circle-->
<xsl:for-each select="/xmldata/current_row[dept = $deptv and sectionname=current()/sectionname]">
<tr>
<td width="66" class="file1" >
<xsl:choose>
<xsl:when test="not(namechin = 'null')">
<xsl:value-of select="namechin"/>
</xsl:when>
<xsl:when test="namechin = 'null' and not(nameeng = 'null')">
<xsl:value-of select="nameeng"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>NameNull</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
<td width="60" class="cao2" onMouseOver="this.style.fontWeight='600';this.style.cursor='hand'" onMouseOut="style.fontWeight='400'" onClick="openWindow('{empid}','','features');parclose()">
<xsl:value-of select="empid"/>
</td>
<td width="90" class="cao1">
<xsl:value-of select="gradedesc"/>
</td>
<td width="25" class="cao1">--</td>
<td width="55" class="cao1">
<xsl:value-of select="positiondesc"/>
</td>
<td width="42" class="cao1">
<xsl:value-of select="employmentstatusdesc"/>
</td>
</tr>
</xsl:for-each>
<!--Employee circle over-->
</table>
</td>
<!--sss-->
</tr>
</xsl:for-each>
<!--section group over-->
</table>
</td>
</tr>
</xsl:for-each>
</table>
</div>
</xsl:template>
</xsl:stylesheet>
星期一, 七月 26, 2004
Xalan XSLT extension Javascript/java出现错误:
http://www.mozilla.org/rhino/download.html 1.5R5
出现错误:Line number can not be negative:-1
这是Bug,必须使用:1.5 R3版本.可以正常使用.
extension使用Java出现错误:
不能正确映射Java对象的方法:
For extension function, could not find method static java.lang.System.currentTimeMills([ExpressionContext,] ).
原因:拼写错误.
------------------
例子:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
exclude-result-prefixes="xalan"
xmlns:java="http://xml.apache.org/xalan/java"
xmlns:my-ext="ext1"
extension-element-prefixes="my-ext"
>
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="employment"/>
<xsl:param name="basicinfo"/>
<xsl:param name="paymentinfo"/>
<xsl:param name="attendance"/>
<xalan:component prefix="my-ext" functions="getdate">
<xalan:script lang="javascript">
var aaa=1;
function getdate()
{
return "ddd";
}
</xalan:script>
</xalan:component>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="not($employment)">
<xsl:text>Nothing</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Yeah</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
<xsl:value-of select="my-ext:getdate()"/>
<xsl:text> </xsl:text>
<xsl:value-of select="$employment/employe/name"/>
<xsl:text> </xsl:text>
<xsl:value-of select="java:java.lang.Math.random()" />
<xsl:text> </xsl:text>
<xsl:value-of select="java:java.lang.System.currentTimeMillis()" />
</xsl:template>
</xsl:stylesheet>
星期六, 七月 24, 2004
XML解析常见错误:org.xml.sax.SAXParseException: Document root element is missing
用可以编辑16 HEX CODE的编辑器,如UltraEdit查看文件类型是输入UTF8-DOS类型,
入图:
就会引起错误.
改正方式,用Ascll方式保存.就可以了.
XML解析中的问题
这里解释了一些规范.
* BOM(Byte order mark):
* 00 00 FE FF = UTF-32, big-endian
* FF FE 00 00 = UTF-32, little-endian
* FE FF = UTF-16, big-endian
* FF FE = UTF-16, little-endian
* EF BB BF = UTF-8
*/
星期三, 七月 21, 2004
Groovy 基本语发:
http://wiki.codehaus.org/groovy/FrontPage
基本语发训练:
http://wiki.codehaus.org/groovy/GroovyTutorial
BlocksAndClosures - Groovy Wiki
Groovy设计到的词汇,Closure:闭包,也可做:回路
1.
structure that holds an expression and an environment of
variable bindings in which that expression is to be evaluated.
The variables may be local or global. Closures are used to
represent unevaluated expressions when implementing
functional programming languages with lazy evaluation. In
a real implementation, both expression and environment are
represented by pointers.
A suspension is a closure which includes a flag to say
whether or not it has been evaluated. The term "thunk" has
come to be synonymous with "closure" but originated outside
functional programming.
2.
set, D and a subset, X of D, the upward closure of X in D is
the union over all x in X of the sets of all d in D such that
x <= d. Thus the upward closure of X in D contains the
elements of X and any greater element of D. A set is "upward
closed" if it is the same as its upward closure, i.e. any d
greater than an element is also an element. The downward
closure (or "left closure") is similar but with d <= x. A
downward closed set is one for which any d less than an
element is also an element.
("<=" is written in LaTeX as \subseteq and the upward
closure of X in D is written \uparrow_\{D} X).
CVS 常用关键词列表.
VSS:
To expand keywords
Type this keyword To add the following
$Archive: $ VSS archive file location
$Author: $ User who last changed the file
$Date: $ Date and time of last check in
$Header: $ Logfile, Revision, Date, Author
$History: $ File history, VSS format
$JustDate: $ Date, without the time addendum.
$Log: $ File history, RCS format
$Logfile: $ Same as Archive
$Modtime: $ Date and time of last modification
$Revision: $ VSS version number
$Workfile: $ File name
$NoKeywords: $ No keyword expansion for all keywords that follow
CVS:
$Id$ 关键字是用文件名、版本、时间、作者 及代码性质替换,如果使用-l选项取出,在Exp后
面会加上登录用户的名称。除了$Id$关键字,RCS还支持下面常用的关键字:
$Log$ : 你所提供的修改日志信息。
$Author$ :存入该版本的作者。
$Locker$ : 该版本的加锁者
$State$ : 该版本的状态 Exp(试验版), Stabe(稳定版), Rel(发行版).缺省是Exp
$Date$ : 该版本存入的时间,使用UTC时间格式。
$Revision$ : 该版本的版本号
$RCSfile$ : RCS文件名
$Source$ : RCS全路径名
$Name$ : 取回该版本的符号名
$Header$ : 相当于$ Source $$ Revision$$Date$$Author $$State$$Locker$的组合
比如:在java Source开头加入:
/*
*$Id$
*/
当commit该Java文件时候.cvs会把$Id替换为包含当前文件名,版本,时间,作者的字符串信息
星期日, 七月 18, 2004
星期六, 七月 17, 2004
Groovy及JSP在Web Module如何发现要打开的资源文件?
import java.util.Date
import java.io.File;
if (session.counter == null) {
session.counter = 1
}
out.println(<<<EOS
<html>
<head>
<title>Groovy Servlet</title>
</head>
<body>
Hello, ${request.remoteHost}: ${session.counter}! ${new Date()}
<br>src
</body>
</html>
EOS)
session.counter = session.counter + 1
//研究了许久.:(,如何打开一个脚本文件
File fl=new File(application.getRealPath("/groovy/HelloWorld.groovy"))
evaluate(fl)
如何利用Groovy和Apache POI 生成 Excel
import groovy.sql.Sql
import org.apache.poi.hssf.usermodel.*
import org.apache.poi.hssf.util.*
import java.io.File
if (args.size() != 1)
{
println(args.join(", "));
println("Error: expecting output filename as a commandline parameter");
System.exit(1);
}
Sql.loadDriver("oracle.jdbc.driver.OracleDriver")
sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:sid", "user", "password")
workbook = new HSSFWorkbook();
sheet = workbook.createSheet("Games");
sheet.setColumnWidth(1.shortValue(), 5600.shortValue())
sheet.setColumnWidth(2.shortValue(), 8000.shortValue())
sheet.setColumnWidth(3.shortValue(), 8000.shortValue())
rowNum = 0
sql.eachRow("select * from tb_game order by name", { game |
skuCount = 0
sql.eachRow("select count(*) from tb_sku where product_id = ${game.id}", { skuCount = it[0] })
row = sheet.createRow(rowNum++)
row.createCell(0.shortValue()).setCellValue(game.id.doubleValue())
row.createCell(1.shortValue()).setCellValue(game.name)
row.createCell(2.shortValue()).setCellValue(game.developer)
row.createCell(3.shortValue()).setCellValue(game.vendor)
row.createCell(4.shortValue()).setCellValue(skuCount.doubleValue())
})
new File(args[0]).withOutputStream({ os | workbook.write(os) })
星期四, 七月 15, 2004
星期一, 七月 12, 2004
Mysql: return Row number at SELECT statement
但是返回的记过将都是0.因为变量的不存在.
星期五, 七月 02, 2004
星期二, 六月 29, 2004
在XSL/XSLT中如何嵌入大段Javascript 的方法
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<!-- Javascript example 1: using CDATA sections -->
<!-- Example 1 ishould be used when embedding javascript snippets that don't make use of XML data during the transform -->
<xsl:text disable-output-escaping="yes">
<![CDATA[
<script>
alert("Generic hello world")
</script>
]]>
</xsl:text>
<!-- Javascript example 2: using xsl:text and disable-output-escaping -->
<!-- Example 2 should be used when embedding javascript snippets that need to make use of XML data during the transform -->
<xsl:text disable-output-escaping="yes"><</xsl:text>script<xsl:text disable-output-escaping="yes">></xsl:text>
alert("<xsl:value-of select="root/node" />")
<xsl:text disable-output-escaping="yes"><</xsl:text>/script<xsl:text disable-output-escaping="yes">></xsl:text>
<!-- the rest of your XSL transformation logic here -->
<xsl:value-of select="root/node" />
</xsl:template>
</xsl:stylesheet>
星期四, 六月 24, 2004
如何修改Jbuilder 的cvs服务器的有关设置
快速删除.所有CVS子目录;
for /R /D %f in (CVS*) do rmdir /S/q %f
星期一, 六月 21, 2004
JSP Form get 和 post 提交参数说明
但同get或通过连接通过?或&方式来传递汉字,必须要正确编码。有保证的是编码为iso-8859-1.
使用java.netURLEncode.encoder(string,string encode)
和Java.net.URLDecode.decoder(string,string encode)
偶合操作来解析汉字。
星期五, 六月 18, 2004
CodingForums.com - Want to Capture Window Close Event
http://msdn.microsoft.com/workshop/author/dhtml/reference/events/onbeforeunload.asp?frame=true
body 的onbeforeunload = "return 'YOUR MESSAGE HERE'"
星期四, 六月 17, 2004
星期五, 六月 11, 2004
星期二, 六月 08, 2004
手工删除Oralce 表空间数据文件后,重新启动Oracle Database Server不能启动.处理步骤.
在Oradata/Oracle实例下删除了某个表空间.dbf文件,重新启动Oracle服务时候,报错:
SVRMGR> startup ORACLE instance started.
Total System Global Area 84721824 bytes Fixed Size 73888 bytes Variable Size 76087296 bytes Database Buffers 8388608 bytes Redo Buffers 172032 bytes Database mounted.
ORA-01157: cannot identify/lock data file 8 - see DBWR trace file ORA-01110: data file 8: '/export/home1/ora8/m02/oradata/ora8/acs01.dbf'
2.处理步骤
1) Connect to SQL*DBA or Server Manager and issue 'shutdown abort'
2) Issue 'startup mount' command
3) Issue the following command, substituting the correct datafile (such as /u01/oradata/temp01.dbf):
alter database datafile '/u01/oradata/temp01.dbf' offline drop;
4) alter database open; (Your database is now up!!!)
5) drop tablespace TEMP including contents;
6)再次重新启动既可.
星期一, 五月 31, 2004
如何在Linux或Unix下,没有启动X Server 使用Java图形库
我们运行在Unix类操作系统下,在X Server没有启动的时候,很多图形库类无法使用,因为这些类需要获得图形设备的一些具体参数,比如dpi,color depth,raster等,在Linux下运行Java application Server经常是不启动X server的,在这种情况下如果需要使用图形类Class.需要在启动的命令行加入以下参数
-Djava.awt.headless=true
JAVA_OPTS=$JAVA_OPTS: -Djava.awt.headless=true
重新启动Application Server如Tomcat,就可以在Servlet中使用这些图形类了.
public BufferedImage DisplayTextPicture(String willtext)
{
int width = 48;
int height = 48;
float size = 8.0f;
int StringH = 8;
BufferedImage buffer = new BufferedImage(width,
height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 =(Graphics2D)buffer.getGraphics();
Font font = new Font("serif", Font.BOLD, StringH);
font = font.deriveFont(size);
FontRenderContext fc = g2.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(willtext,
fc);
width = (int) bounds.getWidth();
height = (int) bounds.getHeight() * 2;
buffer = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
g2 = (Graphics2D)buffer.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setFont(font);
g2.setColor(Color.white);
g2.fillRect(0, 0, width, height);
g2.setColor(Color.red);
String[] tem = willtext.split("\n");
for (int i = 0; i < tem.length; i++)
g2.drawString(tem[i], 0,
(int) - bounds.getY() + i * StringH);
return buffer;
}
public void Display2Servlet(String text,OutputStream os)
{
OutputStream sos=os;
try
{
boolean flag= ImageIO.write(DisplayTextPicture(text), "png", sos);
if(!flag){logger.log(Level.WARNING,"not success");}
sos.flush();
sos.close();
}catch(Exception e)
{
logger.log(Level.WARNING,e.getMessage());
return;
}
}
}
注意:通过 System.setProperty("java.awt.headless", "true");来改变GraphicsEnvirmont()为"无头"模式,可能是不起作用的,所以最好在命令行启动时候加入.
如何让MYSQL for window 建立的表格名称保持大小写敏感.
mysqld.exe -O lower_case_table_names=0
星期日, 五月 30, 2004
Java 如何在一个类中得知被哪个class的哪个方法调用。
import java.io.*;
public class mytest
{
public void inferCaller() {
// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace();
// First, search back to a method in the Logger class.
int ix = 0;
while (ix < stack.length) {
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
if (cname.equals(getClass().getName())) //当前的类正在被call的method
{
System.out.println("ix="+ix);
break;
}
System.out.println(cname+"类:"+frame.getMethodName());
ix++;
}
//ix=0;
// Now search for the first frame before the "Logger" class.
while (ix < stack.length) {
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
if (!cname.equals(getClass().getName()))
{
// We've found the relevant frame.
//在当前类之前的类是调用自己的类.
System.out.println(cname+":"+frame.getMethodName());
}
ix++;
}
}
}
星期五, 五月 28, 2004
jboss Transaction marked for rollback, possibly a timeout错误分析
1.在A表中建立一个记录.
2.在B表中建立一个记录.
思路:
在SessbionBean中分别调用两个table对应的entityBean的remote方法.
出现错误.
修正:在一个Entitybean的Create方法中完成插入两条记录.
MBSC 多字节字符传递规则.(JSP->Servlet/JSP->JSP)
1.JSP->JSP
汉字通过URL?a= &b= 方式在JSP之间传递的时候,必须将汉字java.net.URLEncoder.encode((String)request.getAttribute("academicPeriod"),"gb2312"),来编码,汉字的字符是要根据实际数据显示渲染的charset来定.
2.JSP->Servlet
汉字从JSP->Servlet必须编码为本地字符编码,不能为UTF-8字符.如果为UTF-8字符必须通过new String(STR.getBytes("UTF-8","iso-8859-1")来转换.
3.如果页面导航逻辑没有冲突,可以考虑把要传递的内容设置在bean或request.setAttribute().
星期三, 五月 19, 2004
在XML得到一组唯一的属性值
preceding-sibling", like select="/publish/book[not(year = preceding-sibling::book/year)]
在XML得到一组唯一的属性值
星期二, 五月 18, 2004
如何利用JSTL XML功能来把JDBC得到的数据转为HTML显示?
利用<x:parse var="xmldata">
<%
...Java Code.从jdbc得到数据.通过out.println输出.
%>
</x:parse>
<c:import var="xslt" url="/WEB-INF/xml/adsearchEmployee.xsl"/>
<x:transform xml="${xmldata}" xslt="${xslt}"/>
这样就得到了经过XSLT格式化的数据,Cool啊.
在JSTL 1.0中的XML如何支持Unicode?
<c:import url="/WEB-INF/xml/adsearchEmployee.xsl" var="xslt"/>
<x:transform xml="${xml}" xslt="${xslt}"/>
通过制定charEncoding来输入Unicode的XML数据文件.
星期六, 五月 15, 2004
groovy 和james真是两个好东西。
http://james.apache.org 最棒的纯java Email 平台。很棒啊。看看稳定性。
星期五, 五月 14, 2004
如何在Javascript压缩(trim)空格
/**
* remove White Space from start and/or end of given string
* White Space is defined as:
* - Space
* - Carriage Return
* - newline
* - form feed
* - TABs
* - Vertical TABs
**/
function _trim ( )
{
// / open search
// ^ beginning of string
// \s find White Space, space, TAB and Carriage Returns
// + one or more
// | logical OR
// \s find White Space, space, TAB and Carriage Returns
// $ at end of string
// / close search
// g global search
return this.replace(/^\s+|\s+$/g, "");
}
// Test this
var strDemo = ' something ';
var strStrip = strDemo.trim();
alert ( '|' + strDemo + '|\n' + '|' + strStrip + '|');
星期二, 五月 11, 2004
常用单词缩写及其他
The Architect’s Role
? The architect:
Visualizes the behavior of the system
Creates the blueprint for the system
Defines the way in which the elements of
the system work together
Distinguishes between functional and nonfunctional
system requirements
Is responsible for integrating non-functional
requirements into the system
星期五, 五月 07, 2004
使用Servlet动态生成文本图象.
*使用方法在HTML使用<img src="http://servletname"
*/
import java.awt.image.BufferedImage;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Color;
import java.awt.Font;
import javax.imageio.ImageIO;
import java.awt.font.*;
import java.awt.geom.*;
public class DisplayPicture extends HttpServlet {
private static final String text="不存在图片";
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
OutputStream sos=response.getOutputStream();
String storedirectory=getServletConfig().getInitParameter("FileDirectory");
if(storedirectory==null || storedirectory=="")
{
DisplayTextPicture("web.xml??");
return;
}
File pf=new File(storedirectory+"\\2.jpg");
FileInputStream fis;
if(!pf.exists())
{
response.setContentType("image/png");
ImageIO.write(DisplayTextPicture(text+"\n"+storedirectory),"png",sos);
sos.close();
return;
}
//set contenttype
response.setContentType("image/"+getFileType(pf));
fis = new FileInputStream(pf);
byte[] input=new byte[512];
int count=0;
while(fis.read(input) !=-1)
{
sos.write(input);
}
fis.close();
sos.flush();
sos.close();
}
public String getFileType(File pf)
{
String type="gif";
if(pf.getName().toLowerCase().endsWith(".png"))
{
type = "png";
}
if(pf.getName().toLowerCase().endsWith(".gif"))
{
type = "gif";
}
if(pf.getName().toLowerCase().endsWith(".jpg"))
{
type = "jpg";
}
if(pf.getName().toLowerCase().endsWith(".bmp"))
{
type = "bmp";
}
return type;
}
/**
*DisplayTextPicture支持多行显示图片,分割符号为\n
**/
public BufferedImage DisplayTextPicture(String willtext)
{
int width=48;
int height=48;
float size=20.0f;
int StringH=20;
BufferedImage buffer =new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
Graphics2D g2=buffer.createGraphics();
Font font = new Font("serif", Font.BOLD, StringH);
font = font.deriveFont(size);
FontRenderContext fc = g2.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(willtext,fc);
width = (int) bounds.getWidth();
height = (int) bounds.getHeight()*2;
buffer =new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
g2=buffer.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setFont(font);
g2.setColor(Color.white);
g2.fillRect(0,0,width,height);
g2.setColor(Color.blue);
String[] tem=willtext.split("\n");
for(int i=0;i<tem.length;i++)
g2.drawString(tem[i],0,(int)-bounds.getY()+i*StringH);
return buffer;
}
}
星期四, 五月 06, 2004
IE 层如何显示Layer.
<div id="contentLayer" style="position:absolute; width:202px; height:52px; z-index:1; top: 242px; visibility: visible;background-image:url(c://2.jpg)" >