SAStruts/機能別実装パターン/一覧表示セッション

SAStruts/機能別実装パターン/一覧表示セッション

一覧表示

URL

http://hogehogehoge.com/hogePiyoList/?hoge=piyo&so=id-a&pg=3&lm=10

Action

/**
 * HogePiyoを条件に沿って検索し表示する
 */
public class HogePiyoListAction extends BaseAction{
    @ActionForm
    @Resource
    public HogePiyoListForm hogePiyoListForm;
    @Resource
    protected HogePiyoService hogePiyoService;
    public ListDto<HogePiyo> listDto;
    /**
     * 使用できるレポートフォーマットの選択画面
     * @return
     */
    @Execute(validator = false)
    public String index(){
        hogePiyoForm.init();
        listDto = hogePiyoService.findAllByParams(hogePiyoListForm.getIdCond(),
                                                  hogePiyoListForm.getSortOrder(),
                                                  hogePiyoListForm.getPage(),
                                                  hogePiyoListForm.getLimit());
        return "list.jsp";
    }
}

Form

Formは基本的にStringでうけて、それを内部のJavaで使う型や形式へのgetterメソッドを実装する。

一覧共通

一覧の基本的操作をうける

/**
 * 一覧系のパラーメタ受け取る基本
 *
 */
public abstract class ListBaseForm{
    /**
     * ソート対象と昇順降順
     * ex)
     * "id-a" : idで昇順
     * "id-d" : idで降順
     * "name-d" : 名前で降順
     */
    public String so;
    /** 現在ページ 数値的文字列で1スタート */
    public String pg;
    /** 1ページのレコード数 数値的文字列 */
    public String lm;
    /**
     * デフォルトの検索か否か
     * y or empty : default
     * n : パラメータ無しの検索と解釈
     */
    public String df;
    public boolean isDefault(){
        return !"n".equals(this.df);
    }
 
    /** 昇順降順 */
    public enum ASC_DESC{
        ASC(1, "asc", "a"),
        DESC(2, "desc", "d");
        public int v;public String n; String abbr;
        public static Map<Integer, ASC_DESC> valueMap = new HashMap<Integer, ASC_DESC>();
        public static Map<String, ASC_DESC> nameMap = new HashMap<String, ASC_DESC>();
        public static Map<String, ASC_DESC> abbrMap = new HashMap<String, ASC_DESC>();
        static{
            for(ASC_DESC e : ASC_DESC.values()){
                valueMap.put(e.v, e);
                nameMap.put(e.n, e);
                nameMap.put(e.abbr, e);
            }
        }
        private ASC_DESC(int value, String name, String abbr){
            this.v = value; this.n = name; this.abbr = abbr;
        }
        public static ASC_DESC v2E(int value){ return valueMap.get(value); }
        public static ASC_DESC n2E(String name){ return nameMap.get(name); }
        public static ASC_DESC abbr2E(String abbr){ return abbrMap.get(abbr); }
    }
}

一覧個別

共通を継承して作成。検索キーワード等の画面個別のパラメータをうける

/**
 * HogePiyo一覧のパラメータを受け取る
 *
 */
public class HogePiyoListForm extends ListBaseForm{
    //各種検索パラメータ
    public String id;
    public String name;
    public String age;
    public List<String> licenses;
 
    /** id検索パラメータを内部で使う型で取り出す */
    public Long getIdCond(){
        if(this.hasIdCond()){
            // 条件無しなら条件を無視するようなパラメータを返す
            // S2JDBCの検索系のメソッドではnullをパラメータとして渡すと
            // null検索ではなく検索条件そのものを無視してくれる仕様のためnullを返している
            // ここらへんは検索するメソッドのインタフェースに合わせてケースバイケース
            return null;
        }
        if(!this.isValidId()){
            // 目的は検索なので不正なパラメータの場合は
            // 正常値だけど検索結果ゼロになるようなパラメータを返す
            // 現実的にはどれか1個でも不正ならば処理せずゼロ件表示にショートカットすればいい
            return 0L;
        }
        return NumberUtils.toLong(this.id, 0);
    }
    /** idの検索条件があるかないか */
    public boolean hasIdCond(){
        return !StringUtils.isBlank(this.id);
    }
    /** idの検索条件が正しいものか否か */
    public boolean isValidId(){
        // 検索条件なので空も許可
        if(StringUtils.isBlank(this.id)){
            return true;
        }
        // 空でもない整数値でもないものはダメ
        if(!NumberUtils.isDigits(this.id)){
            return false;
        }
        Long idNum = NumberUtils.toLong(this.id, 0);
        Range<Long> range = Range.between(1L, 99999999L);
        return range.contains(idNum);
    }
    /**
     * 検索条件IDのQueryString表現を返す
     */
    public String getIdQuery(){
        String q = "id=";
        if(StringUtils.isEmpty(this.id)){
            return "id=";
        }else{
            try{
                return "id=" + URLEncoder.encode(this.id, "UTF-8");
            }catch(UnsupportedEncodingException e){
                throw new RuntimeException();
            }
        }
    }
 
    /**
     * 検索条件の初期化
     */
    public void init(){
        if(!this.isDefault()){
            return;
        }
        // デフォルトなので入っていないパラメータを補う
        this.age = "20";
    }
 
