Groovy 学习笔记 (四)

  1. Groovy 支持操作符重载, 每个操作符对应一个方法签名, 如‘+’对应的是’plus’.
  2. Groovy 支持多种字符串表示, 单引号, 双引号(支持GString), 3个单引号(支持多行), 3个双引号(支持多行, 支持GString).
  3. 在 Groovy 中, 方法的括号是可选的, 如果一行只有一个语句, 那么语句后的分号也可省略不写.
  4. Groovy range, 可用于: 数字, 日期, 字符串. 只要数据类型实现了 next(++), previous(–), 和 java.lang.Comparable 接口, 就可以使用 range .
  5. Groovy list 默认使用 ArrayList, 欲使用 LinkedList 等其它类型 List, 需要明确声明.
  6. List 可以使用负值作为index值进行访问, 例如 list[-1]返回的就是list的最后一个值, list[-2]则返回倒数第二个值. 也可以指定倒序的 range, 如list[4..0].
  7. 需注意: list[0..<-2] 等价于 list[0..-1] 而非 list[0..-3].
  8. 声明空的map: [:]
  9. ['a':1] 等价于 [a:1]
By javafuns on August 25, 2009 at 22:22 · Views: 429 · Permalink · RSS · Leave a comment
Categorized in: Scripts · Tagged with: , ,

Groovy 学习笔记 (三)

1. == 是判断是否 equals, 而判断是否是同一对象则用 is

2. list 和 map 的一些方法:

def x  = 1..10
assert x.contains(5)
assert x.contains(15) == false
assert x.size()    == 10
assert x.from      == 1
assert x.to        == 10
assert x.reverse() == 10..1

3. 以下对象都有 size() 方法
Array, String, StringBuffer, Collection, Map, File

4. 数据类型:12 – Integer, 100L – Long, 1.23F – Float, 1.23D – Double, 123G – BigInteger, 1.23,1.23G – BigDecimal

如果一个小数, 末尾什么字符都没加, 那么这个小数使用的是 BigDecimal.

5. 操作符重载

Operator Name Method Works with
a + b Plus a.plus(b) Number,string,collection
a – b Minus a.minus(b) Number,string,collection
a * b Star a.multiply(b) Number,string,collection
a / b Divide a.div(b) Number
a % b Modulo a.mod(b) Integral number
a++ Post increment a.next() Number,string,range
++a Pre increment
a– Post decrement a.previous() Number,string,range
–a Pre decrement
a**b Power a.power(b) Number
a | b Numerical or a.or(b) Integral number
a & b Numerical and a.and(b) Integral number
a ^ b Numerical xor a.xor(b) Integral number
~a Bitwise complement a.negate() Integral number,string
(the latter returning a regular expression pattern)
a[b] Subscript a.getAt(b) Object,list,map,string、Array
a[b] = c Subscript assignment a.puAt(b,c) Object,list,map,StringBuffer,
Array
a << b Left shift a.leftShift(b) Integral number, also used like “append” to StringBuffers, Writers, Files, Sockets, Lists
a >> b Right shift a.rightShift(b) Integral number
a >>> b Right shift unsigned a.rightShiftUnsigned(b) Integral number
switch(a){
case b:
}
Classification b.isCase(a) Object, range, list, collection, pattern, closure; also used with collection c in c.grep(b), which returns all items of c where b.isCase(item)
a == b Equals a.equals(b) Object, consider hashCode()
a != b Not equals !a.equals(b) Object
a <=> b Spaceship a.compareTo(b) java.lang.Comparable
a > b Greater than a.compareTo(b) > 0
a >= b Greater than or equal to a.compareTo(b) >= 0
a < b Less than a.compareTo(b) < 0
a <= b Less than or equal to a.compareTo(b) <= 0
a as type Enforced coercion a.asType(typeClass) Any type
class Money {
  private int    amount
  private String currency
  Money (amountValue, currencyValue) {
    amount   = amountValue
    currency = currencyValue
  }

