当前位置: 首页 > 工具软件 > Betwixt > 使用案例 >

关于Apache Commons Betwixt的简单例子!

王子明
2023-12-01

1. 原理及流程简介
1.1 commons-betwixt
基本原理

Commons Betwixt这个组件提供了一个XML自省(introspection)机制用来把Java Bean映射成XML信息(.xml文件或符合xml格式的字符串,下同)或者把XML信息映射成Java Bean。

在解析XML信息时采用SAX方式。

核心类,方法及步骤简介

xml信息映射成java bean

org.apache.commons.betwixt.io.BeanReader

       要把xml信息映射成 Java Bean,这个类是最核心的类。首先要构造此类的一个对象。然后配置该对象属性,(包括给XML信息是否匹配Attribute或Id等等),下来最重要的一步是给这个对象注册一个BeanClass,即要转化的Java Bean的类名,函数原型为:void registerBeanClass(String path, Class beanClass),其中path为XML信息中要转化的element名。接下来就是最后一步,调用核心方法Object parse(String),这个方法不是BeanReader本身的。而是它继承的org.apache.commons.digester.Digester里面的方法,这里不在叙述。

java bean映射成xml信息

org.apache.commons.betwixt.io.BeanWriter

       要把Java Bean 映射成XML信息,此为核心类。同样,首先要构造此类的一个对象,然后配置该对象(包括是否给生成的XML信息设置格式化,Attribute或Id等等),然后调用核心方法write(String name,Object bean)name是即将生成的XML信息的element名,bean为待转化的对象。此方法是BeanWriter自身的方法。

需要的支持环境:

commons-digester.jar,commons-beanutils.jar, commons-codec.jar, commons-lang.jar,dom4j-1.3.jar


以上都是从http://www.open-java.com/a/200911/10142426.shtml 这里参照过来的,下面是我自己写的サンプル:

Test.java

package beanreadertest04;


import java.beans.IntrospectionException;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;


import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.betwixt.io.BeanReader;
import org.xml.sax.SAXException;




/**
 * 使用betwixt进行xml与java对象之间的互转解析
 * <p>
 * 导入commons-logging-1.0.4.jar commons-beanutils-1.6.1.jar
 * commons-betwixt-0.8.jar commons-collections-2.1.jar commons-digester-1.7.jar
 *
 * @author tower
 *
 */
public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            String xmlPath = "D:\\develop\\eclipse\\WorkSpaceYuYuSeiHo\\HaoTest\\src\\beanreadertest03\\IssueTasksObj.xml";
            IssueTasksObj issueTasksObj = (IssueTasksObj) xml2Object(xmlPath,"IssueTasksObj", IssueTasksObj.class);
            System.out.println(BeanUtils.describe(issueTasksObj));
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    /**
     * 解析xml文件为Object对象
     *
     * @param xmlPath
     *            需解析的xml文件路径
     * @param rootElement
     *            xml文件的根元素
     * @param beanClass
     *            根元素所对应的bean类
     * @return Object
     */
    public static Object xml2Object(String xmlPath, String rootElement, Class<IssueTasksObj> beanClass) {
        Object o = null;
        try {
            BeanReader beanReader = new BeanReader();
            // 是否以attribute的形式显示简单的id
            beanReader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(false);
            // 不自动生成id
            beanReader.getBindingConfiguration().setMapIDs(false);
            // 当遇到ArrayList或者Map时做一个包装
            // beanReader.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
            // 注册
            beanReader.registerBeanClass(rootElement, beanClass);
            // 解析xml为object
            o = beanReader.parse(new FileInputStream(xmlPath));
        } catch (IntrospectionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return o;
    }
}


以上代码中 第33行的 "IssueTasksObj" 要与IssueTasksObj.xml中第2行 "<IssueTasksObj>" 里的字母大小写一定要一致

IssueTasksObj.