    /** 検索条件をURLにくっつける形式で返す */
    public String getParamsQuery(){
        List<String> paramList = new ArrayList<String>();
        paramList.add(this.getIdQuery());
        return StringUtils.join(paramList, "&");
    }
    // 画面上で使用するページングソーティング用のURLパラメータを返すメソッドを
    // 全部作る
    public String geLimit10Query(){
        return this.getLimitQuery(10);
    }
    public String geLimit50Query(){
        return this.getLimitQuery(50);
    }
    public String geLimit100Query(){
        return this.getLimitQuery(100);
    }
    public String getLimitQuery(int limit){
        return this.getParamsQuery() + "&lm=" + Integer.toString(limit);
    }
 
    /** 件数に画面ごとの固定化がほしいならば(画面ごとに同じなら共通側に実装してもよい) */    
    public enum LIMIT{
        LIMIT_10(10, "10"),
        LIMIT_50(50, "50"),
        LIMIT_100(1000, "100");
        public int v;public String n;
        public static Map<Integer, LIMIT> valueMap = new HashMap<Integer, LIMIT>();
        public static Map<String, LIMIT> nameMap = new HashMap<String, LIMIT>();
        static{
            for(LIMIT e : LIMIT.values()){
                valueMap.put(e.v, e);
                nameMap.put(e.n, e);
            }
        }
        private LIMIT(int value, String name){
            this.v = value; this.n = name;
        }
        public static LIMIT v2E(int value){ return valueMap.get(value); }
        public static LIMIT n2E(String name){ return nameMap.get(name); }
    }
}

DTO

JSPで一覧をハンドリングするための入れ物

/**
 * JSPで一覧をハンドリングするための入れ物
 */
public class ListDto<T>{
    // 表示するレコード群を格納する
    public List<T> list;
    // ハンドリング用の情報
    // 1ページのレコード数
    public int limit;
    // 現在のページ番号(1からスタート)
    public int currentPage;
    // 全体件数
    public int total;
    // EL式で値を呼び出したいので getつけてるよ
    /**
     * 最終ページ番号を得る(最初のページは1起算)
     * @return
     */
    public int getMaxPage(){
        // 全体がゼロなら最終もゼロ
        if(total == 0){
            return 0;
        }
        // 割り切れるならそのままのページ数
        if((total % limit) == 0){
            return (int)(total / limit);
        }
        // ページからあふれるならば1ページ足す
        return (int) (total / limit) + 1;
    }
    /**
     * 前のページがあるか否か
     */
    public boolean hasPrevPage(){
        //1ページより現在ページが後だ
        return (currentPage > 1);
    }
    /** EL用 */
    public boolean getHasPrevPage(){
        return this.hasPrevPage();
    }
    /**
     * 次のページがあるか否か
     */
    public boolean hasNextPage(){
        //1ページよりページ数が多い 現在ページが最終ページより前だ
        return (getMaxPage() > 1 && currentPage < getMaxPage());
    }
    /** EL用 */
    public boolean getHasNextPage(){
        return this.hasNextPage();
    }
 
    /**
     * 格納しているレコード群の一番最初のレコードはレコード全体で何番目なのか
     */
    public int getFirstRow(){
        return (currentPage - 1) * limit + 1;
    }
    /**
     * 格納しているレコード群の一番最後のレコードはレコード全体で何番目なのか
     */
    public int getLastRow(){
        return getFirstRow() + list.size() - 1;
    }
}

JSP

共通レイアウト

各一覧の画面

<%@page pageEncoding="UTF-8"%>
<tiles:insert template="/WEB-INF/view/common/layout.jsp" flush="true">
    <tiles:put name="title" value="HogePiyoの一覧" />
    <tiles:put name="content" type="string">
<s:form method="get">
    <%-- 文字入力の検索条件 --%>
    <input name="id" type="text" value="${ hogePiyoListForm.id }" />
    <%-- 文字入力の検索条件 --%>
    <input name="name" type="text" value="${ hogePiyoListForm.name }" />
    <%-- セレクトボックスで選ぶ検索条件 --%>
    <html:select property="age" value="${ hogePiyoListForm.age }" >
        <html:option value="18">18</html:option>
        <html:option value="19">19</html:option>
        <html:option value="20">20</html:option>
        <html:option value="21">21</html:option>
        <html:option value="22">22</html:option>
        <html:option value="23">23</html:option>
        <html:option value="24">24</html:option>
        <html:option value="25">25</html:option>
    </html:select>
    <input name="df" type="hidden" value="n" />
</s:form>
${f:h(listDto.firstRow) } 〜 ${ f:h(listDto.lastRow) } 件 / ${ f:h(listDto.total) } 件中 <br />
<table>
    <tr>
        <th>ID</th>
        <th>name</th>
        <th>age</th>
    </tr>
<c:forEach var="hp" items="${ listDto.list }" >
    <tr>
        <td>${ f:h(hp.id) }</td>
        <td>${ f:h(hp.name) }</td>
        <td>${ f:h(hp.age) }</td>
    </tr>
</c:forEach>
</table>
    </tiles:put>
</tiles:insert>

タグ

java/sastruts/funcitons_implement_pattern/list_session.txt · 最終更新: 2017-09-26 18:34 by ore