xml对象与字符串互换

很多老系统,特别是C++的系统,可能数据结构采用的xml。xml对java来说没有什么,但是C++来说,可能还有个顺序问题,毕竟c++没有那么多通用类库。
2 xstream
先说依赖,我本来不想升级,但是有个问题卡者就给升了,虽然升了并没有解决我的问题。

     
        <dependency>
            <groupId>com.thoughtworks.xstreamgroupId>
            <artifactId>xstreamartifactId>
            <version>1.4.20version>
        dependency>
        <dependency>
            <groupId>xmlpullgroupId>
            <artifactId>xmlpullartifactId>
            <version>1.1.3.4d_b4_minversion>
        dependency>
        <dependency>
            <groupId>xpp3groupId>
            <artifactId>xpp3_minartifactId>
            <version>1.1.4cversion>
        dependency>

2.1 双下划线问题
看下面注释

    public static String toXml(Object obj) {
//        XStream xstream = new XStream(new DomDriver(encoding));
        XStream xstream = new XStream(new Xpp3Driver(new NoNameCoder())); // 解决xml双下划线的问题

        //            XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom来解释
        //            XStream xstream=new XStream(new DomDriver("utf-8")); //指定编码解析器,直接用jaxp dom来解释
        //如果没有这句,xml中的根元素会是<包.类名>;或者说:注解根本就没生效,所以的元素名就是类的属性
        xstream.processAnnotations(obj.getClass()); //通过注解方式的,一定要有这句话
        return xstream.toXML(obj);
    }

2.2 复杂对象转换的问题
一般的复杂结构还不会有问题,但是老式的默认却不行,很奇怪。
跟踪代码调试,发现有一个被解释为String类型了
xml对象与字符串互换_第1张图片
看看我的结构
第一层


@Data
@XStreamAlias("business")
public class ReqInvoiceIssue026Bean extends BusinessBean implements RequestBean {

	/**
	 *
	 */
	private static final long serialVersionUID = 279889115759202804L;

	@XStreamAlias("REQUEST_COMMON_FPKJ")
	private ReqInvoiceIssueBody026Bean body;

第二层

@Data
@XStreamAlias("REQUEST_COMMON_FPKJ")
public class ReqInvoiceIssueBody026Bean implements Serializable {

	/**
	 *
	 */
	private static final long serialVersionUID = 7806868114280462342L;

	@XStreamAlias("class")
	@XStreamAsAttribute
	private String cls = "REQUEST_COMMON_FPKJ";


	@XStreamAlias("COMMON_FPKJ_FPT")
	private ReqInvoiceIssueFyxm026Bean fyxm;

	@XStreamAlias("COMMON_FPKJ_XMXXS")
	private ReqInvoiceIssueFyxmGroup026Bean xmxxs;
}

第三层,到了第三层的时候,解析失败。

@Data
@XStreamAlias("COMMON_FPKJ_XMXXS")
public class ReqInvoiceIssueFyxmGroup026Bean implements Serializable {

    @XStreamAlias("class")
    @XStreamAsAttribute
    private String cls = "COMMON_FPKJ_XMXX";
    @XStreamAsAttribute
    private Integer size;
    @XStreamImplicit(itemFieldName = "COMMON_FPKJ_XMXX")
    private List<ReqInvoiceIssueFyxmGroupXmxx026Bean> xmxx;

第四层

@Data
public class ReqInvoiceIssueFyxmGroupXmxx026Bean implements Serializable {

异常信息如下:


com.thoughtworks.xstream.converters.ConversionException: 
---- Debugging information ----
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : COMMON_FPKJ_XMXX
class               : com.whty.einv.sks.model.params.req.body.ReqInvoiceIssueBody026Bean
required-type       : com.whty.einv.sks.model.params.req.body.ReqInvoiceIssueBody026Bean
converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path                : /business/REQUEST_COMMON_FPKJ/COMMON_FPKJ_XMXXS
line number         : 32
class[1]            : com.whty.einv.sks.model.params.req.business.ReqInvoiceIssue026Bean
required-type[1]    : com.whty.einv.sks.model.params.req.business.ReqInvoiceIssue026Bean
version             : 1.4.20
-------------------------------

	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:81)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:68)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:499)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:425)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:74)
	at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:68)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:52)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:136)
	at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1464)
	at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1441)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1321)
	at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1312)
	at com.whty.einv.sks.model.util.XmlUtil.toBean(XmlUtil.java:53)
	at com.whty.einv.sks.model.test.TestJavaToXml.toBean(TestJavaToXml.java:108)
	at com.whty.einv.sks.model.test.TestJavaToXml.test10_026(TestJavaToXml.java:86)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: com.thoughtworks.xstream.mapper.CannotResolveClassException: COMMON_FPKJ_XMXX
	at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:81)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71)
	at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:125)
	at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:420)
	at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
	at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:74)
	... 40 more


