かずきのBlog

C#やJavaやRubyとメモ書き

目次

Blog 利用状況

ニュース

わんくまBlogが不安定になったため、前に書いてたはてなダイアリーにメインを移動します。
かずきのBlog@Hatena
技術的なネタは、こちらにも、はてなへのリンクという形で掲載しますが、雑多ネタははてなダイアリーだけに掲載することが多いと思います。
コメント
プログラマ的自己紹介
お気に入りのツール/IDE
プロフィール
経歴
広告
アクセサリ

書庫

日記カテゴリ

[Java][Silverlight][NetBeans]Web(Java) + Silverlight2

NetBeansも6.5の正式版が出て、Silverlight2も正式版が出たばっかりということなので両方使って簡単なものを作ってみようと思う。
Silverlight2を使うので、クライアント側はSilverlight2を使わなければならない。
なので、サーバーはJavaでWebサービスを作るようにしてみる。

NetBeans側

作るWebサービスは、NetBeansに付属してくるサンプルデータベースの中にあるCUSTOMERテーブルの中身を返すものにしてみる。
image

とりあえずNetBeansでWebアプリケーションを新規作成する。とりあえず、フレームワークを何も選択しないで素のWebアプリケーションにしてみた。

プロジェクトを作ったらソースパッケージに適当なパッケージ(自分の作ったプログラムではcom.wankuma.kazukiにした)を作ってそこにWebサービスを新規作成する。
image

新規にサービスを作ると、下のようなエラーが起きる。
image

クイックフィックスでとりあえずオペレーションを1つ追加する。名前はgetCustomersにした。
とりあえず、戻り値はStringにしておく。

/**
 *
 * @author Kazuki
 */
@WebService()
public class CustomerService {

    /**
     * Web service operation
     */
    @WebMethod(operationName = "getCustomers")
    public String getCustomers() {
        //TODO 実装コードをここに記述します:
        return null;
    }

}

次に、Customerのデータをとってくるためのクラスを作る。
ここはJPAでやろうと思う。新規作成で、データベースからのエンティティークラスを使いCustomerテーブルのエンティティを作成する。
Customerテーブルのエンティティを作ると関連があるのかDiscountCodeクラスも作られる。
image

DBアクセスの処理を書く前に、Java DB ドライバをライブラリから追加しておく。
そうして、CustomerServiceに以下のようなコードを書く。要は全件とってくるだけ。

@WebService()
public class CustomerService {

    @PersistenceContext
    private EntityManager em;
    /**
     * Web service operation
     */
    @WebMethod(operationName = "getCustomers")
    public CustomerResult[] getCustomers() {
        // DBからデータ取得
        List<Customer> customers = (List<Customer>) em.createQuery("select c from Customer c").getResultList();

        // 戻り値用のリストを作る
        List<CustomerResult> results = new ArrayList<CustomerResult>();
        for (Customer c : customers) {
            // 詰め替え
            CustomerResult result = new CustomerResult();
            result.setCustomerId(c.getCustomerId());
            result.setName(c.getName());
            result.setEmail(c.getEmail());
            results.add(result);
        }
        // 配列にして戻す
        return results.toArray(new CustomerResult[results.size()]);
    }

}

CustomerResultクラスはcustomerIdプロパティとnameプロパティとemailプロパティの3つを持っただけのシンプルなクラスです。もちろんSerializableを実装する形で作る。

これで基本的に完成。Webサービスをテストからテストも可能になってる。
image

テスト画面は下のような感じになる。
image

ボタンを押すことで実行結果の確認も出来る。いい感じ。

Silverlight2側

SilverlightJavaという名前でSilverlightアプリケーションを作成する。
まずは、サービス参照を追加する。追加するのはもちろんJavaで作ったサービス。

JavaのサービスのWSDLへのURLを指定すると普通にサービス参照に追加される。
名前をつけるのがめんどくさかったので、とりあえずServiceReference1という名前で参照した。

Page.xaml.csでは、Webサービスを単純に呼び出して結果をDataContextに入れているだけのシンプル実装。

public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        // 処理を呼び出し
        var client = new ServiceReference1.CustomerServiceClient();
        client.getCustomersCompleted += new EventHandler<SilverlightJava.ServiceReference1.getCustomersCompletedEventArgs>(client_getCustomersCompleted);
        client.getCustomersAsync(client);
    }

    void client_getCustomersCompleted(object sender, SilverlightJava.ServiceReference1.getCustomersCompletedEventArgs e)
    {
        // 実行結果をDataContextへ
        DataContext = e.Result;
    }
}

後はXAMLで見た目を整えれば大丈夫。今回はDataGridに単純に表示するだけにした。

<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="SilverlightJava.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300" Loaded="UserControl_Loaded">
    <Grid x:Name="LayoutRoot" Background="White">
        <data:DataGrid x:Name="dataGrid" ItemsSource="{Binding}" />
    </Grid>
</UserControl>

これでSilverlight側もおしまい。

仕上げ

これでWebサービスとSiliverlight2の両方を実行してもエラーが出てしまう。
これは、WebサービスとSilverlightをホストしてるサーバーのドメインが違うからおきてしまうらしい。

まぁSilverlightからWebサービスが呼び放題とかどうよ?って感じになるからね。

これを、呼び出せるようにするにはWebサービス側にclientaccesspolicy.xmlという名前のファイルを置いてやる必要がある。置く場所は、Webサービスのある側のルートに置くらしい。つまり、http://ドメイン/clientaccesspolicy.xmlでアクセスできないといけない。

実際には、何処に何をアクセスさせるか決めないといけないけど、とりあえずは全アクセス許可で作った。

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

これをGlassFishのpersonalDomain/docrootに置いて実行する。
今度は無事実行される。
image

いい感じ。

投稿日時 : 2008年11月21日 1:11

Feedback

# NYglMPqudJy 2011/12/22 20:38 http://www.discreetpharmacist.com/

8dD7Fd Right from this article begin to read this blog. Plus a subscriber:D

タイトル
名前
Url
コメント