WebServiceの利用

JDK6から@WebServiceアノテーションを利用して
Webサービスを公開、利用できるようになったみたい。


なんでみたいかというと、まだちゃんと理解できていないのです。
とりあえず参考にしたサイトはITProのJava SE 6完全攻略です。
ここにはJAX-WSの事が書かれています。
今回仕事で一緒に働いている同僚から
WebServiceへのアクセス時にSpringではどうやるかということを聞きました。
それがここです。
Springの公式サイトに書かれていました。


まだJAX-WSの利用方法についても、SpringFrameworkについても
怪しいところ満載なので勉強中です。
まあ、忘れないうちにメモとして書いておきます。

eclipse.iniの設定

Mavenを利用してみたいなって思いました。
どうせならEclipseから使いたいという事で調査。


とりあえず簡単なのが良かったのでAmaterasIDEをダウンロードしてきました。
これにはm2eclipseも入っているので簡単です。おまけに日本語版のEclipse
以前は英語版を使っていました。
日本語でエラーが出ると検索するの大変なので。
とりあえず、Eclipseはフォルダさえ変えればいくらでも入れられるようなので
日本語と英語版の両方を入れてます。
workspaceも分けてます。

さてIDEを立ち上げるとコンソールに下記のメッセージ(赤字)が。

Eclipse is running in a JRE, but a JDK is required
  Some Maven plugins may not work when importing projects or updating source folders.

おまけにEclipseMavenの設定をするときにも警告が。
JDKeclipse.iniにvmオプションつけて指定する事と
インストール済みJREに登録しろ見たいなメッセージがでてました。


上記のメッセージでちょっとググればすぐ検索結果が一杯出てきます。
おまけに公式サイトにもiniファイルの書式が載ってるし。
というわけで先にインストール済みのJREとiniファイルに設定しました。


ここからハマりました。
eclipse.iniのvmオプションってどこでもいいわけじゃなかったです。
自分は一番下にかいておけばいいやって思って書いたのですがエラーが消えません。
結局、vmargsオプションより先に書かないといけなかったという事です。


EclipseのHELPを見るとvmragsオプションは
一番最後に書きなさいって書いてありました。
これ以降はvmに渡す引数だからとか、なんとか。
それが分からずにずっとあれこれ悩んでしまいました。
iniファイルの書式が載ってるページ、
メッセージを調査するのにググッたページのどれもがvmargsオプションの前に
vmオプションを書いてました。
あとvmオプションを指定する時は改行を入れた方がいいらしいです。
いくつかのサイトをみてもそのようにしています。(公式ページも含めて)

とりあえず、ドキュメントがあるならしっかり読んで設定しましょう。
早とちりをすると、無駄に時間を使います。

StrutsとFreemarkerの連携

さて、今回も公式のサンプルを元にとりあえず書いてみました。
web.xmlに書く内容はServletにFreemarkerを使うに書かれてます。
jspを/WEB-INF/jspと置くことが多かったので、
TemplatePathを「/WEB-INF/template」に修正しました。
ここがルートになるようなので、
/WebContent/WEB-INF/template/test.ftlにブラウザからアクセスするアドレスは
http://localhost:8080/(コンテキスト名)/test.ftl でした。


とりあえず、struts-config.xmlはこんな感じ。

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE struts-config PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
    "http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
  <form-beans>
    <form-bean name="TestForm" type="sample.TestForm" />
  </form-beans>
  
  <action-mappings>
    <action path="/query" type="sample.TestAction"
        name="TestForm" scope="request">
      <forward name="success" path="/test2.ftl" />
    </action>
  </action-mappings>
  <message-resources parameter="ApplicationResource"></message-resources>
</struts-config>



ActionとFormのソースはこんな感じ。
importやaccessorは省略してます。

public class TestAction extends Action {
    @Override
    public ActionForward execute(
            ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        return mapping.findForward("success");
    }
}
public class TestForm extends ActionForm {
    private static final long serialVersionUID = 1L;
    private String keyword;
    private String exclude;

    //以下 accessor
}



Freemarkerのテンプレートはこんな感じ。サンプルと同じです。
メッセージがあるので、ApplicationResource.propertiesにキーワードを書いておきます。
・test.ftl

