2009년 11월 7일 토요일

SAStrutsでJSONを返す

SAStrutsでJSONを返すAdd Star

| 14:17 | はてなブックマーク - SAStrutsでJSONを返す - wataの日記

SAStrutsDBから取得した情報をJSON形式で返したいと思ったのでJSON-libを使ってみた。単純に取得したEntityを変換してやれば終わりだろうと思っていたらJSON-libがpublicフィールドに対応していない。だからといってgetter、setterを追加するのも馬鹿らしいと思ったのでMapに変換してからJSON形式に変換して回避。

ソースは以下のような感じになった。

	private static final String JSON_RES_HEADER = "application/json";

	@Resource
	protected EntityService entityService;

	@Execute(validator = false)
	public String index() {
		Map<String, Object> user = newHashMap();
		// ここでMapに変換
		BeanUtil.copyProperties(entityService.findById("entity"), user);
		ResponseUtil.write(JSONObject.fromObject(user).toString(), JSON_RES_HEADER, "utf-8");
		return null;
	}

publicフィールドは楽だが外部ライブラリを使うとなったときにまだまだ不便だなぁ。クラスロード時に動的にgetter、setterをつけるようにすればいいのだろうか。でもどれをつける、つけないが問題になったり、そのためにアノテーションや設定を書くのもなんだかなぁということになりそう

[jQuery] 유용한 링크 모음

[jQuery] 유용한 링크 모음, jQuery / Programming

2009/09/28 13:31

복사 http://blog.naver.com/joycestudy/100089925967

 

http://matthiasschuetz.com/javascript-framework-matrix/en/ 

- Javascript framework 비교표

- jQuery, MooTools, The Dojo Toolkit, Prototype, Script.aculo.us, Ext JS, Adobe Spry, BBC Glow, Yahoo! UI Library

- 특히, http://matthiasschuetz.com/javascript-framework-matrix/en/classes 클래스 만드는 예제는, 아주 깔끔하게 잘 정리했슴.

 

http://jquerylist.com/

- 1 페이지에 jQuery 주요 plugin 정보를 담은 리스트

- 카테고리별로 잘 정리

 

http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx

- jQuery를 ‘뛰어나게’ 사용하는 팁, 25가지나.

- 첫 번째가, 1. Load the framework from Google Code 이다.

 

http://www.sitepoint.com/blogs/2009/07/22/how-to-develop-a-jquery-plugin/

- jQuery Plugin을 개발하는 방법, 의외로 쉽다.

- plugin call 방법

- plugin declaration 방법

- plugin parameter 초기 설정 방법

- plugin main code: this.each(function() { ... });

 

http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-best-practices/

- unobtrusive DOM Scripting

- 아주, 기초적인 내용.

 

http://www.webdesignerwall.com/tutorials/jquery-tutorials-for-designers/

- 여러가지 효과(effect)에 대한 간결한 예제와 좋은 설명 for 디자이너

2009년 11월 6일 금요일

ServletException when SAStruts is executed on SDLoader-jsp21

SAStrutsをSDLoaderで動かそうとしたら ServletException。

javax.servlet.ServletException: javax.servlet.jsp.tagext.TagAttributeInfo.<init>(Ljava/lang/String;ZLjava/lang/String;ZZLjava/lang/String;ZZLjava/lang/String;Ljava/lang/String;)V
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:275)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:688)
	at sdloader.javaee.impl.FilterChainImpl.doFilter(FilterChainImpl.java:50)
	at org.seasar.framework.container.filter.S2ContainerFilter.doFilter(S2ContainerFilter.java:79)
	at sdloader.javaee.impl.FilterChainImpl.doFilter(FilterChainImpl.java:48)
        ~略~

エラーメッセージの内容が、TagAttributeInfoのコンストラクタで何かあったらしいので、調べると。

SAStrutsが同梱している geronimo-jsp_2.0_spec-1.0.jar は JSP2.0。

SDLoaderの中に含まれるJasperは、JSP2.1。

なので、geronimo-jsp_2.0_spec-1.0.jar をはずして起動で解決。

と思ったら、JSP2.0版のSDLoaderがあった。

なお、JSPがないもの、JSP20を使用するものは、Downloadsのタブの一覧からダウンロードできます。

sdloader - Project Hosting on Google Code

これをいれたら、geronimo-jsp_2.0_spec-1.0.jar を入れてても普通に動いた。。

