Thursday, April 11, 2013

Gson

JSON 的 serialization 库,挺好用。
import com.google.gson.Gson ;
import java.util.List ;
import java.util.Map ;
import java.util.HashMap ;
import java.util.Arrays ;

public class TestGson {
    public static class Foo {
        public int a ;
        public String b ;
        public int[] c ;
        public List d ;
        public Map e ;
    }

    public static void main (String[] args) {
        Foo bar = new Foo ();
        bar.a = 1 ;
        bar.b = "abc" ;
        bar.c = new int[] {6,7,8} ;
        bar.d = Arrays.asList ("hello", "world") ;
        bar.e = new HashMap () ;
        bar.e.put ("zoo", 3) ;
        bar.e.put ("keeper", 5) ;

        Gson gson = new Gson () ;
        String s = gson.toJson (bar) ;
        System.out.println (s) ;
        Foo bb = gson.fromJson (s, Foo.class) ;
        System.out.println (gson.toJson (bb)) ;
    }
}
文档见此

Thursday, February 14, 2013

jOOQ

这个小工具不像 Hibernate 等那么 heavy,似乎比较容易帮助写 SQL(特别对怎么写 SQL 不是太熟悉的人来说)。之外,当然还可以帮助你执行(需要建立到 DataSource 或者 DB connection 的连接),接口比较简单,适合轻量级应用,停留在 table 级(不需要映射到对象)的用途,下面是个简单的例子,展示如何生成 SQL。
import org.jooq.impl.Factory ;
import org.jooq.SQLDialect ;
import static org.jooq.impl.Factory.*;

public class App {
    public static void main( String[] args ) {
        Factory create = new Factory (SQLDialect.H2) ;
        String sql = create.select ()
            .from (tableByName ("foo"))
            .where (fieldByName ("bar").equal ("foobar"))
            .getSQL () ;
        System.out.println (sql);
    }
}

Sunday, January 27, 2013

java.lang

java.lang 里面的类默认都是被 import 的,我们这里列出来它提供的常用分类:
  • primitive 的衍生类,不过值得注意的是 JDK 现在支持 boxing/unboxing 了,原先传递 int 的地方不需要将 Integer 转换了再传递了。这些类都是 immutable 的,即创建之后无法修改,除非更换引用的对象。如果希望使用 mutable 的版本可以使用 org.apache.commons.lang3 提供的 mutable.* 里面的对应实现
  • 系统相关的放在 System 里面,除了三个输入输出设备以外,提供了与 OS 的接口,如环境变量,获得或者设定系统属性
  • 数学函数放在 Math 里面
  • 进程线程支持包括 Process、ProcessBuilder、Thread、ThreadGroup 和 ThreadLocal、InheritableThreadLoad
  • 语言相关的有 Compiler、Class、ClassLoader、Package
  • 提供了一些常用的 Exception,Exception 的父类是 Throwable,需要区分的概念是 Error(同样继承了 Throwable),区别是 Error 系的一般不建议 catch 而 Exception 建议处理。另外需要注意的概念是 Exception 包含 checked 和 unchecked 两种,看现在的趋势是尽量不要用 checked exception,唯一用 checked exception 的位置是用这个类/方法的人必须得处理这个 exception。Exception 的子类除了 RuntimeException 以外都是 checked。
  • 提供了三个 annotation、Deprecated、SuppressWarnings 和 Override
hmm... 这算是基础知识了,我才开始学习...

Thursday, January 24, 2013

retry 的一种实现

调用外部的 service 总会有失败的可能,我们总会不停的写 while 什么 try,然后 catch 到 exception 就 Thread.sleep 之后继续,直到 fail 次数足够多了或者如何我们才放手。为了减少这种重复的 code,一个叫 sarge 的 library 使得整个问题变得简单了很多。我们看看下面的例子:
import org.jodah.sarge.Plan ;
import org.jodah.sarge.Plans ;
import org.jodah.sarge.Sarge ;
import org.jodah.sarge.util.Duration ;
 

Plan plan = Plans
   .retryOn (RuntimeException.class, 5, Duration.millis(10))
   .escalateOn (InterruptedException.class)
   .rethrowOn (IllegalArgumentException.class)
   .make();
 

Sarge sarg = new Sarge () ;

App app = sarg.supervise (App.class, plan) ;

app.mayFail () ;

app.fail () ;
这里实现的诀窍大概就是为这些东西创建一个 proxy,这些 proxy 有我们定制过的 handler,handler 将 Plan 的细节应用到传递 Method 的过程中,比如如果 catch 到了某个 exception 就交给 Plan 分析如何处理。这也算是一种 decorator 么?

Tuesday, January 15, 2013

计算 HMAC

如何使用 Java 计算数字签名。
import javax.crypto.KeyGenerator ;
import javax.crypto.Mac ;
import javax.crypto.SecretKey ;
import javax.crypto.spec.SecretKeySpec ;

import java.security.NoSuchAlgorithmException ;
import java.security.InvalidKeyException ;

import org.apache.commons.codec.binary.Base64 ;

public class TestHMAC {
    SecretKey key ;
    Mac mac ;

    public String getKey () {
 byte[] bin = key.getEncoded () ;
 byte[] ascii = Base64.encodeBase64 (bin) ;
 return new String (ascii) ;
    }

    public TestHMAC (String alg)
 throws NoSuchAlgorithmException, InvalidKeyException {
 KeyGenerator gen = KeyGenerator.getInstance (alg) ;
 key = gen.generateKey () ;
 mac = Mac.getInstance (key.getAlgorithm ()) ;
 mac.init (key) ;
    }

    public TestHMAC (String alg, String k)
 throws NoSuchAlgorithmException, InvalidKeyException {
 byte [] ascii = k.getBytes () ;
 byte [] c = Base64.decodeBase64 (k) ;
 key = new SecretKeySpec (c, alg) ;
 mac = Mac.getInstance (key.getAlgorithm ()) ;
 mac.init (key) ;
    }

    public byte[] hash (Object o) {
 byte[] c = o.toString ().getBytes () ;
 return mac.doFinal (c) ;
    }

    public String hashToAscii (Object o) {
 byte [] hash = hash (o) ;
 byte [] ascii = Base64.encodeBase64 (hash) ;
 return new String (ascii) ;
    }

}