<#assign html=JspTaglibs["http://struts.apache.org/tags-html"]>
<#assign bean=JspTaglibs["http://struts.apache.org/tags-bean"]>

<html>
  <body>
    <h1><@bean.message key="welcome"/></h1>
    <@html.errors/>
    <@html.form action="/query" method="POST">
      Keyword: <@html.text property="keyword"/><BR />
      Exclude: <@html.text property="exclude"/><BR />
      <@html.submit value="Send"/>
    </@html.form>
  </body>
</html>



POSTしたデータを受け取る。
・test2.ftl

<#assign html=JspTaglibs["http://struts.apache.org/tags-html"]>
<#assign bean=JspTaglibs["http://struts.apache.org/tags-bean"]>

<html>
<body>
  <H1>
    <@bean.message key="greeting" /><BR />
    キーワード:<@bean.write name="TestForm" property="keyword" /><BR />
    除外:<@bean.write name="TestForm" property="exclude" />
  </H1>
</body>
</html>



とりあえず使ってみた感想はそんなに違和感を感じなかったです。
JSPの時と同じようにカスタムタグの定義も多少書き方がちがうだけです。
呼び出し方も@とドットを利用すれば呼べました。
JSPとの比較も公式サイトに書いてあります。
最初、普通の呼び出しと同じだと思ってbean:writeという感じでコロンを使ってました。
もちろん、動かしたらエラーで落ちてましたけどね。


次はFormにListがあったり、beanがあった場合にどういう呼び出しができるか。
それとFreemarkerでどんなことが出来るか、もう少しドキュメントを読んでみようと思います。

とりあえず書いてみた

前回、週末に試してみようとか書いていたんですけどね。
土曜日に親知らずを抜いたところ
熱、頭痛、熱という感じで体調を崩していて、プログラムどころではなかったです。
前の抜歯の時はこんなこと無かったんですけどね。
昨日あたりは熱も微熱程度だったのですが様子をみました。
日中の仕事時間はすこぶる元気でした。
お薬がきいているからかな。


さてそんな言い訳みたいな事ばかり書いててもしょうがないので、
とりあえずFreeMarkerのサイトにあるサンプルを書いて動きをみました。
ソース見れば分かるんでしょうけど、
自分はそんなに頭よくないので、とにかくサンプルを書いていじってみます。


まず環境作りから。
jarファイルをダウンロード
tar.gzを解凍するとfreemarker.jarがみつかるので、
EclipseJava Projectとlibフォルダつくってjarファイル投げ込んで、Build Path追加〜。
Eclipse用のEditorとかPluginがあるようだけど、
サンプルちょっといじるだけなので今回は利用しません。