以下は、SAStrutsをSDLoaderで起動するコード。

package boot;

import sdloader.SDLoader;
import sdloader.javaee.WebAppContext;
import sdloader.util.Browser;

public class Main {
    public static void main(String[] args) {
        
        String contextPath = "/sa-struts-tutorial";
        
        SDLoader loader = new SDLoader(true);
        loader.addWebAppContext(
            new WebAppContext(contextPath, "src/main/webapp"));
        loader.setPort(8080);
        
        loader.start();
        
        Browser.open("http://localhost:" + loader.getPort() + contextPath);
    }
}

FileSystemComponentAutoRegister vs JarComponentAutoRegister

seasarのFramworkを利用して、拡張共通モジュールを実装してて、
それをJARにして別のプロジェクトで使おうとしてるところ、
setter-injectionがうまくいかなかった。

問題はFileSystemComponentAutoRegisterは
diconファイルが存在するクラスパス(/WEB-INF/classes)をみるが、
jarの中にあるクラスは参照しきれなくてOUT!!

diconファイルの記述を変更し、JarComponentAutoRegister
に変更して問題解決。
修正前
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
  "http://www.seasar.org/dtd/components24.dtd">
<components>

  <include path="convention.dicon"/>
  <include path="s2jdbc.dicon"/>
  <component
    class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
  <property name="instanceDef">
    @org.seasar.framework.container.deployer.InstanceDefFactory@PROTOTYPE
  </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"hoge.hoge..framework.service"</arg>
      <arg>".*Service"</arg>
    </initMethod>
  </component>
  <component
    class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
  <property name="instanceDef">
    @org.seasar.framework.container.deployer.InstanceDefFactory@PROTOTYPE
  </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"hoge.hoge..framework.helper"</arg>
      <arg>".*Helper"</arg>
    </initMethod>
  </component>
  <component
    class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
  <property name="instanceDef">
    @org.seasar.framework.container.deployer.InstanceDefFactory@SESSION
  </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <initMethod name="addClassPattern">
      <arg>"hoge.hoge..framework.dto"</arg>
      <arg>".*Dto"</arg>
    </initMethod>
  </component>

</components>
修正後
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
  "http://www.seasar.org/dtd/components24.dtd">
<components>

  <include path="convention.dicon"/>
  <include path="s2jdbc.dicon"/>
  <component
    class="org.seasar.framework.container.autoregister.JarComponentAutoRegister">
  <property name="instanceDef">
    @org.seasar.framework.container.deployer.InstanceDefFactory@PROTOTYPE
  </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <property name="referenceClass">
      @hoge.hoge..framework.service.FwAbstractService@class
    </property>
    <property name="jarFileNames">"hoge-framework.*"</property>
    <initMethod name="addClassPattern">
      <arg>"hoge.hoge..framework.service"</arg>
      <arg>".*Service"</arg>
    </initMethod>
  </component>

  <component
    class="org.seasar.framework.container.autoregister.JarComponentAutoRegister">
  <property name="instanceDef">
    @org.seasar.framework.container.deployer.InstanceDefFactory@PROTOTYPE
  </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <property name="referenceClass">
      @hoge.hoge..framework.helper.FwConverterHelper@class
    </property>
    <property name="jarFileNames">"hoge-framework.*"</property>
    <initMethod name="addClassPattern">
      <arg>"hoge.hoge..framework.helper"</arg>
      <arg>".*Helper"</arg>
    </initMethod>
  </component>
    <property name="jarFileNames">"hoge-framework.*"</property>
    <initMethod name="addClassPattern">
      <arg>"hoge.hoge..framework.dto"</arg>
      <arg>".*Dto"</arg>
    </initMethod>
  </component>
  <component
    class="org.seasar.framework.container.autoregister.JarComponentAutoRegister">
  <property name="instanceDef">
    @org.seasar.framework.container.deployer.InstanceDefFactory@SESSION
  </property>
    <property name="autoNaming">
      <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
    </property>
    <property name="referenceClass">
      @hoge.hoge..framework.dto.LoginUserDto@class
    </property>
    <property name="jarFileNames">"hoge-framework.*"</property>
    <initMethod name="addClassPattern">
      <arg>"hoge.hoge..framework.dto"</arg>
      <arg>".*Dto"</arg>
    </initMethod>
  </component>


