LoginSignup
0
0

More than 5 years have passed since last update.

commons-digesterによるXMLからJavaオブジェクトへのマッピング

Last updated at Posted at 2013-09-07

概要

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の仕様に沿ったフィールド名とアクセサ名の関連付けについての議論は、
下記サイトが分かりやすい。

JavaBeansの命名規則 - 日々常々

読み込む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>]
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0