2011年7月22日金曜日

ZK: Fileアップロードサンプル

ZKForum のこのスレッドで紹介されていたヘルパークラスを使い、アップロードされたファイルをサーバに格納するサンプルです。


簡単な使い方:
--- zul ---
<button id="uploadBtn" label="Upload file" upload="true,maxsize=300"/>

--- java ---
public void onUpload$uploadBtn(UploadEvent event) throws InterruptedException {
org.zkoss.util.media.Media media = event.getMedia();
Medias.saveToFile(media, "/path/to/save");;
}


ソース

ヘルパークラス
--- Medias.java ---
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;

import org.apache.commons.io.IOUtils;
import org.zkoss.util.media.Media;


public class Medias {

public static File saveToFile(Media media, String path) {
try {
File file = new File(path + File.separator + media.getName());
OutputStream output = new FileOutputStream(file);
if (media.isBinary()) {
InputStream input = Medias.asStream(media);
IOUtils.copy(input, output);
input.close();
} else {
Reader input = Medias.asReader(media);
IOUtils.copy(input, output);
input.close();
}
output.close();
return file;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public static String asString(Media media) {
try {
String result = null;
if (media.isBinary()) {
InputStream input = Medias.asStream(media);
result = IOUtils.toString(input);
input.close();
} else {
Reader reader = Medias.asReader(media);
result = IOUtils.toString(reader);
reader.close();
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private static InputStream asStream(Media media) {
return new BufferedInputStream(
media.inMemory() ?
new ByteArrayInputStream(media.getByteData()): media.getStreamData());
}

private static Reader asReader(Media media) {
return new BufferedReader(media.inMemory() ?
new StringReader(media.getStringData()) : media.getReaderData());
}
}





ビュー
--- fileupload.zul ----
<?page title="ファイルアップロード" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="ファイルアップロード" border="normal" apply="sample.ctrl.UploadCtrl ">
<button id="uploadBtn" label="Upload file" upload="true,maxsize=300" />
<separator />
<image id="img" />
<separator />
<label id="msgLbl" />

</window>
</zk>




コントローラ
--- FileUploadCtrl.java ---
public class FileUploadCtrl extends GenericForwardComposer {
private Label msgLbl;
private Image img;

public void onUpload$uploadBtn(UploadEvent event) throws InterruptedException {
msgLbl.setValue("");
org.zkoss.util.media.Media media = event.getMedia();

if(media == null){
msgLbl.setValue("ファイルを選択してください。");
return;
}

if (media instanceof org.zkoss.image.Image) {
org.zkoss.zul.Image image = new org.zkoss.zul.Image();
image.setContent((org.zkoss.image.Image)media);
image.setParent(img);
}

Medias.saveToFile(media, "/path/to/save");;
}
}

2011年7月16日土曜日

ZK: コミュニティ・エディションで Captchaを使う

ZK コミュニティ・エディション(CE)では残念ながらCaptchaコンポーネントを利用することができません。
しかし SimpleCaptcha を用いることで、CEでも Captchaを簡単に利用することができる方法が ZKforum で紹介されていたのでまとめてみました。

元ネタ

  • SimpleCaptcha サイトからsimplecaptcha.jarをダウンロードし WEB-INF/libへ配備する。

  • CaptchaUtils クラスを作成する。

    import nl.captcha.Captcha;
    import nl.captcha.backgrounds.GradiatedBackgroundProducer;
    import nl.captcha.text.renderer.ColoredEdgesWordRenderer;

    /**
    * CAPTCHAを作成するユーティリティクラス <br>
    * Captchaは直接 org.zkoss.zul.Imageにロード可能 <br>
    *
    * <pre>
    * Image img = new org.zkoss.zul.Image();
    * img.setContent(CaptchaUtils.getCaptcha());
    *
    * String verifyStr = captcha.getAnswer();
    * </pre>
    *
    * @author Stephan Gerth
    */
    public class CaptchaUtils
    public CaptchaUtils(){
    }

    /**
    * 5桁のキャプチャを作成する
    */
    public static Captcha getCaptcha() {

    Captcha captcha = new Captcha.Builder(140, 50)
    .addText(new ColoredEdgesWordRenderer()).addNoise()
    .addBackground(new GradiatedBackgroundProducer())
    .addBorder()
    .build();

    return captcha;
    }
    }



  • コントローラ クラスを作成する。

    public class CaptchaCtrl extends GenericForwardComposer {
    private static final long serialVersionUID = -804655396850565215L;
    private Image img_captcha;
    private Textbox txt_captcha;
    private Captcha captcha;


    public void onCreate$win(Event event){
    doReCaptcha();
    }

    public void onClick$btn1(Event event){
    if (txt_captcha.getValue().equals(captcha.getAnswer())){
    alert("正しいキャプチャです。");
    } else {
    alert("間違っています!!");
    }
    }

    public void onClick$btn2(Event event){
    doReCaptcha();
    }

    /**
    * キャプチャを再表示する<br>
    *
    */
    private void doReCaptcha() {
    captcha = CaptchaUtils.getCaptcha();
    img_captcha.setContent(captcha.getImage());
    }
    }


  • ZULを作成する。

    <window id="win" border="normal" width="350px"
    title="コミュニティ・エディションでもキャプチャが使えます" apply="ctrl.CaptchaCtrl" >
    <vlayout id="input" width="100%" >
    <hbox>
    <image id="img_captcha" />
    <button label="再表示" id="btn2"/>
    </hbox>
    キャプチャを入力してください。
    <textbox id="txt_captcha" hflex="1" width="250px"/>
    <button label="確認" id="btn1"/>
    </vlayout>
    </window>