</components>

Seasar2のconvention.diconに複数のルートパッケージを追加

Seasar2のconvention.diconに複数のルートパッケージを追加

スズキです。

Seasar2でjarファイルにあるDAO(別パッケージ)をDI/AOPしようとしたときに、
今までは、JarComponentAutoRegisterをapp.diconに書くことによって
実現していました

近頃、SmartDeployを覚えて、同様のことを試すと、
例外が発生してしまいます。(どのような例外かは忘れてしまいました)

で、途方にくれていたら、ふと、
ルートパッケージを定義しているconvention.diconの、
実際にルートパッケージを追加するメソッドは
addRootPackageName
だったなー。
"add"!?、
"set"じゃないんだ!
ということで、下記を試してみたら、見事にjarのほうのパッケージも
ルートパッケージとして認識して、SmartDeployを通して、
DAOもDI/AOPされるようになりました。

--------convention.dicon
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC
    "-//SEASAR//DTD S2Container 2.4//EN"
    "http://www.seasar.org/dtd/components24.dtd">
<components>
  <component
      class="org.seasar.framework.convention.impl.NamingConventionImpl">
    <initMethod name="addRootPackageName">
      <arg>"jp.co.iret.suz.user"</arg>
    </initMethod>
    <initMethod name="addRootPackageName">
      <arg>"jp.co.iret.suz.common"</arg>
    </initMethod>
  </component>
</components>
--------

2009년 11월 5일 목요일

flexgrid install (sample)

http://code.google.com/p/flexigrid/downloads/list よりFlexigridをダウンロード。

     オプションで                       ------------------------- 2009.5.28 修正
       singleSelect: true,
       showToggleBtn: false,
       resizable: false,
       height: 150
  というようにshowToggleBtn: falseを指定するとエラーになります。

     flexigrid.js 996行目より (Date: 2008-07-14 00:09:43 +0800 版)
     ---------------------------------------------------------------------------------
     996:                           var nv = $('th:visible',g.hDiv).index(this);
     997:                           var onl = parseInt($('div:eq('+nv+')',g.cDrag).css('left'));
     998-old: //  2009.5.28 u       var nw = parseInt($(g.nBtn).width()) + parseInt($(g.nBtn).css('borderLeftWidth'));
     998-new:                       var nw = (p.showToggleBtn)?parseInt($(g.nBtn).width()) + parseInt($(g.nBtn).css('borderLeftWidth')):0; 
     999:                           nl = onl - nw + Math.floor(p.cgwidth/2);
     1000:                               
     1001:                          $(g.nDiv).hide();$(g.nBtn).hide();
     1002:                          
     1003-old: // 2009.5.28 u       $(g.nBtn).css({'left':nl,top:g.hDiv.offsetTop}).show();
     1003-new:                      if (p.showToggleBtn) $(g.nBtn).css({'left':nl,top:g.hDiv.offsetTop}).show();
     1004:                           
     1005:                          var ndw = parseInt($(g.nDiv).width());
     1006:                          
     1007:                          $(g.nDiv).css({top:g.bDiv.offsetTop});
                                    
                                    if ((nl+ndw)>$(g.gDiv).width())
                                        $(g.nDiv).css('left',onl-ndw+1);
                                    else
                                        $(g.nDiv).css('left',nl);
     ------------------------------------------------------------------------------------
     と修正するとよいと http://groups.google.com/group/flexigrid/browse_thread/thread/f87f8e68851ad379/27ad3d1ef29d77e7?lnk=raot  に載っていた。
     たしかにエラーがなくなった。これで hide: true の項目が表示されなくなる。
     ドラッグでカラムのリサイズを出来なくしたいのだがだめなようですね。


     public_htmlに展開して、JPよりカタカナ小文字入りをダウンロードして、半角→全角変換、
     さらにSJIS→UTF-8変換したもの。
     必要な sample1.html(index.html) と post3.php を修正したものを置いておきます。
     JQUERYはオリジナルのflexigrid内に含まれています。
JQUERY/Flexigrid.js一式ダウンロード:flexigrid-yuubin.tgz(2307KB)
     これをpublic_html ディレクトリに解凍して使います。

public_html/css

