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)) ; } }
Java Newbie
Thursday, April 11, 2013
Gson
JSON 的 serialization 库,挺好用。
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
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) ; } }
Thursday, December 13, 2012
Apache Commons --- BSF
BSF 亦即 bean scripting framework 也就是对 bean 的 scripting language 方面的支持,这个支持主要是通过 BSFManager 来做到的,实现一个语言到这个 framework 里面需要继承 BSFManagerImpl 并 override 掉其中一部分方法,最核心的是 eval。有了每个语言对应的 BSFManager 我们就能用 JVM 来解析各种 scripting language 了。在 scripting language 的 domain 里面存在一个 bsf 对象,通过它可以调用 BSFManager 的方法,比如
有一些参考的例子,比如 JDEE 里面带了一个所谓的 beanshell,这个就是 Java 语言自己的 scripting engine。
当然 BSF 其实自己就支持了不少流行的语言,如 jython、groovy、Javascript 之类的,其他的像 JRuby 自带了 BSF 的支持。
另外 BSF 自己有一个已经实现好的命令行工具供我们把玩:
BSF 现在有 3.x 版本了,似乎也开始使用 javax.scripting 的接口了。
- registerBean
- lookupBean
有一些参考的例子,比如 JDEE 里面带了一个所谓的 beanshell,这个就是 Java 语言自己的 scripting engine。
当然 BSF 其实自己就支持了不少流行的语言,如 jython、groovy、Javascript 之类的,其他的像 JRuby 自带了 BSF 的支持。
另外 BSF 自己有一个已经实现好的命令行工具供我们把玩:
java -cp bsf-2.4.0/lib/bsf.jar org.apache.bsf.Main -in test.py
BSF 现在有 3.x 版本了,似乎也开始使用 javax.scripting 的接口了。
Tuesday, December 11, 2012
Apache Commons --- Betwixt
说起 beans 一直都比较陌生,为了好好了解一下 Java 自己的哲学,于是趁研究 Betwixt 的时候学习了一下 Java beans 到底是什么东西,简单的说 beans 是符合以下要求的 Java class,
正因为以上原因,beans 其实与某个 java package 是独立的,但是处理 beans 需要的一些手段被抽象出来,SDK 里面提供了 java.beans 这个 package,其中很多接口就能看出来主要是为了让这些 beans 与 IDE 等 framework 更好工作,比如
当然 java.beans 提供的一些支持还比较接近底层,特别是和 IDE 打交道的部分,同时里面还提供了两个类跟这里 Betwixt 有关,那就是 XMLDecoder 和 XMLEncoder,两者负责将一个 bean 写到 XML 文件里面或者从里面构造出一个 bean。Betwixt 的目标就是将这个转换过程变成可以控制的,通过尽量少的代价干涉定制者得到需要的效果。直接用 XMLEncoder 的话大致如下
参看 userguide、API 和例子。
- default constructible,即可以默认构造,但这个并不保证对应的 bean 处于 valid 状态
- 所有的“属性”都含有 getter/setter 方法,这两个方法必须满足前者返回对应类型不带参数,后者带一个参数返回 void
- 实现了 java.io.Serializable,这包括 readObject、writeObject 和 readObjectNoData 三个方法
正因为以上原因,beans 其实与某个 java package 是独立的,但是处理 beans 需要的一些手段被抽象出来,SDK 里面提供了 java.beans 这个 package,其中很多接口就能看出来主要是为了让这些 beans 与 IDE 等 framework 更好工作,比如
- BeanInfo 获得 bean 的一些 property 等信息,Customizer 用来为 bean 某些信息进行更新
- DesignMode 用来判断是否在设计界面(如 applet 的设计),PropertyEditor 用来帮助编辑属性
当然 java.beans 提供的一些支持还比较接近底层,特别是和 IDE 打交道的部分,同时里面还提供了两个类跟这里 Betwixt 有关,那就是 XMLDecoder 和 XMLEncoder,两者负责将一个 bean 写到 XML 文件里面或者从里面构造出一个 bean。Betwixt 的目标就是将这个转换过程变成可以控制的,通过尽量少的代价干涉定制者得到需要的效果。直接用 XMLEncoder 的话大致如下
import java.beans.XMLEncoder ; public class TestBeanCodec { private int age ; public int getAge () { return age ; } public void setAge (int a) { age = a ; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public static void main (String[] args) { TestBeanCodec bean = new TestBeanCodec () ; bean.setAge (5) ; bean.setName ("foo") ; XMLEncoder encoder = new XMLEncoder (System.out) ; encoder.writeObject (bean) ; encoder.close () ; } }使用 betwixt 的话我们为每个 class 提供一个 class.betwixt 文件打包到 jar 里面,之后使用 org.apache.commons.betwixt 里面的 BeanWriter/BeanReader 就能进行定制化的输入输出了。
参看 userguide、API 和例子。
Subscribe to:
Posts (Atom)