java – XmlAdapter到JAXB绑定Joda时间间隔?
在我的JAXB绑定中遇到Web服务问题我已经被困了几个小时:
为了准备一个必须返回Joda Time类实例(即时,持续时间,间隔等)的更大的Web服务,我开始使用只有一个返回Interval的方法的Web服务: package jodaws; import javax.jws.WebService; import javax.xml.ws.Endpoint; import org.joda.time.Interval; @WebService(name = "JodaWS") public class JodaWebService { public Interval readInterval() { return new Interval(30,40); } public static void main(String[] args) { Endpoint.publish("http://localhost:10100/JodaWS",new JodaWebService()); } } 发布此Web服务我收到一个异常,指出“org.joda.time.Interval没有no-arg默认构造函数”: 29.05.2011 17:24:07 com.sun.xml.internal.ws.model.RuntimeModeler getRequestWrapperClass INFO: Dynamically creating request wrapper Class jodaws.jaxws.ReadInterval 29.05.2011 17:24:07 com.sun.xml.internal.ws.model.RuntimeModeler getResponseWrapperClass INFO: Dynamically creating response wrapper bean Class jodaws.jaxws.ReadIntervalResponse Exception in thread "main" javax.xml.ws.WebServiceException: Unable to create JAXBContext at com.sun.xml.internal.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:153) at com.sun.xml.internal.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:83) at com.sun.xml.internal.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:244) at com.sun.xml.internal.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:312) at com.sun.xml.internal.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:178) at com.sun.xml.internal.ws.api.server.WSEndpoint.create(WSEndpoint.java:456) at com.sun.xml.internal.ws.api.server.WSEndpoint.create(WSEndpoint.java:475) at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:213) at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:143) at com.sun.xml.internal.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:102) at javax.xml.ws.Endpoint.publish(Endpoint.java:170) at jodaws.JodaWebService.main(JodaWebService.java:17) Caused by: java.security.PrivilegedActionException: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions org.joda.time.Interval does not have a no-arg default constructor. this problem is related to the following location: at org.joda.time.Interval at public org.joda.time.Interval jodaws.jaxws.ReadIntervalResponse._return at jodaws.jaxws.ReadIntervalResponse org.joda.time.base.BaseInterval does not have a no-arg default constructor. this problem is related to the following location: at org.joda.time.base.BaseInterval at org.joda.time.Interval at public org.joda.time.Interval jodaws.jaxws.ReadIntervalResponse._return at jodaws.jaxws.ReadIntervalResponse at java.security.AccessController.doPrivileged(Native Method) at com.sun.xml.internal.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:140) ... 11 more Caused by: com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions org.joda.time.Interval does not have a no-arg default constructor. this problem is related to the following location: at org.joda.time.Interval at public org.joda.time.Interval jodaws.jaxws.ReadIntervalResponse._return at jodaws.jaxws.ReadIntervalResponse org.joda.time.base.BaseInterval does not have a no-arg default constructor. this problem is related to the following location: at org.joda.time.base.BaseInterval at org.joda.time.Interval at public org.joda.time.Interval jodaws.jaxws.ReadIntervalResponse._return at jodaws.jaxws.ReadIntervalResponse at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277) at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100) at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143) at com.sun.xml.internal.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:95) at com.sun.xml.internal.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.java:97) at com.sun.xml.internal.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:148) at com.sun.xml.internal.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:140) ... 13 more 所以我已经阅读了几个教程等,最后为Interval类编写了我自己的XmlAdapter – 第一个实现返回有效但是常量值: package jodaws; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.Interval; public class IntervalAdapter extends XmlAdapter<String,Interval> { @Override public Interval unmarshal(String v) throws Exception { return new Interval(10,20); } @Override public String marshal(Interval v) throws Exception { return "10-20"; } } 另外我已经注释了我的web方法来使用适配器: package jodaws; import javax.jws.WebService; // import added import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.ws.Endpoint; import org.joda.time.Interval; @WebService(name = "JodaWS") public class JodaWebService { // annotation added @XmlJavaTypeAdapter(IntervalAdapter.class) public Interval readInterval() { return new Interval(30,new JodaWebService()); } } 现在它应该工作.但是,当我再次启动Web服务时,我仍然会收到一个例外,尽管是另一个例外: 29.05.2011 17:27:33 com.sun.xml.internal.ws.model.RuntimeModeler getRequestWrapperClass INFO: Dynamically creating request wrapper Class jodaws.jaxws.ReadInterval 29.05.2011 17:27:34 com.sun.xml.internal.ws.model.RuntimeModeler getResponseWrapperClass INFO: Dynamically creating response wrapper bean Class jodaws.jaxws.ReadIntervalResponse Exception in thread "main" javax.xml.ws.WebServiceException: java.lang.IllegalArgumentException: value class jodaws.IntervalAdapter at com.sun.xml.internal.ws.model.WrapperBeanGenerator.createResponseWrapperBean(WrapperBeanGenerator.java:269) at com.sun.xml.internal.ws.model.RuntimeModeler.getResponseWrapperClass(RuntimeModeler.java:293) at com.sun.xml.internal.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:688) at com.sun.xml.internal.ws.model.RuntimeModeler.processMethod(RuntimeModeler.java:612) at com.sun.xml.internal.ws.model.RuntimeModeler.processClass(RuntimeModeler.java:401) at com.sun.xml.internal.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:240) at com.sun.xml.internal.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:312) at com.sun.xml.internal.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:178) at com.sun.xml.internal.ws.api.server.WSEndpoint.create(WSEndpoint.java:456) at com.sun.xml.internal.ws.api.server.WSEndpoint.create(WSEndpoint.java:475) at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:213) at com.sun.xml.internal.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:143) at com.sun.xml.internal.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:102) at javax.xml.ws.Endpoint.publish(Endpoint.java:170) at jodaws.JodaWebService.main(JodaWebService.java:18) Caused by: java.lang.IllegalArgumentException: value class jodaws.IntervalAdapter at com.sun.xml.internal.ws.org.objectweb.asm.ClassWriter.newConstItem(ClassWriter.java:893) at com.sun.xml.internal.ws.org.objectweb.asm.AnnotationWriter.visit(AnnotationWriter.java:185) at com.sun.xml.internal.ws.model.WrapperBeanGenerator.createBeanImage(WrapperBeanGenerator.java:111) at com.sun.xml.internal.ws.model.WrapperBeanGenerator.createResponseWrapperBean(WrapperBeanGenerator.java:265) ... 14 more 那就是我被困住的地方.我究竟做错了什么? 解决方法
你是正确的,你需要在这个用例中使用
XmlAdapter .以下是如何完成的示例:
IntervalStringAdapter 下面的适配器将以格式start-end的形式将Interval实例转换为Strings. package blog.joda; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.joda.time.Interval; public class IntervalStringAdapter extends XmlAdapter<String,Interval>{ @Override public Interval unmarshal(String v) throws Exception { int dashIndex = v.indexOf('-'); long start = Long.valueOf(v.substring(0,dashIndex)); long end = Long.valueOf(v.substring(dashIndex + 1)); return new Interval(start,end); } @Override public String marshal(Interval v) throws Exception { return v.getStartMillis() + "-" + v.getEndMillis(); } } 根 下面是如何配置属性以使用适配器的示例: package blog.joda; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.joda.time.Interval; @XmlRootElement public class Root { private Interval interval; @XmlJavaTypeAdapter(IntervalStringAdapter.class) public Interval getInterval() { return interval; } public void setInterval(Interval interval) { this.interval = interval; } } 演示 package blog.joda; import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); Root root = (Root) unmarshaller.unmarshal(new File("src/blog/joda/input.xml")); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true); marshaller.marshal(root,System.out); } } input.xml中 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <interval>10-20</interval> </root> 欲获得更多信息 > http://bdoughan.blogspot.com/2011/05/jaxb-and-joda-time-dates-and-times.html (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Java中的多个类和main方法,以及包,命名空间
- Java concurrency之公平锁(一)_动力节点Java学院整理
- Java 中组合模型之对象结构模式的详解
- java.sql.SQLException:无法加载类:com.mysql.jdbc.Drive
- Hibernate commit方法:提交事务
- java – 与构造函数和子类混淆
- java – 每个’容器’类一个DAO或每个表一个DAO?
- 如何将按钮的文本调整为按钮的大小 – Java的Swing
- java-允许Servlet和客户端脚本读取同一文件的最佳方法是什么
- java – 在Android上执行JUnit测试的CalledFromWrongThread