  boolean equals (Object other) {
    if (null == other)              return false
    if (! (other instanceof Money)) return false
    if (currency != other.currency) return false
    if (amount    != other.amount)  return false
    return true
  }

  int hashCode() {
    amount.hashCode() + currency.hashCode()
  }

  Money plus (Money other) {
    if (null == other)    return null
    if (other.currency != currency) {
      throw new IllegalArgumentException("cannot add $other.currency to $currency")
    }
    return new Money(amount + other.amount, currency)
  }
}
def buck = new Money(1, 'USD')
d Use overridden ==
assert buck
assert buck == new Money(1, 'USD')
e Use overridden +
assert buck + buck == new Money(2, 'USD')

6.

By javafuns on August 5, 2009 at 22:21 · Views: 399 · Permalink · RSS · Leave a comment
Categorized in: Scripts · Tagged with: , ,

The interesting but useful mock assertion in Java

在某开源项目里, 发现它使用了一种很有意思的 assertion 机制. 这是一种仿 assertion 的方式来实现对输入参数或特定表达式的判断.

伪代码如下:

  public final class Assert {
    private Assert() {}

    public static void notNull(Object o) {
      notNull("Null object is used", o);
    }

    public static void notNull(String description, Object o) {
      if(o == null) {
        throw new AssertionException(description);
      }
    }

    ...... // other assertion methods
  }

AssertionException 继承自 RuntimeException, 因此是可以不捕获的.

在某方法里可以如此使用这个 Assert :

  public void someMethod(String arg1 ...) {
    Assert.notNull(arg1);
    ...
  }

好处是:
1. 类似 Java 已有的 Assertion 机制, 使用起来非常直观.
2. 减少了大量对参数进行 if-else 等的判断, 代码看起来更加整洁, 易懂.
3. 对类似错误可以进行统一处理, 对错误信息进行统一描述.

By javafuns on July 30, 2009 at 10:55 · Views: 412 · Permalink · RSS · Leave a comment
Categorized in: Java · Tagged with: ,

XML 中的 schemaLocation 属性究竟是什么意思?

在 XML 实例文档中有时会发现有 schemaLocation 属性。很多人对此非常疑惑,搞不清这个属性究竟是什么意思,究竟该如何使用。

schemaLocation 属性用来引用(schema)模式文档,解析器可以在需要的情况下使用这个文档对 XML 实例文档进行校验。它的值(URI)是成对出现的,第一个值表示命名空间,第二个值则表示描述该命名空间的模式文档的具体位置,两个值之间以空格分隔。当然,在必要情况下,可以为 schemaLocation 属性指派多个这样的值对。

<p:Person
  xmlns:p="http://contoso.com/People"
  xmlns:v="http://contoso.com /Vehicles"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation=
    "http://contoso.com/People

http://contoso.com/schemas/people.xsd

http://contoso.com/schemas/Vehicles

http://contoso.com/schemas/vehicles.xsd

http://contoso.com/schemas/People

    http://contoso.com/schemas/people.xsd">
  <name>John</name>
  <age>28</age>
  <height>59</height>
  <v:Vehicle>
    <color>Red</color>
    <wheels>4</wheels>
    <seats>2</seats>
  </v:Vehicle>
</p:Person>

如果为没有目标命名空间的模式文档指定位置,需用 noNamespaceSchemaLocation 属性.


By javafuns on July 23, 2009 at 13:43 · Views: 908 · Permalink · RSS · Leave a comment
Categorized in: SOA · Tagged with: ,

