人生でやりたいことを浮き彫りにする質問
最近Tracのチケットテンプレートファイルをカスタムするのがマイブームになっています。
今日は、テンプレートファイルにて、ログインユーザ名を取得する方法がわかったので、メモします。
$authnameこれで取得できます! 因みに環境は、以下のとおり
WebシステムでPropertyファイルを起動時に読み込んでメモリ上に展開することはよくあることだと思います。
で、それをEnumでやったらこうなる!というのを作ってみました。
PropertyHolder.java
package property;
import java.util.Properties;
import java.util.Set;
public enum PropertyHolder {
Hoge("hoge.properties"), Foo("foo.properties"), Bar("bar.properties");
private Properties properties;
private String fileName;
static {
System.out.println("staticイニシャライザ開始");
for (PropertyHolder p : values()) {
System.out.println("static:" + p.name());
p.init();
}
}
private PropertyHolder(String fileName) {
System.out.println("constructor:" + fileName);
this.fileName = fileName;
}
private void init() {
System.out.println("init:" + fileName);
properties = new Properties();
try {
properties.load(getClass().getClassLoader().getResourceAsStream(
fileName));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String get(String key) {
return properties.getProperty(key);
}
public String getAll() {
System.out.println("getAll:" + fileName);
Set<Object> keys = properties.keySet();
StringBuilder sb = new StringBuilder();
for (Object obj : keys) {
String key = (String) obj;
sb.append("[");
sb.append(key);
sb.append(":");
sb.append(get((String) obj));
sb.append("]");
}
return sb.toString();
}
}
package property;
public class Main {
public static void main(String[] args) {
System.out.println("Hoge.get(\"a\"):" + PropertyHolder.Hoge.get("a"));
System.out.println("Hoge.getAll():" + PropertyHolder.Hoge.getAll());
System.out.println("Foo.getAll():" + PropertyHolder.Foo.getAll());
System.out.println("Bar.getAll():" + PropertyHolder.Bar.getAll());
}
}
hoge.properties a=A b=B c=Cfoo.properties
aa=AA bb=BB cc=CCbar.properties
aaa=AAA bbb=BBB ccc=CCC実行結果
constructor:hoge.properties constructor:foo.properties constructor:bar.properties staticイニシャライザ開始 static:Hoge init:hoge.properties static:Foo init:foo.properties static:Bar init:bar.properties Hoge.get("a"):A getAll:hoge.properties Hoge.getAll():[b:B][a:A][c:C] getAll:foo.properties Foo.getAll():[aa:AA][bb:BB][cc:CC] getAll:bar.properties Bar.getAll():[bbb:BBB][aaa:AAA][ccc:CCC]ポイントは、staticイニシャライザでEnumクラスの定数一つ一つがもっているinitメソッドを呼んでいるところですかね。
いろいろな使い方があるEnumですが、Utilクラスを作るのにもつかえます!
ためしに日付を変換するUtilを作ってみました。
日付<>文字列を変換するときは、いろいろなフォーマットの日付を表す文字列に対応しなければならないので、フォーマットの定義(yyyyMMddみたいなの)をたくさん定義して、定義した分だけ同じよう名メソッドを作らなければなりません。。
ですが、Enumを使えばすっきりかけます~。
以下コードです。
DateUtil.java
package util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
// TODO: 自動生成された Javadoc
/**
* The Enum DateUtil.
*/
public enum DateUtil {
// ------------------------------
// 変換したいフォーマットを追加(start)
// ------------------------------
/** The YYYYMMDD. */
YYYYMMDD("yyyy/MM/dd"),
/** The YYYYMMDDHHMM. */
YYYYMMDDHHMM("yyyy/MM/dd hh:mm"),
/** The YYYYMMDDHHMMSS. */
YYYYMMDDHHMMSS("yyyy/MM/dd HH:mm.ss"),
/** The YYYYMMDDHHMMSSSSS. */
YYYYMMDDHHMMSSSSS("yyyy/MM/dd HH:mm.ss.SSS"),
/** The Jp_ yyyymmdd. */
JP_YYYYMMDD("yyyy年MM月dd日"),
/** The Jp_ yyyymmddhhmm. */
JP_YYYYMMDDHHMM("yyyy年MM月dd日HH時mm分"),
/** The Jp_ yyyymmddhhmmss. */
JP_YYYYMMDDHHMMSS("yyyy年MM月dd日HH時mm分ss秒");
// ------------------------------
// 変換したいフォーマットを追加(end)
// ------------------------------
/** The format. */
private String format;
/**
* Instantiates a new date util.
*
* @param format
* the format
*/
private DateUtil(String format) {
this.format = format;
}
/**
* To date.
*
* @param dateString
* the date string
* @return the date
*/
public Date toDate(String dateString) {
try {
return new SimpleDateFormat(format).parse(dateString);
} catch (ParseException e) {
// RuntimeExceptionでラップしてしまっていますが、システム共通Exceptionを投げるようにする方がいいと思います。
// 場合によって使い分けてください。
throw new RuntimeException("文字列→Dateへの変換に失敗しました(format:" + format
+ ",string:" + dateString + ")", e);
}
}
/**
* To string.
*
* @param date
* the date
* @return the string
*/
public String toString(Date date) {
return new SimpleDateFormat(format).format(date);
}
}
Main.java
package util;
import java.util.Date;
public class Main {
public static void main(String[] args) {
System.out.println("YYYYMMDD.toDate:"
+ DateUtil.YYYYMMDD.toDate("2012/1/29"));
System.out.println("YYYYMMDDHHMM.toDate:"
+ DateUtil.YYYYMMDDHHMM.toDate("2012/1/29 1:5"));
System.out.println("YYYYMMDDHHMMSS.toDate:"
+ DateUtil.YYYYMMDDHHMMSS.toDate("2012/1/29 1:5.7"));
System.out.println("YYYYMMDDHHMMSSSSS.toDate:"
+ DateUtil.YYYYMMDDHHMMSSSSS.toDate("2012/1/29 1:5.7.100"));
System.out.println("JP_YYYYMMDD.toDate:"
+ DateUtil.JP_YYYYMMDD.toDate("2012年1月29日"));
System.out.println("JP_YYYYMMDDHHMM.toDate:"
+ DateUtil.JP_YYYYMMDDHHMM.toDate("2012年1月29日1時5分"));
System.out.println("JP_YYYYMMDDHHMMSS.toDate:"
+ DateUtil.JP_YYYYMMDDHHMMSS.toDate("2012年1月29日1時5分7秒"));
System.out.println("------------------------------");
System.out.println(DateUtil.YYYYMMDD.toString(new Date()));
System.out.println(DateUtil.YYYYMMDDHHMM.toString(new Date()));
System.out.println(DateUtil.YYYYMMDDHHMMSS.toString(new Date()));
System.out.println(DateUtil.YYYYMMDDHHMMSSSSS.toString(new Date()));
System.out.println(DateUtil.JP_YYYYMMDD.toString(new Date()));
System.out.println(DateUtil.JP_YYYYMMDDHHMM.toString(new Date()));
System.out.println(DateUtil.JP_YYYYMMDDHHMMSS.toString(new Date()));
}
}
実行結果
YYYYMMDD.toDate:Sun Jan 29 00:00:00 JST 2012
YYYYMMDDHHMM.toDate:Sun Jan 29 01:05:00 JST 2012
YYYYMMDDHHMMSS.toDate:Sun Jan 29 01:05:07 JST 2012
YYYYMMDDHHMMSSSSS.toDate:Sun Jan 29 01:05:07 JST 2012
JP_YYYYMMDD.toDate:Sun Jan 29 00:00:00 JST 2012
JP_YYYYMMDDHHMM.toDate:Sun Jan 29 01:05:00 JST 2012
JP_YYYYMMDDHHMMSS.toDate:Sun Jan 29 01:05:07 JST 2012
------------------------------
2012/01/29
2012/01/29 06:27
2012/01/29 18:27.51
2012/01/29 18:27.51.073
2012年01月29日
2012年01月29日18時27分
2012年01月29日18時27分51秒
まぁこんな感じです。
DateUtilクラスでは、フォーマットを定義をして、Date<>Stringのメソッドを共通的に実装してます!
フォーマットごとにDate<>String変換メソッドを実装しなくてすむので、楽です~
※サンプルでは、toDateメソッドにて、ParseExceptionをRuntimeExceptionにラップしてしまっているので、使うときは、システムで使用しているExceptionにラップして使うようにしてください!
以下の環境で、strutsのtilesをしようしようとしたら503エラーが。。
struts 1.3.10
spring 2.5
なんでかって。。それは、struts-configで宣言しているcontrollerタグで指定するクラスが間違ってたからでした。
↓の用に設定していましたが、DelegatingRequestProcessorではなDelegatingTilesRequestProcessorでした。。
ダメ
<controller>
<set-property property="processorClass"
value="org.springframework.web.struts.DelegatingRequestProcessor"/>
</controller>
<controller>
<set-property property="processorClass"
value="org.springframework.web.struts.DelegatingTilesRequestProcessor"/>
</controller>
きっかけ
JSPを作成する際に上のほうに↓のような宣言をよくかきますよね。。
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
tiles.xmlでputタグに設定したvalueの値を、JSP側のbean:messageタグのkey属性に設定しようとしたらはまったので、メモします。
前提
tiles.xml
↓の用に定義しています。
<definition name="baseLayout" path="/WEB-INF/jsp/shared/baseLayout.jsp">
<put name="screenId" value="A001"/>
</definition>
A001=A画面
<bean:message key="<tiles:getAsString name="screenId"/>" />
<bean:define id="screenId"><tiles:getAsString name="screenId"/></bean:define>これで何とかリソースファイルから値を取得することが出来ました。
<bean:message key="${screenId}" />