入力補完サンプル

最近勉強していないので、もうほとんどの方はやったことあるでしょうが、お勉強のために…
入力補完」テキストボックスで候補入れると、リストがでるあれです。プラグインも山ほどありましたが、せっかくなので、自分でやりたいので…
とはいっても、「jquery.autocomplete」は仕様の参考にしました。
http://jquery.bassistance.de/autocomplete/demo/


まずは、洗い出し。

  • テキストボックス(現段階では、テキストエリアは考慮しない)に文字を打ち込むまたは、文字を削除すると候補リストが表示される。
  • 対象のテキストボックスまたは、候補が表示されているエリアからフォーカスをはずすと、リスト非表示。
  • 候補リストは↓↑キー+Enterキーまたは、マウスにより選択可能。
  • 候補リストは、当然スクロール考慮↓↑キーにより選択されている候補が隠れたら、スクロールする。
  • データの受け渡しは、Ajax + Json。(まあ、ここはイメージがわきやすいので、後回しにして、とりあえず、変数にリテラルで保持)
  • 最終的には、プラグイン化したい。(テキストボックスとdivだけユーザに作成してもらって、クラスを指定すると、あら、不思議みたいにしようかな…まだわからないけど…)
  1. テキストボックス(現段階では、テキストエリアは考慮しない)に文字を打ち込むまたは、文字を削除すると候補リストが表示される。

$("テキストボックスのセレクター").bind('keypress change',function(event){
});

SQLページング

久しぶりに自分のメモ書き程度に書いときます。
検索結果表示画面をあまりこって作ってこなかったので特に必要なかったが自分のために勉強しました。


select filter.*
from
(
select
rownum seqno
, main.*
from (

-- メインロジック(ページングを意識せず、まんまのSQLを記述)
select * from ir
where
mt_nm = 'XXXX'
and ctt_nm = 'YYYY'
order by ir_no

) main
) filter
where
filter.seqno > 10 and filter.seqno <= 10 + 10
こんな感じでしょうか?メインロジック以外はほぼ定型文ですね。
後は、どのページを切り取るかは、範囲指定でもってやるイメージですかね…
パフォーマンスとか何か問題あれば改めて…

http://oracle.se-free.com/dml/03_rownum.html


さっそくCyokodogさんにコメントいただきました。ありがとうございます。
無駄な階層があるということでさっそく手直し…

手直しいただいたのSQLの場合(下記)


-- メインロジックにrownum追加
select rownum seqno, ir.* from ir
where
mt_nm = 'XXXX'
and ctt_nm = 'YYYY'
order by ir_no

結果はメインロジックのソート順とrownumが一致しません。


seqno | main.ir_no
3 | 00001
2 | 00011
1 | 00021
4 | 00031
5 | 00051
結果から判断するに、rownumはソートする前の結果に対しての振られることがわかりました。

最初のSQLの場合


select
rownum seqno
, main.*
from (
-- メインロジック(ページングを意識せず、まんまのSQLを記述)
select * from ir
where
mt_nm = 'XXXX'
and ctt_nm = 'YYYY'
order by ir_no
) main

結果はメインロジックのソート順とrownumが一致します。


seqno | main.ir_no
1 | 00001
2 | 00011
3 | 00021
4 | 00031
5 | 00051
結果から判断するに、rownumはソートする前の結果に対しての番号なので
(しつこい?w)
外側でrownumを発番すれば、ソート後の結果に対して順番通り
になるというわけでした。

とここまで書いて、改めて考察
「rownumが順番通り並んでいてなんか得すんの?」
ってこと、rownumでソートやページング以外の条件に使用するならともかく
表だってrownumは使わない(ページング以外では)
じゃあ、階層深くしてまで、する必要ないやってことで
コメントいただいたものがやはり間違いなかったってことでした。
ありがとうございます。!!



select
, main.*
from (

-- rownum + メインロジック
select rownum seqno ir.* from ir
where
mt_nm = 'XXXX'
and ctt_nm = 'YYYY'
order by ir_no

) main
seqno > 10 and seqno <= 10 + 10

アップロードされたファイル達を別サーバーに保管する-2

お久しぶりです。

表題の件で、突き詰めると、Appサーバーに可変に増えるリソースを保存
するのは、Webの考え方としてあっているのか?
といったところに行き着くような気がします。

私は、Appサーバーに保存するのは、正しくないような気がするのですが・・・
データも、通常、Appサーバーと、DBサーバーと分けますよね?

いかがか?

アップロードされたファイル達を別サーバーに保管する

久しぶりに執筆意欲がわいたのでつれづれなるままに・・・

今日は、汎用的な処理を行うサーバー(以降汎用サーバー)、また、アップロードされたファイルを保存し、また参照できるサービスを提供するサーバー(以降汎用サーバー)をたてて別のAPPサーバーから利用できるようにするための方法を検討する。

  1. 汎用的な処理
    • ライセンスが必要なツールを必要とする処理を汎用サーバーでやりたい。
  2. ファイル保存、参照
    • APPサーバーのディスクを圧迫させたくない。

この二つの機能を提供するためには、ほかにも方法があるかもしれないが、今回はJAVAベースで考える。
いろいろ調べて、RMIですすめていくことにした。