テンプレートファイル(test.ftl

<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <h1>Welcome ${user}!</h1>
  <p>${hatena.name}:<a href="${hatena.url}">こちら</a>!
</body>
</html>



出力結果

<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <h1>Welcome kzk-y!</h1>
  <p>kzk-y's Dairy:<a href="http://d.hatena.ne.jp/kzk-y/">こちら</a>!
</body>
</html>

とりあえずアプリケーションで動かすことは出来ました。
分かったことは、データ部分はMapで定義してHashMapで実体つくればよさそう。
もっとしっかりドキュメント読まないといけなさそうだ。
それにプログラムも書かないと。まあ続きは明日以降にしよう。


次はWebアプリケーションとしてstrutsと連携させるようにしてみよう。
それから、どの辺がいいか、わるいかなど考えてみようかな。

今度の開発で、テンプレートエンジンを使うそうです。
FreeMarkerです。


正直使い方さっぱりわかりません。
週末サンプル拾って感じがつかめたらな〜。
今度、書いてみた感想を載せてみようと思います。

次の仕事は

次の仕事はStruts+Spring+iBATISといった組み合わせらしい。


いまは基本設計をやっています。
SpringとかiBATISとかやったこと無いので、ちょっと調べてみました。
iBATISは簡単そうだった。


とりあえず詳細設計を始めるまでもう少し時間があるので
もっとパターンとかいろいろ本などをみて情報を集めておかなければ。

変換を行ってみる

S2Dxoを利用してEntityをPageに変換してみる。
テストは4パターン

  1. SourcePrefixのみ
  2. DestPrefixのみ
  3. SourcePrefix&ConversionRule
  4. DestPrefix&ConversionRule

1と2はS2Dxo#プレフィックス付きのプロパティに載っています。
3と4はプレフィックス付きのプロパティと変換元プロパティ名の指定を合わせています。


ソースは以下の感じ。setter/getterは省略
3のEntityとPage

public class Test3Entity {
	private String sourceData1;
	private String sourceData2;
}

public class Test3Page {
	private String testData1;
	private String data2;
}

4のEntityとPage

public class Test4Entity {
	private String sourceData1;
	private String data2;
}

public class Test4Page {
	private String destData1;
	private String destData2;
}

で、変換するDxoはこんな感じ。

public interface TestDxo {
	// SourcePrefixテスト用
	@SourcePrefix("source")
	Test1Page convertTest1(Test1Entity entity);
	// DestPrefixテスト用
	@DestPrefix("dest")
	Test2Page convertTest2(Test2Entity entity);
	// SourcePrefix + ConversionRuleテスト用
	@SourcePrefix("source")
	@ConversionRule("sourceTestData1:sourceData1")
	Test3Page convertTest3(Test3Entity entity);
	// DestPrefix + ConversionRuleテスト用
	@DestPrefix("dest")
	@ConversionRule("data1:sourceData1")
	Test4Page convertTest4(Test4Entity entity);
}

で、Mainはこんな感じ。

public class TestMain {

	public static void main(String[] args) {
		// S2Conteinerの取得
		SingletonS2ContainerFactory.setConfigPath("examples/app.dicon");
		SingletonS2ContainerFactory.init();
		S2Container container = SingletonS2ContainerFactory.getContainer();

		// Dxoの作成
		TestDxo dxo = (TestDxo) container.getComponent(TestDxo.class);

		// Test1
		Test1Entity entity1 = new Test1Entity();
		entity1.setSourceData1("entity1_source1");
		entity1.setSourceData2("entity1_source2");
		Test1Page page1 = dxo.convertTest1(entity1);
		print("Test1", page1);
        
		// Test2
		Test2Entity entity2 = new Test2Entity();
		entity2.setData1("entity2_data1");
		entity2.setData2("entity2_data2");
		Test2Page page2 = dxo.convertTest2(entity2);
		print("Test2", page2);
        
		// Test3
		Test3Entity entity3 = new Test3Entity();
		entity3.setSourceData1("entity3_source1");
		entity3.setSourceData2("entity3_source2");
		Test3Page page3 = dxo.convertTest3(entity3);
		print("Test3", page3);
        
		// Test4
		Test4Entity entity4 = new Test4Entity();
		entity4.setSourceData1("entity4_source1");
		entity4.setData2("entity4_data2");
		Test4Page page4 = dxo.convertTest4(entity4);
		print("Test4", page4);
	}

	private static void print(String name, Object obj) {
		System.out.println("****************************************");
		System.out.println("(" + name + ") " + obj.toString());
	}
}

結果はこんな感じ。

****************************************
(Test1) data1 : entity1_source1, data2 : entity1_source2
(Test2) destData1 : entity2_data1, destData2 : entity2_data2
(Test3) testData1 : entity3_source1, data2 : entity3_source2
(Test4) destData1 : entity4_source1, destData2 : entity4_data2
****************************************

最初、TestDxo#convertTest3で、

@ConversionRule("testData1:sourceData1")

としたところtestData1はnullになりました。
結果からみると3の場合は対象のプロパティをConversionRuleで変換をした後、SourcePrefixの値をEntityのプロパティから削除してPageのプロパティにセットしているみたい。
だから4の場合は問題なくPageのプロパティにセットできた。
sourceData1→data1に置き換えて、data1にdestを追加してdestData1になる。
イメージはこんな感じだと思う。
ソースをみれば詳しく分かるのだろうけど。


注意点はConversionRuleとSourcePrefix(DestPrefix)を同時に利用する時はConversionRuleが先に実行される。