Java Thread 注意事项

  1. 该同步要同步
  2. 同步块尽可能的小
  3. 循环内使用wait()
  4. synchronized (obj) {
        while (condition) {
            obj.wait();
        }
    }
    因为唤醒后,条件是否满足还不一定,所以还需要再次检查。
  5. notifyAll()优先于notify()
  6. yield()不可靠
  7. 在持有锁的时候, 尽量不要调用其它对象的方法(这些方法可能也是同步过的), 因为这很可能是死锁的源头.
  8. 对象锁:使用对方法进行synchronized时,线程进入该方法前需先获得该对象上的同步锁。所以,即使另外一个线程调用的是该对象上的另一个方法,因为此时该对象锁已被另一线程占有,所以该线程还是要排队等候以占有对象锁。
    由于线程进入非同步方法并不需要占有锁,所以非同步方法并不会被该对象上的同步方法所阻塞。

    对象锁:使用对方法进行synchronized时,线程进入该方法前需先获得该对象上的同步锁。所以,即使另外一个线程调用的是该对象上的另一个方法,因为此时该对象锁已被另一线程占有,所以该线程还是要排队等候以占有对象锁。由于线程进入非同步方法并不需要占有锁,所以非同步方法并不会被该对象上的同步方法所阻塞.

  9. 类锁:对静态方法进行 synchronized,那么就决定了进入该静态同步方法前,线程必须先获得类锁。类锁其实是并不存在的,原因在于类锁是基于类的class对象,每个类都有唯一的一个class对象与之对应,该类的所有实例也都拥有该唯一class对象的引用,因此,静态同步方法所使用的锁其实就是类的class对象,本质上还是一个对象锁.
  10. 基于以上两点,对象锁与类锁互不相干,因为它们的锁是完全不同的.
  11. ThreadDeath 是 Error 的子类. 调用 Thread 类中带有零参数的 stop 方法(该方法已不推荐使用)时,受害线程将抛出一个 ThreadDeath 实例.
  12. 线程优先级取决于底层实现, 应尽量避免使用.
  13. 线程结束后,再次调用该线程对象的 start() 方法会抛出异常,也就是不要重新开始一个已经执行完毕的线程.
  14. 守护线程与非守护线程的区别: 当进程中所有非守护线程已(结束或)退出时, 即使仍有守护线程在运行,进程仍将结束.
  15. Thread.UncaughtExceptionHandler接口:当线程因未捕获异常而终止时,会调用本接口的实现进行处理。Thread.setDefaultUncaughtExceptionHandler静态方法设置的是全局默认处理程序。可对单个thread、ThreadGroup对象设置未捕获异常处理程序。调用顺序是:先尝试使用thread的未捕获异常处理程序,如果该线程未设置,则使用该线程所属线程组的,如果线程组也没有设置,则使用默认的未捕获异常处理程序。
By javafuns on July 22, 2009 at 22:07 · Views: 350 · Permalink · RSS · Leave a comment
Categorized in: Java · Tagged with: ,

SMTP Transport Binding for SOAP

SOAP 除了可以 bind 到 HTTP 上外, 也可以 bind 到 SMTP 上. 其实个人感觉, SOAP bind 到 SMTP 上的场景很少会使用到, 通常限于 one-way operation (比如通知等不需要响应). 如果需要实现 request/response, 那么是需要多做一些工作的(下文会有叙述).

soap:binding element 的 transport 属性需指定一个 http://xxx(例如:http://schemas.xmlsoap.org/soap/smtp) URL 来表明所要 binding 的 protocol. 似乎这个 URL 是任意形式, 只要能让调用方知道要使用什么协议即可. 在 soap:address 要给定 mailto:xxxx@xxx.xxx 这样形式的 URI.

    <service name="StockQuoteServiceBinding_service">
        <port name="StockQuoteServiceBinding_port"
                binding="binding:StockQuoteServiceBinding">
            <soap:address location="mailto:getQuote@test.com"/>
        </port>
    </service>

注意: 在 soap:address element 中, 可能会有一些扩展元素, 例如smtp server, smtp username, smtp password, etc.