<?xml version="1.0" encoding="UTF-8"?>
<IssueTasksObj>
<ftpInfo>
   <ip>192.168.11.12</ip>
   <password>1234</password>
   <port>8080</port>
   <username>ceshi</username>
</ftpInfo>
<issueTasks>
   <issueTask>
    <contentcode>111</contentcode>
    <starttime>Tue Dec 30 09:24:04 CST 2008</starttime>
    <status>0</status>
   </issueTask>
   <issueTask>
    <contentcode>111</contentcode>
    <starttime>Tue Dec 30 09:24:04 CST 2008</starttime>
    <status>0</status>
   </issueTask>
</issueTasks>

 <librarys>
        <library>new Librarys1</library>
        <library>new Librarys2</library>
        <library>new Librarys3</library>
        <library>new Librarys4</library>
        <library>new Librarys5</library>
  </librarys>
</IssueTasksObj>


注意:两个add方法(addIssueTask和addLibrary最后都没有S。(我最初带上S,XML里的值就取不出来!)

IssueTasksObj.java

package beanreadertest04;

import java.util.ArrayList;
import java.util.List;

public class IssueTasksObj {
    private FtpInfo ftpInfo;

    // 在这里new是防止空指针
    private List<IssueTask> issueTasks = new ArrayList<IssueTask>();
    private List<String> librarys = new ArrayList<String>();

    /**
     * 每个Bean都必须有一个不带参数的构造方法。 或者bean不要写任何构造方法(这样实际上有一个默认的不带参数的构造方法)
     */
    public IssueTasksObj() {
    }

    /**
     * 每个对于包含其他Bean集合的Bean,要有一个addXxxBean(XxxBean bean)的方法,
     * 只有这样,才能保证将xml转换为java的时候,集合属性不丢失。 ※ 方法名最后没有S ※
     *
     * @param issueTask
     */
    public void addIssueTask(IssueTask issueTask) {
        issueTasks.add(issueTask);
    }

    /**
     * 每个对于包含其他Bean集合的Bean,要有一个addXxxBean(XxxBean bean)的方法,
     * 只有这样,才能保证将xml转换为java的时候,集合属性不丢失。 ※ 方法名最后没有S ※
     *
     * @param library
     */
    public void addLibrary(String library) {
        librarys.add(library);
    }

    public FtpInfo getFtpInfo() {
        return ftpInfo;
    }

    public void setFtpInfo(FtpInfo ftpInfo) {
        this.ftpInfo = ftpInfo;
    }

    public List<IssueTask> getIssueTasks() {
        return issueTasks;
    }

    public void setIssueTasks(List<IssueTask> issueTasks) {
        this.issueTasks = issueTasks;
    }

    public List<String> getLibrarys() {
        return librarys;
    }

    public void setLibrarys(List<String> librarys) {
        this.librarys = librarys;
    }
}

FtpInfo.java

package beanreadertest04;

public class FtpInfo {
    private String ip;
    private String username;
    private String password;
    private int port;

    /**
     * 每个Bean都必须有一个不带参数的构造方法。 或者bean不要写任何构造方法(这样实际上有一个默认的不带参数的构造方法)
     */
    public FtpInfo() {
    }

    public FtpInfo(String ip, String username, String password, int port) {
        this.ip = ip;
        this.username = username;
        this.password = password;
        this.port = port;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    public String toString() {
        return "FtpInfo[" + ip + " " + username + " " + password + " " + port + "]";
    }
}

IssueTask.java

package beanreadertest04;

import java.util.Date;

public class IssueTask {
    private int contentcode;
    private Date starttime;
    private int status;

    public IssueTask() {

    }

    public int getContentcode() {
        return contentcode;
    }

    public void setContentcode(int contentcode) {
        this.contentcode = contentcode;
    }

    public Date getStarttime() {
        return starttime;
    }

    public void setStarttime(Date starttime) {
        this.starttime = starttime;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "IssueTask[" + contentcode + " " + starttime + " " + status + "]";
    }
}
 类似资料: