One POJO but the different XmlRootElement name

191 views Asked by At

For Example, I have one POJO as shown below but it feeds into multiple operations but I do not want to create several identical POJO's just because the root element name changes for each operation. Hence I need one POJO but in such a way that I can dynamically change the Root Element Name.

@ToString
@MappedSuperclass
@lombok.Data
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
@EqualsAndHashCode(callSuper = false)
public class AmountOrAccountBlockOrUnblockRequest extends XmlBuilder implements SessionGenerator {

    @JsonIgnore
    @XmlElement
    private String TargetBankVerificationNumber;

    @JsonIgnore
    @XmlElement
    private String Narration;

    @JsonProperty("amount")
    @XmlElement(name = "Amount")
    private String amount;

    @JsonProperty("savingAccountNumber")
    @XmlElement(name = "TargetAccountNumber")
    private String targetAccountNumber;

    @JsonIgnore
    @XmlElement
    private String ChannelCode;

    @JsonProperty("unblockId")
    @JsonIgnore
    @XmlElement
    private String ReferenceCode;

    @JsonIgnore
    @XmlElement
    private String DestinationInstitutionCode;

    @JsonIgnore
    @XmlElement
    private String TargetAccountName;

    @XmlElement
    private String SessionID;

    @JsonIgnore
    @XmlElement
    private String ReasonCode;

    // if account is still blocked or released
    @JsonProperty("block")
    private boolean blockUnblock;

    @JsonProperty("blockUnblockReason")
    private String blockUnblockReason;

    @Override
    public String toXmlString() {
        return super.convertObjectToXmlString(this, this.getClass());
    }

    @Override
    public void generateSessionID(HelperFacade helperFacade) {
        setSessionID(helperFacade.generateSessionID(this.getDestinationInstitutionCode()));
    }
}

This single POJO above will serve several operations but with a different Root Element Name for each operation for example,

<AmountUnblockRequest>
<SessionID>000001100913103301000000000001</SessionID>
<DestinationInstitutionCode>000002</DestinationInstitutionCode>
<ChannelCode>7</ChannelCode>
<ReferenceCode>xxxxxxxxxxxxxxx</ReferenceCode>
<TargetAccountName>Ajibade Oluwasegun</TargetAccountName>
<TargetBankVerificationNumber>1033000442</TargetBankVerificationNumber>
<TargetAccountNumber>2222002345</TargetAccountNumber>
<ReasonCode>0001</ReasonCode>
<Narration>Transfer from 000002 to 0YY</Narration>
<Amount>1000.00</Amount>
</AmountUnblockRequest>

and

<AmountBlockRequest>
<SessionID>000001100913103301000000000001</SessionID>
<DestinationInstitutionCode>000002</DestinationInstitutionCode>
<ChannelCode>7</ChannelCode>
<ReferenceCode>xxxxxxxxxxxxxxx</ReferenceCode>
<TargetAccountName>Ajibade Oluwasegun</TargetAccountName>
<TargetBankVerificationNumber>1033000442</TargetBankVerificationNumber>
<TargetAccountNumber>2222002345</TargetAccountNumber>
<ReasonCode>0001</ReasonCode>
<Narration>Transfer from 000002 to 0YY</Narration>
<Amount>1000.00</Amount>
</AmountBlockRequest>

I want to avoid the pain of having to create two identical classes all because the root element name will change.

1

There are 1 answers

0
mfe On

You can use Declarative Stream Mapping (DSM) stream parsing library. You don't need to annotate your POJO both for XML and JSON.

You just define the mapping for data you want to extract from XML.

Here are mapping definitions for your XML.

result:
  path: /(AmountBlockRequest|AmountUnblockRequest) // path is regex
  type: object
  fields:
    TargetBankVerificationNumber:
    Narration:
    amount:
      path: amount
      xml:
        path: Amount
    targetAccountNumber:
      path: targetAccountNumber
      xml:
        path: TargetAccountNumber

    channelCode:
      path: ChannelCode
    referenceCode:
      path: ReferenceCode
    destinationInstitutionCode:
      path: DestinationInstitutionCode
    targetAccountName:
      path: TargetAccountName
    sessionID:
      path: SessionID
    reasonCode:
      path: ReasonCode
    blockUnblockReason:
      path: BlockUnblockReason

Java Code to parse XML:

DSM dsm=new DSMBuilder(new File("path/to/mapping.yaml")).setType(DSMBuilder.TYPE.XML)..create(AmountOrAccountBlockOrUnblockRequest.class);;
// For json
//DSM dsm=new DSMBuilder(new File("path/to/mapping.yaml")).setType(DSMBuilder.TYPE.JSON)..create(AmountOrAccountBlockOrUnblockRequest.class);
AmountOrAccountBlockOrUnblockRequest result=  (AmountOrAccountBlockOrUnblockRequest)dsm.toObject(xmlFileContent);
// json represntation fo result
dsm.getObjectMapper().writerWithDefaultPrettyPrinter().writeValue(System.out, object);

Here is output:

   {
  "amount" : "1000.00",
  "targetAccountNumber" : "2222002345",
  "blockUnblock" : false,
  "blockUnblockReason" : null,
  "sessionID" : "000001100913103301000000000001",
  "reasonCode" : "0001",
  "referenceCode" : "xxxxxxxxxxxxxxx",
  "channelCode" : "7",
  "narration" : null,
  "targetBankVerificationNumber" : null,
  "destinationInstitutionCode" : "000002",
  "targetAccountName" : "Ajibade Oluwasegun"
}

Currently it is not support serialization.