在需要 request / response 语义情况下, 需使用标准的 Message-Id 和 In-Reply-To SMTP header 来实现这一目标. 请求包含一个 Message-Id header, 相应的响应则在 In-Reply-To header 中使用请求的 Message-Id header 值, 同时也创建一个新的 Message-Id header. 这样, 在请求与响应之间便建立了关联.

请求:

To: <soap@example.org>
 From: <soap@client.com>
 Reply-To: <soap@client.com>
 Date: Tue, 15 Nov 2001 23:27:00 -0700
 Message-Id: <1F75D4D515C3EC3F34FEAB51237675B5@client.com>
 MIME-Version: 1.0
 Content-Type: text/xml; charset=utf-8
 Content-Transfer-Encoding: QUOTED-PRINTABLE

 <?xml version=3D"1.0" encoding=3D"UTF-8"?>
 <SOAP-ENV:Envelope SOAP-ENV:encodingStyle=3D"http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:SOAP-ENC=3D"http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:SOAP-ENV=3D"http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd=3D"http://www.w3.org/2001/XMLSchema"
 xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance">
 <SOAP-ENV:Body>
 <m:echoString xmlns:m=3D"http://soapinterop.org/">
 <inputString>get your SOAP over SMTP here !</inputString>
 </m:echoString>
 </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

响应:

To: <soap@client.com>
 From: <soap@example.org>
 Date: Tue, 13 Nov 2001 23:27:00 -0700
 In-Reply-To: <1F75D4D515C3EC3F34FEAB51237675B5@client.com>
 Message-Id: <FF75D4D515C3EC3F34FEAB51237675B5@soap.example.org>
 MIME-Version: 1.0
 Content-Type: TEXT/XML; charset=utf-8
 Content-Transfer-Encoding: QUOTED-PRINTABLE

 <?xml version=3D"1.0" encoding=3D"UTF-8"?>
 <SOAP-ENV:Envelope SOAP-ENV:encodingStyle=3D"http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:SOAP-ENC=3D"http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:SOAP-ENV=3D"http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd=3D"http://www.w3.org/2001/XMLSchema"
 xmlns:xsi=3D"http://www.w3.org/2001/XMLSchema-instance">
 <SOAP-ENV:Body>
 <m:echoStringResponse xmlns:m=3D"http://soapinterop.org/">
 <return>get your SOAP over SMTP here !</return>
 </m:echoStringResponse>
 </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

Resources:

  1. http://www.pocketsoap.com/specs/smtpbinding/
  2. http://people.apache.org/~pzf/SMTPBase64Binding.html
By javafuns on July 19, 2009 at 23:37 · Views: 366 · Permalink · RSS · Leave a comment
Categorized in: SOA · Tagged with: , , , ,

Java 中类的重载与覆盖之间的一点小区别

大的区分我想熟悉 Java 这门语言的人都知道,本文仅为记录在阅读《Effective Java》时所遇到的新知识。

在《Effective Java》中,Joshua Bloch提到:对于重载方法 (overloaded method) 的选择是静态的,而对于被改写的方法 (overridden method) 的选择是动态的。

对于被改写的方法,选择正确的方法版本是在运行时刻进行的,选择的依据是被调用方法所在对象的运行时类型。如果被改写方法是在子类实例上被调用,那么该子类实例中的方法将会执行。

而对于重载方法,则恰恰与改写方法的行为相反。

请看如下例子:

public class CollectionClassifier {

    public static String classify(Set s) {
        return "Set";
    }

    public static String classify(List l) {
        return "List";
    }

    public static String classify(Collection c) {
        return "Unknown Collection";
    }

    public static void main(String[] args) {
        Collection[] cs = new Collection[] {
            new HashSet(), new ArrayList(), new HashMap().values()
        };

        for (Collection c : cs) {
            System.out.println(classify(c));
        }
    }
}

在这个例子中,将打印 “Unknown Collection” 三次。这是因为到底调用哪个重载方法是在编译时刻就做出决定的。在三次循环中,参数的编译类型都是:Collection。

