spring-oxm中unmashaller疑似bug

spring-integration中测试XML Transformers的一些代码:

maven:

 

<!-- for spring-oxm -->
	<dependency>
       	<groupId>com.thoughtworks.xstream</groupId>
      	<artifactId>xstream</artifactId>
     	<version>1.3.1</version>
      	<optional>true</optional>
 	</dependency>
 	<dependency>
      	<groupId>com.sun.xml.bind</groupId>
      	<artifactId>jaxb-impl</artifactId>
      	<version>2.1.7</version>
      	<optional>true</optional>
  	</dependency>
  	<dependency>
     	<groupId>org.jibx</groupId>
     	<artifactId>jibx-run</artifactId>
      	<version>1.1.5</version>
     	<optional>true</optional>
 	</dependency>
 	<dependency>
      	<groupId>org.apache.xmlbeans</groupId>
      	<artifactId>xmlbeans</artifactId>
      	<version>2.4.0</version>
      	<optional>true</optional>
  	</dependency>
  	<dependency>
      	<groupId>org.codehaus.castor</groupId>
      	<artifactId>castor-xml</artifactId>
      	<version>1.3.2</version>
     	<optional>true</optional>
     	<exclusions>
     		<exclusion>
     			<groupId>commons-logging</groupId>
     			<artifactId>commons-logging</artifactId>
     		</exclusion>
     	</exclusions>
 	</dependency>
 	
 	<!-- spring-xml -->
 	<dependency>
     	<groupId>org.apache.ws.commons.schema</groupId>
    	<artifactId>XmlSchema</artifactId>
    	<version>1.4.7</version>
     	<optional>true</optional>
 	</dependency>
 	<dependency>
     	<groupId>jaxen</groupId>
      	<artifactId>jaxen</artifactId>
      	<version>1.1.1</version>
      	<!-- 1.1.3 version is not good. -->
      	<optional>true</optional>
 	</dependency>

 Marshaller:

 

@Configuration
public class XmlConfiguration {

    @Bean
    public CastorMarshaller marshaller() {
    	CastorMarshaller marshaller = new CastorMarshaller();
        return marshaller;
    }
}

 报错日志:

 

10:04:43,305  INFO main handler.LoggingHandler:136 - [Payload=<?xml version="1.0" encoding="UTF-8"?>
<customer><address>100 State Street</address><last-name>Smith</last-name><zip>90064</zip><first-name>John</first-name><state>CA</state><city>Los Angeles</city></customer>][Headers={timestamp=1331172283294, id=ed20763b-8061-4207-88d1-688673621b81}]
createUnmarshaller()
Exception in thread "main" org.springframework.integration.transformer.MessageTransformationException: failed to transform message
	at org.springframework.integration.transformer.AbstractTransformer.transform(AbstractTransformer.java:44)
	at org.springframework.integration.transformer.MessageTransformingHandler.handleRequestMessage(MessageTransformingHandler.java:67)
......
Caused by: org.exolab.castor.xml.MarshalException: The class for the root element 'customer' could not be found.{File: [not available]; line: 2; column: 11}
	at org.exolab.castor.xml.Unmarshaller.convertSAXExceptionToMarshalException(Unmarshaller.java:866)
......
Caused by: org.xml.sax.SAXException: The class for the root element 'customer' could not be found.
	at org.exolab.castor.xml.UnmarshalHandler.processFirstElement(UnmarshalHandler.java:890)
...

 可以看出传输的对象已经正确转换成xml,但是将xml转回类的时候说根节点Customer对应的类没找到。

单独编写测试代码:

 

package com.apress.prospringintegration.transform;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.xml.transform.stream.StreamSource;

import org.exolab.castor.xml.Unmarshaller;
import org.xml.sax.InputSource;

public class Test {

	public static void main(String[] args) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
		sb.append("<customer>");
		sb.append("<address>100 State Street</address>");
		sb.append("<last-name>Smith</last-name>");
		sb.append("<zip>90064</zip>");
		sb.append("<first-name>John</first-name>");
		sb.append("<state>CA</state>");
		sb.append("<city>Los Angeles</city>");
		sb.append("</customer>");
		InputStream in = new ByteArrayInputStream(sb.toString().getBytes());
		Unmarshaller u = new Unmarshaller();
		u.setClass(Customer.class);
		Object o = u.unmarshal(new InputSource(in));
		System.out.println(o.getClass());
	}
}

 发现,只有设置了setClass(Clazz)才能正确解析。

spring-oxm中的org.springframework.oxm.castor.CastorMarshaller类封装了org.exolab.castor.xml.Unmarshaller。单很奇怪的是,CastorMarshaller并没有封装Unmarshaller的setClass方法。

怎么回事,bug?

翻了一遍Spring 3以来所有版本的源代码,CastorMarshaller都一样。

但Google这个关键字时,第3个结果第427到430行代码是3.0版本以后没有的!

 

425       private Unmarshaller createUnmarshaller() {
  426           Unmarshaller unmarshaller = xmlContext.createUnmarshaller();
  427           if (targetClass != null) {
  428               unmarshaller.setClass(targetClass);
  429               unmarshaller.setClassLoader(targetClass.getClassLoader());
  430           }
  431           customizeUnmarshaller(unmarshaller);
  432           return unmarshaller;
  433       }
 

有了这一段代码,就可以设置CastorMarshaller的targetClass来指定转换的类。

问题来了,貌似刚才说到的这个类是很早以前版本的,那就是说3.0以后官方把这个类改掉了,是优化了,提供了替代的方法,然后还没发现吗?

 

 

 

[2012.6.24 10:57 补充]

 

将pom.xml的依赖包换成:

 

<dependency>
        <groupId>org.codehaus.castor</groupId>
        <artifactId>castor</artifactId>
        <version>1.2</version>
        <optional>true</optional>
        <scope>test</scope>
</dependency>
<dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        <version>2.9.1</version>
        <optional>true</optional>
        <scope>test</scope>
</dependency>
 

 

你可能感兴趣的:(spring)