これからサンプルを作成していこうと思います。
どうせなら、せっかくTeeda勉強したので、「S2RMI」使ってみようかな・・・

今日はここまで
だれかにコメントしてほしい・・・(笑)
ありがとうございました。

Teedaおさわり

ども、toshinonoです。
はじめて日記を書くのですがちょっと緊張しますな〜

まずは、Teedaについて。
Teedaについてのブログはいろんなところで目にしますが
今回は、自動ログイン画面遷移機能を実装してみました。

いろんなところで目にするのは、システム内の画面にログイン画面を介さず
アクセスされた場合、ログイン認証させてその画面に戻るといった処理ですが
クエリストリングを考慮されたものを見たことなかったので作ってみました。

http://localhost:8080/session-app/view/dept/deptEdit.html?crudType=2&id=1&versionNo=1
赤色のところも考慮したわけです。

A画面(クエリストリング付)

インタセプタ
 ・ログイン情報がなかったら、ログイン画面に遷移
 ・A画面URL+クエリストリングをセッション情報に保持

ログイン画面
 ・ログイン認証
 ・ログイン情報をセッションに保持
 ・呼び出し元画面(この場合、A画面ね)情報があればそこにGetで送信
 ・なければ、最初にログイン画面がよばれたということで、通常通りメニュー画面に遷移

メニュー画面 or 呼び出し元画面(この場合、A画面ね)

ここまで
 
環境
Teeda Extenshon-1.3.13-sp4
JDK 1.5.0.11
Tomcat5.5.27

  • app.dicon










カスタマイザを追加

  • customizer.dicon

pageCustomizerにloginInterceptorを追加






"loginInterceptor"

"prerender"



↓ログインページクラスはインターセプタ対象外という意味↓

"app.session.web.login"
".*Page"

  • LoginInterceptor.java

ここでの肝は、sessionDtoにユーザ情報と、どの画面からログイン画面がよびだされたかのnextPageにURL+クエリストリングを保持すること!!


package example.interceptor;

import javax.servlet.http.HttpServletRequest;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import org.seasar.framework.aop.interceptors.AbstractInterceptor;
import example.dto.SessionDto;

public class LoginInterceptor extends AbstractInterceptor{

private static final long serialVersionUID = 1L;

public SessionDto sessionDto;

public HttpServletRequest httpServletRequest;

Logger logger = Logger.getLogger(this.getClass());

public Object invoke(MethodInvocation methodInvocation) throws Throwable {

//URLを取得
String url = httpServletRequest.getRequestURL().toString();
//URLのクエリストリング(引数)を取得
String queryString = httpServletRequest.getQueryString();

// ログイン情報がない場合、ログイン画面に遷移
if (StringHelper.isEmpty(sessionDto.userInfoDto.loginId)) {
sessionDto.nextPage = StringHelper.isEmpty(queryString) ? url : url + "?" + queryString;

return "login_login";
}
logger.debug("遷移先 = " + sessionDto.nextPage);

return methodInvocation.proceed();
}
}

  • SessionDto

セッションDtoにはアノテーションで、こいつはセッションスコープだぞと宣言


package example.dto;

import java.io.Serializable;
import org.seasar.framework.container.annotation.tiger.Component;
import org.seasar.framework.container.annotation.tiger.InstanceType;

@Component(instance=InstanceType.SESSION)
public class SessionDto implements Serializable{

private static final long serialVersionUID = 1L;

public String nextPage;

public UserInfoDto userInfoDto;

}

  • UserInfoDto


package example.dto;

import java.io.Serializable;
import java.util.Date;

public class UserInfoDto implements Serializable{

private static final long serialVersionUID = 1L;

public String loginId;

public String password;

public String mailAddress;

public Integer kengen;

public Date torokuDate;
}

  • LoginPage


public String doLogin() throws IOException {
String nextPage = null;

//ログイン認証失敗
if(!userInfoDao.checkLogin(loginId, password)){
Object[] args = {"loginId", "password"};
FacesMessageUtil.addErrorMessage("E0000002", args);
}
else{
//セッション情報に追加
sessionDto.userInfoDto = userInfoDxo.convert(userInfoDao.selectById(loginId));
nextPage = sessionDto.nextPage;

//直接ログイン画面がよばれた場合、メニュー画面に飛ぶ
if(nextPage == null || "".equals(nextPage)){
nextPage = "menu_menu";
}
else{
//ここが肝!!
//下記2行なしの場合、returnで指定されているnextPageに遷移するが
//クエリストリング付のURLでRedirectする場合に使用する。
httpServletResponse.sendRedirect(nextPage);
facesContext.responseComplete();
}
}

return nextPage;
}

  • あとがき

おっしゃ、動いた〜〜ってことで
いや〜何がはまったかって、通常、TeedaのPageクラス内のボタン等でsubmitするdoXXXX系の戻り値は、"menu_menu"みたいに記述するのが普通で、じゃあどうやってクエリストリングをバインドするか非常になやんでますた。

したら、よくよくteeda-exampleのサンプル内にredirectがあって
こ、こ、これだーと思い試したらうまくいった次第です。