By javafuns on July 8, 2009 at 22:54 · Views: 383 · Permalink · RSS · Leave a comment
Categorized in: Java · Tagged with: 

Which style of WSDL should I use? (reship)

Russell Butek (butek@us.ibm.com), SOA and Web services consultant, IBM

Date: 24 May 2005 (Published 31 Oct 2003)
Level: Advanced

Summary: A Web Services Description Language (WSDL) binding style can be RPC or document. The use can be encoded or literal. How do you determine which combination of style and use to use? The author describes the WSDL and SOAP messages for each combination to help you decide.

Introduction

A WSDL document describes a Web service. A WSDL binding describes how the service is bound to a messaging protocol, particularly the SOAP messaging protocol. A WSDL SOAP binding can be either a Remote Procedure Call (RPC) style binding or a document style binding. A SOAP binding can also have an encoded use or a literal use. This gives you four style/use models:

  1. RPC/encoded
  2. RPC/literal
  3. Document/encoded
  4. Document/literal

Add to this collection a pattern which is commonly called the document/literal wrapped pattern and you have five binding styles to choose from when creating a WSDL file. Which one should you choose?

Before I go any further, let me clear up some confusion that many of us have stumbled over. The terminology here is very unfortunate: RPC versus document. These terms imply that the RPC style should be used for RPC programming models and that the document style should be used for document or messaging programming models. That is not the case at all. The style has nothing to do with a programming model. It merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model.

Likewise, the terms encoded and literal are only meaningful for the WSDL-to-SOAP mapping, though, at least here, the traditional meanings of the words make a bit more sense.

For this discussion, let’s start with the Java method in Listing 1 and apply the JAX-RPC Java-to-WSDL rules to it (see Resources for the JAX-RPC 1.1 specification).

Listing 1. Java method

public void myMethod(int x, float y);

RPC/encoded

Take the method in Listing 1 and run it through your favorite Java-to-WSDL tool, specifying that you want it to generate RPC/encoded WSDL. You should end up with something like the WSDL snippet in Listing 2.
Listing 2. RPC/encoded WSDL for myMethod

<message name="myMethodRequest">
    <part name="x" type="xsd:int"/>
    <part name="y" type="xsd:float"/>
</message>
<message name="empty"/>

<portType name="PT">
    <operation name="myMethod">
        <input message="myMethodRequest"/>
        <output message="empty"/>
    </operation>
</portType>

<binding .../>
<!-- I won't bother with the details, just assume it's RPC/encoded. -->

Now invoke this method with “5″ as the value for parameter x and “5.0″ for parameter y. That sends a SOAP message which looks something like Listing 3.
Listing 3. RPC/encoded SOAP message for myMethod

<soap:envelope>
    <soap:body>
        <myMethod>
            <x xsi:type="xsd:int">5</x>
            <y xsi:type="xsd:float">5.0</y>
        </myMethod>
    </soap:body>
</soap:envelope>

A note about prefixes and namespaces

For the most part, for brevity, I ignore namespaces and prefixes in the listings in this article. I do use a few prefixes that you can assume are defined with the following namespaces:

  • xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
  • xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  • xmlns:soap=”http://schemas.xmlsoap.org/soap/envelope/”

For a discussion about namespaces and the WSDL-to-SOAP mapping, see paper “Handle namespaces in SOAP messages you create by hand” (see Resources).

There are a number of things to notice about the WSDL and SOAP message for this RPC/encoded example:

Strengths

Weaknesses

Is there a way to keep the strengths and remove the weaknesses? Possibly. Let’s look at the RPC/literal style.

By javafuns on July 7, 2009 at 16:40 · Views: 839 · Permalink · RSS · Leave a comment
Categorized in: SOA · Tagged with: , , , , ,
  • Highest Rated

  • My PicasaPhotos

    IMG_0633.JPG

    IMG_0522.JPG

    Img253474329.jpg

  • RSS My del.icio.us

  • My RSS