JSPでファイルアップロード

ファイルアップロードでハマった。

javaのweb開発でクライアントPCからファイルをサーバに送信して解析する仕組みを作りたかった。
ServletJakarta Commons FileUploadが一般的らしいがどうしても失敗する。
そもそもサーバにファイルを保存する必要はないのでFile f = form.getFile() みたいなので十分。
[jsp]

<html:file property="uploadFile" styleId="uploadFile"/>

[form.java]

import org.apache.struts.upload.FormFile;
...

private FormFile uploadFile;

public FormFile getUploadFile() {
     return uploadFile;
}
public void setUploadFile(FormFile uploadFile) {
     this.uploadFile = uploadFile;
}

[actionlogic.java]

InputStream is = form.getUploadFile().getInputStream();

StrutsにFormFileというクラスがあったので楽にできた。

CASE文で呼び出される度にフラグを切り替えるSQL

割と便利。

UPDATE hoge_table
  SET 
    hoge_flag = 
      CASE WHEN (SELECT hoge_flag FROM hoge_table WHERE hoge_no = '001') = '1' --フラグが'1'なら'0'に切り替え
	   THEN '0'
           WHEN (SELECT hoge_flag FROM hoge_table WHERE hoge_no = '001') = '0' --フラグが'0'なら'1'に切り替え
	   THEN '1' 
      END
      WHERE
      hoge_no = '001'

NOT演算を条件分岐で表現する際の方法

ある処理をしたい時にNOT演算子(!)を使いたい場面は多いと思う。
例えば

if(!"str".equals(str)){
  //処理
}

String strが"str"でなければtrueになるわけですが、他人のコードを見ていると

if("str".equals(str)){
  //処理なし
} else {
  //処理
}

という処理をよく見る。
厳密な動作確認をしているわけでな無いので前者、後者で結果に差異があるのかは分からないが、コードを読む上では少し差が出てくる。
前者はコードがすっきりしているがNOT演算子が「!」で見落としやすい。
後者は何をやりたいのかが明確だが、ifでtrueになった場合に処理なしという一見無駄なコードが発生する。

個人的な好みは後者。
なんとなくだが前者は一つの条件分岐に詰め込みすぎてわかりづらい。
条件分岐一つ一つはできるだけシンプルに書くのがいいと思う。

updateをjoinぽく実行

テーブル設計の変更で2つのテーブルを一つに結合することにした。
VIEWでもいいけど可読性が下がるからやめた。
片方のテーブルにカラムを追加してそこに片方のテーブルデータを流し込むことに。
JOINで結合してどうにかこうにかやるのかと考えてたけど、調べてみたらもっと簡単だった。

UPDATE hoge
  SET 
    zipcd = hoge2.zipcd,
    address = hoge2.address,
    phoneno = hoge2.phoneno,
    name = hoge2.name,
    birthday = hoge2.birthday
    FROM hoge2
    WHERE hoge1.kanriNo = hoge2.kanriNo

泥沼になるその前に

プログラミングにおいて、ある問題を解決するのどんな手段が最適かを考えなければいけない場面はよくある。
というか毎日。

中にはたいした事でないのに一筋縄では行かない問題もあったりする。
まだまだ経験の少ない自分は大体、問題を解決するのに余計なコードを書き、問題を「回避」しようとする。
そういうことをすると大体の場合、泥沼にハマる。
SQLのクエリ回数を減らすのに処理方法を変えていたら、いくつのもプログラムファイルを書き換えないといけなくなってしまったり。
出力ファイルを文字コードを変換しようとしたら使用しているクラスでは出来なくて、根こそぎ書き換えなくてはいけなかったり。(実は出来た...)


少ない開発の日々を振り返ってみるとほとんどすべての問題はシンプルな解決手段が用意されていた。
しかも問題の「回避」ではなく「解決」で。
それは自分の曖昧な理解と、調べ不足が原因で泥沼化していたし、行き詰まって「あれ、何を解決したかったんだっけ?」
って思い直して始めに戻って、少し調べてドキュメントを眺めてみたら解決手段が見つかる。

熟練者は勘どころというか、泥沼化するある種の「匂い」が分かって、その辺の勘が鋭いんだろうなと思う。

SQLでNULLの条件文

whereを使用する際、NULLではない行を条件にするのに

hoge <> ''

を使用していた。
しかし、NULLの行を条件にする場合

hoge = ''

hoge = null

はうまく動作しない(エラーにならず結果0件)

正解は

hoge is null

だった。

hoge <> ''

hoge is not null

のがおしゃれですね。

Tomcat起動時、自動で処理を実行する

バッチ処理のようなことをしたくなることは、ままあると思います。
方法はJavaにかぎらず色々ありますが、アプリケーションサーバで処理したファイルをゴニョゴニョしたくなったのでシステムに組み込むことにした。

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class HogerTest implements ServletContextListener {

	public void contextInitialized(ServletContextEvent event) {
		//Tomcat起動時処理
	}

	public void contextDestroyed(ServletContextEvent event) {
		//Tomcatシャットダウン時処理
	}
}

処理のなかみを書いてweb.xml

<listener>  
    <listener-class>com.hoge.HogerTest</listener-class>  
</listener>

と記述