Loading [MathJax]/extensions/tex2jax.js

2010-02-27

GWT+GAEでのファイルアップロード処理

とりあえず試してみたのでメモ書きです。本番環境で試してないのですが、たぶんおっけい?


クライアント側
下記のサンプルは、GWTのAPI仕様書(JavaDoc)に書かれている内容を参考にしてます。FileUploadウィジェットを用います。Formパネルの子としておかないとダメなのに注意。FileUploadウィジェットを用いれば、ファイルの選択などのGUIが用意されます。
public void onModuleLoad() {
// フォームパネルを宣言.これを使わないとダメです。
final FormPanel form = new FormPanel();
//どのURLへ飛ばすのか指定
form.setAction("/FileUploadServ");
// POSTの利用とmultipart MIME encodingであることを指定.
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
VerticalPanel panel = new VerticalPanel();
form.setWidget(panel);
// FileUploadウィジェットを宣言
FileUpload upload = new FileUpload();
upload.setName("uploadFormElement");
panel.add(upload);
// Add a 'submit' button.
panel.add(new Button("Submit", new ClickHandler() {
public void onClick(ClickEvent event) {
form.submit();
}
}));
// Add an event handler to the form.
form.addSubmitHandler(new FormPanel.SubmitHandler() {
public void onSubmit(SubmitEvent event) {
// This event is fired just before the form is submitted. We can take
// this opportunity to perform validation.
//<ここでは未使用>
}
});
form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
public void onSubmitComplete(SubmitCompleteEvent event) {
// When the form submission is successfully completed, this event is
// fired. Assuming the service returned a response of type text/html,
// we can get the result text here (see the FormPanel documentation for
// further explanation).
//<ここでは未使用>
}
});
RootPanel.get().add(form);
}
サーバー側

下記の例では、純粋なサーブレットですが、GAEでも動かすことを前提にしてます(本番環境では試してませんが)。ポイントは、FileItemStreamからInputStreamを生成しているところでしょうか。これで、ファイルタイプに応じていろんな対応ができるはずです。
なお、Apache のCommons FileUploadライブラリを仕様してます。
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, AuthenticationException, ServiceException {
try {
ServletFileUpload fileUpload = new ServletFileUpload();
FileItemIterator itemIterator = fileUpload.getItemIterator(request);
while (itemIterator.hasNext()) {
FileItemStream itemStream = itemIterator.next();
//ファイルタイプを調べる
String contentType =itemStream.getContentType();
InputStream inputStream = itemStream.openStream();
if(contentType==null){
contentType="";
}
else if(contentType.contains("image")){
//何かする
}
else if(contentType.contains("text")){
}
else{
}
} catch (FileUploadException e) {
response.sendError(500);
}
}

上記のプログラムでは、アップロード処理が終わった後の処理について書いてませんので、そこは各自で対応をお願いします。

2010-02-25

GooglePicasa APIを試してみた

PicasaのAPIを試してみました。基本的には、Developer's Guide: Java を参考にしてます。

SDKインストールについて
Java Google Data APIs Client Libraryをダウンロードしてパスを通せばいいのですが、不足のライブラリを言われます。
  • Google-Collect
  • JavaMail
の2つを追加ライブラリとしました。前者は、DataAPIClientライブラリの中に入ってますが、JavaMailはなかったですね。

とりあえず試したのは、アルバムと写真のリストの入手です。以下のサンプルで出力している内容自体はあまり意味はありません。どんな情報が出てくるのかは、各自で試してみてください。

アルバムリストの入手 

  1. public void getAlbumList() throws MalformedURLException, IOException, ServiceException {  
  2.  PicasawebService myService = new PicasawebService("example");           
  3.  myService.setUserCredentials("USERID""PASSWD");  
  4.  URL feedUrl = new URL("http://picasaweb.google.com/data/feed/api/user/USERID?kind=album");  
  5.  UserFeed myUserFeed = myService.getFeed(feedUrl, UserFeed.class);  
  6.  for (AlbumEntry myAlbum : myUserFeed.getAlbumEntries()) {  
  7.     System.out.println(myAlbum.getTitle().getPlainText());  
  8.     System.out.println(myAlbum.getId());  
  9.  }  
  10. }  


フォトリストの入手
  1. public void getPhotoList() throws MalformedURLException, IOException, ServiceException {  
  2.         PicasawebService myService = new PicasawebService("example");  
  3.         URL feedUrl = new URL("http://picasaweb.google.com/data/feed/api/user/USERID/albumid/ALUBUMID");  
  4.         myService.setUserCredentials("USERID""PASSWD");  
  5.         AlbumFeed feed = myService.getFeed(feedUrl, AlbumFeed.class);  
  6.         for (PhotoEntry photo : feed.getPhotoEntries()) {  
  7.             System.out.println(photo.getTitle().getPlainText());  
  8.             System.out.println(photo.getHtmlLink().getHref());  
  9.             System.out.println(photo.getId());  
  10.             }  
  11.         }  
  12.     }  


