概要
digesterを使用してXMLの属性値をJavaのオブジェクトに設定するとき、
アクセサのメソッド名でハマった際の覚書。
ハマったケースは、 <element cAmel="hoge">
のように、属性値の1文字目が小文字、2文字目が大文字の場合。
public void setcAmel(String cAmel)
とすればよいようだが、
とある開発環境でアクセサを自動生成した際に、public void setCAmel(String CAmel)
と作成された。
commons-digesterはJavaにマッピングする際に、内部ではBeanUtilsに依存しており
BeanUtilsはJavaBeans Specification (Version 1.0.1)に従い
リフレクションを使ってsetterを呼びに行く模様。
Java Beansの仕様に沿ったフィールド名とアクセサ名の関連付けについての議論は、
下記サイトが分かりやすい。
読み込むXML
読み込むXML
<?xml version="1.0" encoding="UTF-8"?>
<response>
<elements>
<element number="123" cAmel="cAmel" UPPER="UPPER" lower="lower"
boolFlag="true" emptyString="" blankString=" " />
<element unknownProperty="unknown" />
</elements>
</response>
マッピング先のJavaクラス
ResponseDto.java
public class ResponseDto {
private List<ElementDto> _elements;
public List<ElementDto> getElements() {
return this._elements;
}
public void setElements(List<ElementDto> elements) {
this._elements = elements;
}
}
ElementDto
public class ElementDto {
private Integer _number;
private String _cAmel;
private String _UPPER;
private String _lower;
private Boolean _boolFlag;
public Integer getNumber() {
return this._number;
}
public void setNumber(Integer number) {
this._number = number;
}
public String getcAmel() {
return this._cAmel;
}
public void setcAmel(String cAmel) {
this._cAmel = cAmel;
}
public String getUPPER() {
return this._UPPER;
}
public void setUPPER(String uPPER) {
this._UPPER = uPPER;
}
public String getLower() {
return this._lower;
}
public void setLower(String lower) {
this._lower = lower;
}
public Boolean getBoolFlag() {
return this._boolFlag;
}
public void setBoolFlag(Boolean boolFlag) {
this._boolFlag = boolFlag;
}
public String toString(){
return new ReflectionToStringBuilder(this).toString();
}
}
使用したdigesterのルール
<!DOCTYPE digester-rules PUBLIC
"-//Apache Commons //DTD digester-rules XML V1.0//EN"
"http://commons.apache.org/digester/dtds/digester-rules-3.0.dtd">
<digester-rules>
<!-- "response" タグが現れると ResponseDtoを作成する -->
<pattern value="response">
<object-create-rule classname="org.nt67.digester_test.dto.ResponseDto" />
</pattern>
<!-- "elements" タグが現れると java.util.ArrayListを作成して、親(ResponseDto)の setElementsメソッドを呼び出す-->
<pattern value="response/elements">
<object-create-rule classname="java.util.ArrayList" />
<set-next-rule methodname="setElements" />
</pattern>
<!-- "element"タグが現れると ElementDtoを作成し、属性を設定して、親のaddメソッド(java.util.ArrayList)を呼ぶ -->
<pattern value="response/elements/element">
<object-create-rule classname="org.nt67.digester_test.dto.ElementDto" />
<set-properties-rule/>
<set-next-rule methodname="add" />
</pattern>
</digester-rules>
読み込み結果
読み込み結果
// ElementDtoのtoString出力結果
org.nt67.digester_test.dto.ElementDto@2b76e552[_number=123,_cAmel=cAmel,_UPPER=UPPER,_lower=lower,_boolFlag=true]
org.nt67.digester_test.dto.ElementDto@332611a7[_number=<null>,_cAmel=<null>,_UPPER=<null>,_lower=<null>,_boolFlag=<null>]