Simple JSON Library 1.0 リリース

誰も使っていないという噂のJSON Libraryのversionを1.0にアップしますた。誰も使ってないのに正式リリースとはこれ如何に。

おそらく他のJSONライブラリよりもPOJOを有効活用してくれるライブラリにはなってると思うのだけれど……自信なし。

[2007/05/28追記] 最新版はsourceforge.jpよりダウンロードください。

変更点は、以下の通り

  • Javaの標準的な記法に従いクラス名をJsonからJSONに変更
  • debug用にPretty Print機能(=タブ、改行など読みやすく整形)を追加
  • Beanに総称型指定のプロパティやフィールドがある場合には、その情報を使うように変更
  • 拡張しやすいようにstaticメソッドはそのままにメソッドの内容を通常のメソッドに移動
  • JSONによるメソッド実行機能を追加
  • 再帰の制約を緩和(自分のinstanceを返す場合のみ無視)した代りにネストの深さに上限を設けるように変更(setMaxDepthで変更可)

今回の目玉は5番目のJSONによるメソッド実行機能かなぁ。下記のような感じで任意の実行ができます。

// JSONによるメソッド実行
JSON json = new JSON();
Object retval = json.invoke(o, "メソッド名", "[1,2,3,4]");

特に2番目はWebアプリで任意のBeanのメソッドを呼びだしたい場合に利用できます。
例えば、下記のようなサーブレットを作りhttp://.../view/test.json?action=execute&data=[1,true]といったURLを叩くと、TestPage.javaのexecute(int, boolean)のメソッドが呼びだされ、結果をJSONで返すことができます(ただし、この例では呼び出しの制約がかかっていないのでセキュリティ上の問題があります。メソッドを呼び出せるか否かはJSONクラスのlimitメソッドをoverrideすることで対応します。デフォルトではObjectクラスで宣言されたメソッドは拒否するようになっています)。

public class ControlServlet extends HttpServlet {
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    execute(request, response);
  }

  protected void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String path = request.getServletPath();
    String action = request.getParameter("action");
    
    if (!StringUtil.isEmpty(action) && path.endsWith(".json")) {
      S2Container container = SingletonS2ContainerFactory.getContainer();
      
      NamingConvention namingConvention = (NamingConvention)container.getComponent(NamingConvention.class);
      
      String pagePath = path.substring(0, path.lastIndexOf('.')) + namingConvention.getViewExtension();
      String pageName = namingConvention.fromPathToPageName(pagePath);
      
      if (container.hasComponentDef(pageName)) {
        Object page = container.getComponent(pageName);
        
        Map<String, Object> output = new LinkedHashMap<String, Object>();
        JSON json = new JSON();
        json.setPrettyPrint(!Env.PRODUCT.equals(Env.getValue()));
        try {
          output.put("data", json.invoke(page, action, request.getParameter("data")));
        } catch (Exception e) {
          throw new ServletException(e);
        }
        
        PrintWriter writer = response.getWriter();
        response.setContentType("text/javascript");
        writer.write(json.format(output, new StringBuilder()).toString());
      } else {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
      }
    }
  }
}