Jibx 结合 ant使用的一些心得

关于jibx结合ant的使用。结合网上相关资料整理。
[参考资料](http://www.codeweblog.com/jibx-1-2-6-maven%E9%A1%B9%E7%9B%AE-ant%E7%BC%96%E8%AF%91%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/)
[参考资料](http://blog.csdn.net/hills/article/details/46741643)
[参考资料](http://www.cnblogs.com/hoojo/archive/2011/04/27/2030205.html)

1. 准备阶段相关jar

        <!-- https://mvnrepository.com/artifact/org.jibx/jibx-bind -->
        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-bind</artifactId>
            <version>1.2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.jibx/jibx-tools -->
        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-tools</artifactId>
            <version>1.2.6</version>
        </dependency>

2.开始构建。

  • step 1 :

    创建实体类Address.java
    
        package nettyJiBX.jn;

        import java.util.List;

        public class Address {

            private String street1;

            private String street2;

            private String city;

            private String state;

            private String postCode;

            private String country;

            private List<Order> listOrder;

        //  private HashMap<String,Order> map; 

        //  private String[] strArr;

            get set 方法省略...
        }
    创建Customer.java
        public class Customer {

            private long customerNumber;

            private String firstName;

            get set 方法省略...

        }
    创建Order.java
        package nettyJiBX.jn;

        public class Order {

            private long OrderNumber;

            private Customer customer;

            get set 方法略...

        }
  • step 2 生成xml相关信息:

          网上的好多文章第二步基本上就通过cmd窗口操作了。但是这里没有用那种方    
       法,因为可能需要好多依赖jar包如果配置不好,很容易就报错。所以直接在
       myeclips中找到这个类执行main方法就好了(外面的cmd窗口执行原理是一样
       的)。
    
       第二步应该找到org.jibx.binding.generator.BindGen
    

    这里写图片描述

    这个时候需要先配置启动参数

        - t:表示xml和xsd输出路径   
        - v:运行时打印输出信息
        - b: 设置输出的xml的名称 
    
        如果需要有多个类需要xml和bean互转可以写多个。
        "-t""G:\jibx-out""-v""nettyJiBX.jn.Address""nettyJiBX.jn.Order""nettyJiBX.jn.Customer"
        然后执行。
    
       生成的文件如下:
    

    这里写图片描述

  • step 3 执行ant:

    这一步就需要执行ant了,直接上ant相关配置。
    
    <?xml version="1.0" encoding="utf-8"?>
    <project default="main" basedir=".">
    <path id="classpath">
        <dirset dir="${basedir}/target/classes" />
        <dirset dir="${basedir}/target/test-classes" />
        <fileset dir="E:/maven/maven-jars/org/jibx/jibx-run/1.2.5/" includes="*.jar" />
        <fileset dir="E:/maven/maven-jars/org/jibx/jibx-bind/1.2.5/" includes="*.jar" />
        <fileset dir="E:/maven/maven-jars/bcel/bcel/5.1/" includes="*.jar" />
        <fileset dir="E:/maven/maven-jars/org/jibx/jibx-extras/1.2.6/"  ncludes="*.jar"/> 
        <fileset dir="E:/maven/maven-jars/xpp3/xpp3_min/1.1.4c/" includes="*.jar"/>   
    </path>
    <target name="main" depends="compile,binggen, bind" description="Main target" />
    <target name="compile" description="Compilation target">
        <echo>Building file.</echo>
        <echo>${basedir}</echo>
        <javac srcdir="${basedir}/src/main/java/nettyJiBX/jn" destdir="${basedir}/target/classes/nettyJiBX/jn" includeantruntime="true" />
    </target>
    <target name="binggen">
        <echo message="Running BindGen tool" />
        <java classpathref="classpath" fork="true" failonerror="true" classname="org.jibx.binding.BindingGenerator">
            <arg value="nettyJiBX.jn.Address" />
            <arg value="nettyJiBX.jn.Order" />
            <arg value="nettyJiBX.jn.Customer" />
        </java>
    </target>
    <target name="bind">
        <echo message="Running bind" />
        <taskdef name="bind" classname="org.jibx.binding.ant.CompileTask">
            <classpath refid="classpath"/>
        </taskdef>       
        <bind binding="${basedir}/map.xml">
            <classpath refid="classpath"/>
        </bind>
    </target>
</project>
    map.xml就是我们通过org.jibx.binding.generator.BindGen生成的。

    到此,所有的准备工作都已经完成了。
  • step 4 测试:
package nettyJiBX.jn;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.jibx.runtime.BindingDirectory;
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class JnTest {
    private IBindingFactory factory = null;

    private StringWriter writer = null;
    private StringReader reader = null;

    private Address bean = null;
    @Before
    public void init() {
        bean = new Address();
        bean.setCity("city");
        bean.setCountry("country");
        bean.setPostCode("postCode");
        bean.setState("state");
        bean.setStreet1("street1");
        bean.setStreet2("street2");
        Order order1 = new Order();
        Customer cus1 = new Customer();
        cus1.setCustomerNumber(500L);
        order1.setCustomer(cus1);
        order1.setOrderNumber(100L);
        Order order2 = new Order();
        Customer cus2 = new Customer();
        cus2.setCustomerNumber(1000L);
        order2.setCustomer(cus2);
        order2.setCustomer(null);
        order2.setOrderNumber(200L);
        List<Order> list = new ArrayList<Order>();
        list.add(order2);
        list.add(order1);
//      bean.setListOrder(list);
        try {
            factory = BindingDirectory.getFactory(Address.class);
        } catch (JiBXException e) {
            e.printStackTrace();
        }
    }

    @After
    public void destory() {
        bean = null;
        try {
            if (writer != null) {
                writer.flush();
                writer.close();
            }
            if (reader != null) {
                reader.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void bean2XML() {
        try {
            writer = new StringWriter();
            // marshal 编组
            IMarshallingContext mctx = factory.createMarshallingContext();
            mctx.setIndent(2);
            mctx.marshalDocument(bean, "UTF-8", null, writer);
            fail(writer);

            reader = new StringReader(writer.toString());
            //unmarshal 解组
            IUnmarshallingContext uctx = factory.createUnmarshallingContext();
            Address acc = (Address) uctx.unmarshalDocument(reader, null);
            fail(acc);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void fail(Object o) {
        System.out.println(o);
    }

    public void failRed(Object o) {
        System.err.println(o);
    }

}
  • 简单总结:

    jibx实现转换的时候主要涉及到三个类(中的main方法):

  • org.jibx.binding.generator.BindGen
  • org.jibx.binding.BindingGenerator
  • org.jibx.binding.Compile

    我把自己研究结果的基本流程跟大家分享一下:

  • 第一步:
    通过指定的实体类生成xml文件,这一步主要是通过
    org.jibx.binding.generator.BindGen
    org.jibx.binding.BindingGenerator
    上面的这两个类来实现的,但是通过尝试发现BindingGenerator这个类生成的会好一点儿。因为如果这个实体中有Map那么BindingGenerator也能生成,但是用BindGen就会报错
    Exception in thread "main" java.lang.IllegalStateException:
    No way to handle type java.util.HashMap, referenced from nettyJiBX.jn.MapBean
    at org.jibx.binding.generator.BindGen.expandReferences(BindGen.java:227)
    at org.jibx.binding.generator.BindGen.findReferences(BindGen.java:1010)
    at org.jibx.binding.generator.BindGen.generate(BindGen.java:1124)
    at org.jibx.binding.generator.BindGen.main(BindGen.java:1302)
  • 第二步:
    就是通过第一步生成的xml生成一些类
    这里写图片描述
    第二步生成的class主要是通过org.jibx.binding.Compile中的compile方法
    这里写图片描述
    我们上面的ant文件中的org.jibx.binding.ant.CompileTask也就是
 <target name="bind">
        <echo message="Running bind" />
        <taskdef name="bind" classname="org.jibx.binding.ant.CompileTask">
            <classpath refid="classpath"/>
        </taskdef>       
        <bind binding="${basedir}/map.xml">
            <classpath refid="classpath"/>
        </bind>
    </target>
其实也是调用了org.jibx.binding.Compile中的compile方法

这里写图片描述

所以其实上面的ant文件中的

<target name="binggen">
        <echo message="Running BindGen tool" />
        <java classpathref="classpath" fork="true" failonerror="true" classname="org.jibx.binding.BindingGenerator">
            <arg value="nettyJiBX.jn.Address" />
            <arg value="nettyJiBX.jn.Order" />
            <arg value="nettyJiBX.jn.Customer" />
        </java>
    </target>

可以去掉,因为如果前面已经生成了xml这一步就没什么用了,当然如果可以一起集成到ant中也是极好的,
因为对ant用的较少还不是很6。

还有一个常见的异常:

org.jibx.runtime.JiBXException: Base element type java.lang.Long must be mapped
    at org.jibx.binding.BindingGenerator.defineFields(BindingGenerator.java:360)
    at org.jibx.binding.BindingGenerator.defineStructure(BindingGenerator.java:624)
    at org.jibx.binding.BindingGenerator.createMapping(BindingGenerator.java:739)
    at org.jibx.binding.BindingGenerator.generate(BindingGenerator.java:891)
    at org.jibx.binding.BindingGenerator.main(BindingGenerator.java:1092)

这种异常可以在调用main方法中增加参数“java.lang.Long”就可以了,以此类推(java.lang.String);(PS:感觉这种解决方法不是很好,等待更好的方法)。

还有一个解决实体中Map转换的问题。
只需要加一个类。

package nettyJiBX.jn;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.jibx.runtime.IAliasable;
import org.jibx.runtime.IMarshallable;
import org.jibx.runtime.IMarshaller;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.IUnmarshaller;
import org.jibx.runtime.IUnmarshallingContext;
import org.jibx.runtime.JiBXException;
import org.jibx.runtime.impl.MarshallingContext;
import org.jibx.runtime.impl.UnmarshallingContext;

public class HashMapper implements IMarshaller, IUnmarshaller, IAliasable{



    private static final String SIZE_ATTRIBUTE_NAME = "size";
    private static final String ENTRY_ELEMENT_NAME = "entry";
    private static final String KEY_ATTRIBUTE_NAME = "key";
    private static final int DEFAULT_SIZE = 10;

    private String m_uri;
    private int m_index;
    private String m_name;

    public HashMapper() {
        m_uri = null;
        m_index = 0;
        m_name = "hashmap";
    }

    public HashMapper(String uri, int index, String name) {
        m_uri = uri;
        m_index = index;
        m_name = name;
    }

    /* (non-Javadoc)
     * @see org.jibx.runtime.IMarshaller#isExtension(int)
     */

//    public boolean isExtension(int index) {
//        return false;
//    }
// 
    /* (non-Javadoc)
     * @see org.jibx.runtime.IMarshaller#marshal(java.lang.Object,
     *  org.jibx.runtime.IMarshallingContext)
     */
    @Override
    public void marshal(Object obj, IMarshallingContext ictx)
        throws JiBXException {

        // make sure the parameters are as expected
        if (!(obj instanceof HashMap)) {
            throw new JiBXException("Invalid object type for marshaller");
        } else if (!(ictx instanceof MarshallingContext)) {
            throw new JiBXException("Invalid object type for marshaller");
        } else {

            // start by generating start tag for container
            MarshallingContext ctx = (MarshallingContext)ictx;
            HashMap map = (HashMap)obj;
            ctx.startTagAttributes(m_index, m_name).
                attribute(m_index, SIZE_ATTRIBUTE_NAME, map.size()).
                closeStartContent();

            // loop through all entries in hashmap
            Iterator iter = map.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry)iter.next();
                ctx.startTagAttributes(m_index, ENTRY_ELEMENT_NAME);
                if (entry.getKey() != null) {
                    ctx.attribute(m_index, KEY_ATTRIBUTE_NAME,
                        entry.getKey().toString());
                }
                ctx.closeStartContent();
                if (entry.getValue() instanceof IMarshallable) {
                    ((IMarshallable)entry.getValue()).marshal(ctx);
                    ctx.endTag(m_index, ENTRY_ELEMENT_NAME);
                } else {
                    throw new JiBXException("Mapped value is not marshallable");
                }
            }

            // finish with end tag for container element
            ctx.endTag(m_index, m_name);
        }
    }

    /* (non-Javadoc)
     * @see org.jibx.runtime.IUnmarshaller#isPresent(org.jibx.runtime.IUnmarshallingContext)
     */
    @Override
    public boolean isPresent(IUnmarshallingContext ctx) throws JiBXException {
        return ctx.isAt(m_uri, m_name);
    }

    /* (non-Javadoc)
     * @see org.jibx.runtime.IUnmarshaller#unmarshal(java.lang.Object,
     *  org.jibx.runtime.IUnmarshallingContext)
     */
    @Override
    public Object unmarshal(Object obj, IUnmarshallingContext ictx)
        throws JiBXException {

        // make sure we're at the appropriate start tag
        UnmarshallingContext ctx = (UnmarshallingContext)ictx;
        if (!ctx.isAt(m_uri, m_name)) {
            ctx.throwStartTagNameError(m_uri, m_name);
        }

        // create new hashmap if needed
        int size = ctx.attributeInt(m_uri, SIZE_ATTRIBUTE_NAME, DEFAULT_SIZE);
        HashMap map = (HashMap)obj;
        if (map == null) {
            map = new HashMap(size);
        }

        // process all entries present in document
        ctx.parsePastStartTag(m_uri, m_name);
        while (ctx.isAt(m_uri, ENTRY_ELEMENT_NAME)) {
            Object key = ctx.attributeText(m_uri, KEY_ATTRIBUTE_NAME, null);
            ctx.parsePastStartTag(m_uri, ENTRY_ELEMENT_NAME);
            Object value = ctx.unmarshalElement();
            map.put(key, value);
            ctx.parsePastEndTag(m_uri, ENTRY_ELEMENT_NAME);
        }
        ctx.parsePastEndTag(m_uri, m_name);
        return map;
    }
    @Override
    public boolean isExtension(String arg0) {
        return false;
    }

}

再改一下第一步生成的xml文件就好了。
这里写图片描述
至此,常用数据的xml转换就都能进行了。

一些执行类的参数留着以后自己看:
BindingGenerator

BindGen

Compile
各位同仁发现什么问题,可以评论中告诉我,共同学习.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值