2010-02-23

GAEのデータストアを試してみた

GAEのデータストアについては、サンプルプログラムでは動かしてみたことはあるのだが、開発中のシステムへの利用を前提にちょっと動かしてみた。今日はそのメモ書き。。。。

ローカルでのGAE管理コンソール

http://localhost:8080/_ah/admin
でアクセスできます。データベースの中身も見れます。

データストアのIDについて
IDについてはなんでもいいのではなく、どうやら型に制約があるらしい。
  • Longクラス ← longではなくLongね
  • Stringクラス
  • Keyクラス


IDの自動生成について
いちいちIDをアプリケーション側で生成するのが面倒な場合は、GAEに任せるという手がある。

  1. @PrimaryKey  
  2. @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)  
  3. private Long id;  


参考URL


2010-02-22

GWT2.0のUIBinderを試してみた

2.0からの新機能であるUIBinderについて、試してみました。ネタ元は、本家のサイ トDeclarative Layout with UiBinderです。




ファイル構成
○○○.ui.xml 
ここで ユーザインタフェースの定義をします。Java側で呼び出す際の変数名も指定します。スタイルシートの設定も可能です。
  1. <ui:uibinder xmlns:ui="urn:ui:com.google.gwt.uibinder">  
  2.   
  3.   
  4.   
  5.   
  6.   
  7.   
  8.   
  9. <div>Hello, <span ui:field="nameSpan"></span>.  
  10. </div></ui:uibinder>  

○○○.java
  • UIObject を継承したクラスを宣言します。ui.xmlと同じ名前にしましょう。
  • クラス内でUiBinderを継承したインタフェース (MyUiBinder)を宣言します。
  • MyUiBinderを呼び出し、コンストラクタにてUIBindの初期化をします。
  • @UiField アノテーションにより、上記xmlファイルで定義した要素と変数を関連付けます

  1. public class HelloWorld extends UIObject { // Could extend Widget instead  
  2.   interface MyUiBinder extends UiBinder<divelement, helloworld=""> {}  
  3.   private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);  
  4.   
  5.   @UiField SpanElement nameSpan;  
  6.   
  7.   public HelloWorld() {  
  8.     // createAndBindUi initializes this.nameSpan  
  9.         
  10.     setElement(uiBinder.createAndBindUi(this));  
  11.   }  
  12.   public void setName(String name) { nameSpan.setInnerText(name); }  
  13. }  

わかりにくいのは、UIBinderを継承したインタフェース定義のところでしょうか?このインテフェース定義は、最終的にUiBind処理の初期化に利用 されます。ここで重要なのは、 extends UiBinder<U,O>のところの2つのパラメーターです。

  • U はui.xmlファイルで記述しているエレメントのrootのタイプを記述します。
  • O@UiFields を所有するクラスを記述します。
ui.xmlとJavaのファイルの関連付け
次の 2つの方法があります。

  • ファイル名を同じにする
  • @UiTemplate("ファイル名.ui.xml") と 指定する
後者については、interface定義をするところの直前に記述すればOKです。


MainEntryPoint クラスでの記述

普通にクラスのインスタンスを生成し、Elementとしてappendするという方法になります。
  1. public void onModuleLoad() {  
  2.         HelloWorld helloWorld = new HelloWorld();  
  3.         Document.get().getBody().appendChild(helloWorld.getElement());  
  4.         helloWorld.setName("おちくん");  
  5.        
  6.     }  

ちょっと 触ってみて感想

今のところ、個人的には正直、このUIBinderの利便性についてはいまいち整理できてなく、
  • 全部Javaでゴリゴリ 書きあげることができるGWTが好きだったので、タグを書くことになるのは個人的にはどうも、、、
  • でも、複雑なレイアウトのUIを考え た場合、Javaで書いていくのはちょっと面倒な点はある。その点、UIBinderのやり方は直感的
  • というか雰囲気的に StrutsとかJSFでやってるUIBindの方法と同じ感じか
  • ui.xmlで記述するタグに付いてはちょっと勉強が必要だけど、
  • ス タイルシートの変数も動的に変えられるというのは面白い
  • 使いこなすにはちょっと勉強する必要があるかも。ただ、壁を乗り越えたら開発効 率があがる?
なんて、いろいろ思ったりしてます。まあ、Google様を信用して今後導入していこうかとは思ってます。

2010-02-02

ランダム文字列を生成する

パスワードの初期発行の時に使えるcommonsを利用したランダムな文字列の生成サンプルです。

  1. //commonsを使用  
  2. import org.apache.commons.lang.RandomStringUtils;   
  3. String  string = RandomStringUtils.randomAlphabetic(20); //長さ20