Process finished with exit code -1

.1 jibx实现
先看依赖,使用这个技术比较麻烦一点,就是再打包的时候要执行mvn jibx:bind

  <dependency>
            <groupId>org.jibxgroupId>
            <artifactId>jibx-runartifactId>
            <version>1.3.1version>
        dependency>
        <dependency>
            <groupId>org.jibxgroupId>
            <artifactId>jibx-extrasartifactId>
            <version>1.3.1version>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.jibxgroupId>
            <artifactId>jibx-toolsartifactId>
            <version>1.3.1version>
            <scope>testscope>
        dependency>

再看打包

<build>
        <plugins>
            
            <plugin>
                <artifactId>maven-source-pluginartifactId>
                <version>2.1version>
                <configuration>
                    <attach>trueattach>
                configuration>
                <executions>
                    <execution>
                        <phase>compilephase>
                        <goals>
                            <goal>jargoal>
                        goals>
                    execution>
                executions>
            plugin>
            <plugin>
                <groupId>org.jibxgroupId>
                <artifactId>jibx-maven-pluginartifactId>
                <version>1.3.1version>
                <configuration>
                    <schemaBindingDirectory>src/main/resourcesschemaBindingDirectory>
                    <includeSchemaBindings>
                        
                        
                        <includeSchemaBindings>binding/request/*-binding.xmlincludeSchemaBindings>
                        <includeSchemaBindings>binding/response/*-binding.xmlincludeSchemaBindings>
                    includeSchemaBindings>
                    <verbose>trueverbose>
                configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>bindgoal>
                        goals>
                    execution>
                executions>
            plugin>
        plugins>
        <resources>
            <resource>
                <directory>src/main/javadirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
            <resource>
                <directory>src/main/resourcesdirectory>
                <includes>
                    <include>**/*.propertiesinclude>
                    <include>**/*.xmlinclude>
                includes>
                <filtering>falsefiltering>
            resource>
        resources>
    build>

使用如下

	/**
	 * obj转xml
	 *
	 * @param obj
	 * @param indent 格式化缩进
	 * @return String
	 * @throws JiBXException
	 */
	public static String toXml(Object obj, int indent) throws JiBXException {
		IBindingFactory bfact = BindingDirectory.getFactory(obj.getClass());
		IMarshallingContext mctx = bfact.createMarshallingContext();
		mctx.setIndent(indent);

		StringWriter writer = new StringWriter();
		mctx.marshalDocument(obj, encoding, null, writer);
		return writer.toString();
	}

	/**
	 * xml转obj
	 *
	 * @param xml
	 * @param clazz
	 * @return
	 * @throws JiBXException
	 */
	public static <T> T fromXml(String xml, Class<T> clazz) throws JiBXException {
		IBindingFactory bfact = BindingDirectory.getFactory(clazz);
		IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
		Object obj = uctx.unmarshalDocument(new StringReader(xml), null);
		return clazz.cast(obj);
	}

你可能感兴趣的:(岁月云——Web系统最佳实践,xml,xstream,jibx)