|-- flexigrid
|   |-- flexigrid.css
|   `-- images
|       |-- bg.gif
|       |-- btn-sprite.gif
|       |-- ddn.png
|       |-- dn.png
|       |-- fhbg.gif
|       |-- first.gif
|       |-- hl.png
|       |-- last.gif
|       |-- line.gif
|       |-- load.gif
|       |-- load.png
|       |-- magnifier.png
|       |-- next.gif
|       |-- prev.gif
|       |-- up.png
|       |-- uup.png
|       `-- wbg.gif
`-- images
    |-- add.png
    |-- bg.gif
    |-- btn-sprite.gif
    |-- close.png
    |-- ddn.png
    |-- dn.png
    |-- fhbg.gif
    |-- first.gif
    |-- hl.png
    |-- last.gif
    |-- line.gif
    |-- load.gif
    |-- load.png
    |-- magnifier.png
    |-- next.gif
    |-- prev.gif
    |-- up.png
    |-- uup.png
    `-- wbg.gif

public_html/js

|-- flexigrid.js
|-- flexigrid.pack.js
`-- jquery-1.3.2.js

public_html/flexigrid-yuubin

|-- Data-yuubin
|   |-- KEN_ALL.CSV
|   |-- README-DATA-YUUBIN-UTF8.TXT
|   `-- yuubin.sql
|-- chrom-yuubin.jpg
|-- firefox-yuubin.jpg
|-- ie-yuubin.jpg
|-- index.html
|-- magnifier.png
`-- post3.php

     Mysql にテーブルを作って、
      1. source yuubin.sql [Enter]
     CSVデータを
      2. load data local infile "KEN_ALL.CSV" into table yuubin fields terminated by ',' enclosed by '"';
     で読み込ませる。
      3. post3.php のユーザ名、パスワード、データベース名を修正する。
 
   http://localhost/~xxx/flexigrid-yuubin/index.html  で表示される。
      Quick Searchボタンをクリックして検索バーを表示する。
      検索項目と検索内容を入力し、[Enter]キーを押す。

2009년 11월 3일 화요일

JSONIC의 소개

http://jsonic.sourceforge.jp/

JSONICとは

JSONICは、Java用のシンプルかつ高機能なJSONエンコーダー/デコーダーライブラリです。
Java用のJSONライブラリはすでに多数存在しますが、JSONICはRFC 4627に従った正式なJSON形式でのデコード/エンコードを行いながらも、プログラミング言語に依存する情報をJSON内に含めることなくPOJO(Plain Old Java Object)と自然な変換を行える点に特徴があります。

使い方も非常に簡単です。

import net.arnx.jsonic.JSON;

// POJOをJSONに変換します
String text = JSON.encode(new Hoge());

// JSONをPOJOに変換します
Hoge hoge = JSON.decode(text, Hoge.class);

ダウンロード

ダウンロードはこちらからできます。なお、JSONICのビルド/実行には、Java 5.0以上が必要です。


基本的な使い方

通常の用途では、二つの静的メソッドencode/decodeだけ利用すれば事足ります。

■ encodeメソッド - POJOからJSONへの変換

POJOからJSONに変換する場合は、encodeを使います。デフォルトでは、空白などを含まない可読性の低いJSONが出力されますが、二番目の引数をtrueにすることで可読性の高いJSONが出力されるようになります(Pretty Printモード)。

なお、JSONのフォーマット中に何らかの例外が発生した場合は、JSONExceptionでラップされ通知されます(Beanからの取得時に例外発生など)。

// 変換対象のPOJOを準備
Hoge hoge = new Hoge();
hoge.number = 10;      // public field
hoge.setString("aaa"); // public property
hoge.setArray(new int[] {1, 2, 3});

// POJOをJSONに変換します。戻り値は {"number":10,"string":"aaa","array":[1,2,3]}となります
String text = JSON.encode(hoge);

// POJOを可読性の高いJSONに変換します。戻り値は次のような文字列になります
// {
//     "number": 10,
//     "string": "aaa",
//     "array": [1, 2, 3]
// }
String text = JSON.encode(hoge, true); 

// Appendable(StringBuffer, Writerなど)やOutputStreamを出力先にすることもできます(※1)
JSON.encode(hoge, new FileWriter("hoge.txt"));
JSON.encode(hoge, new FileOutputStream("hoge.txt"));
(※1) OutputStreamを指定した場合に出力される文字コードはUTF-8固定となります。 また、close処理は自動では行われませんので必要に応じて別途行う必要があります。