menu
書いてる野郎
orebike@gmail.com
http://hogehogehoge.com/hogePiyoList/?hoge=piyo&so=id-a&pg=3&lm=10
/** * 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は基本的に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); } } }
/** * 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; } }
<%@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>