Я конвертирую свое веб-приложение в веб-сервисы, используя CXF.В моем веб-приложении есть классы, созданные для работы с enum.Пример:
package test.javabean;
import java.util.HashMap;
import java.util.Map;
public class GlassType {
private static Map<String, GlassType> glasses = new HashMap<String, GlassType>();
private final String id;
private final String desc;
private GlassType(String id, String desc) {
this.id = id;
this.desc = desc;
glasses.put(id, this);
}
public static final GlassType RED = new GlassType("R", "Bloody Red");
public static final GlassType BLACK = new GlassType("B", "Pitch Black");
public static final GlassType WHITE = new GlassType("W", "Blind White");
public static GlassType valueOf(final String id) {
return glasses.get(id);
}
public String getDesc() {
return desc;
}
public String getId() {
return id;
}
}
Поскольку я не хочу менять свой класс GlasssType на тип enum, я создал адаптер, чтобы этот класс отображался как enum в WSDL.Класс адаптера:
package test.adapters;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import test.javabean.GlassType;
public class GlassTypeEnumAdapter extends XmlAdapter<GlassEnum, GlassType> {
@Override
public GlassEnum marshal(GlassType arg0) throws Exception {
System.out.println("MARSHALLING");
return GlassEnum.valueOf(arg0.getId());
}
@Override
public GlassType unmarshal(GlassEnum arg0) throws Exception {
System.out.println("UNMARSHALLING");
return GlassType.valueOf(arg0.getId());
}
}
Адаптер сопоставлен с классом GlassType с использованием XmlJavaTypeAdapter, упомянутого в package-info.java:
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters( {
@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(
value = test.adapters.GlassTypeEnumAdapter.class,
type = test.javabean.GlassType.class) })
package test.javabean;
Класс GlassEnum:
package test.adapters;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlType;
@XmlEnum(String.class)
@XmlType(name = "myEnum")
public enum GlassEnum {
RED("R"), BLACK("B"), WHITE("W");
private final String id;
private GlassEnum(String id) {
this.id = id;
}
private GlassEnum() {
this.id = "RED";
}
public String getId() {
return id;
}
}
WSDL, сгенерированный с правильным type = "myEnum", где бы я ни использовал GlassType.
ПРОБЛЕМА:
Когда клиент моей веб-службы отправляет значение для GlassType, адаптер вызывается в Marshall myEnum дляGlassType.НО, когда мой веб-сервис отвечает обратно клиенту с GlassType, выдается следующая ошибка:
[3/03/11 20: 43: 48: 078 CDT] 00000023 PhaseIntercep W org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging Перехватчик для {http://webservices.test/}TestWebServiceImplService#{http://webservices.test/}getTestResult выдал исключение, разматывая сейчас org.apache.cxf.interceptor.Fault: Marshalling Error: класс test.javabean.GlassType, ни один из его суперклассов не известен этому контексту.в org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall (JAXBEncoderDecoder.java:256) в org.apache.cxf.jaxb.io.DataWriterImpl.write (DataWriterImpl.java:16interor.Affor.Affor.Affor.org или forceptor)..writeParts (AbstractOutDatabindingInterceptor.java:110) в org.apache.cxf.interceptor.BareOutInterceptor.handleMessage (BareOutInterceptor.java:68) в org.apache.cxf.phase.PhaseInterceptorChain.inInterorChain.inInteror (org.inInceptorapache.cxf.interceptor.OutgoingChainInterceptor.handleMessage (OutgoingChainInterceptor.java:77) в org.apache.cxf.phase.PhaseInterceptorChain.doIntercept (PhaseInterceptorChain.java:255. транспортный сервер.Java: 113) в org.apache.cxf.transport.servlet.ServletDestination.invoke (ServletDestination.java:97) в org.apache.cxf.transport.servlet.ServletController.invokeDestination (ServletController.java:461 at или.cxf.transport.servlet.ServletController.invoke (ServletController.java:188) в org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke (AbstractCXFServlet.java:148) в org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest (AbstractHT): orgTG.apache.cxf.(AbstractHTTPServlet.java:159) на com.ibm.ws.webcontainer.servlet.ServletWrapper.service (ServletWrapper.java:1143) на com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest (ServletWrapper.j) atjcom.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest (ServletWrapper.java:481) в com.ibm.ws.webcontainer.webapp.WebApp.handleRequest (WebApp.java:3453) в com.ibm.ws.wecontainwebapp.WebGroup.handleRequest (WebGroup.java:267) по адресу com.ibm.ws.webcontainer.WebContainer.handleRequest (WebContainer.java:815) по адресу com.ibm.ws.wswebcontainer.WebContainer.handleЗапрос (WebContainer.java:1466) на com.ibm.ws.webcontainer.channel.WCChannelLink.ready (WCChannelLink.java:119) на com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination (HttpInboundLink.Java: 458) на com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation (HttpInboundLink.java:387) на com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready (HttpInboundLink.Java: 267) в com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators (NewConnectionInitialReadCallback.java:214)на com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete (NewConnectionInitialReadCallback.java:113)
на com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted (AioReadCompletionListener.java:165)
на com.ibm.io.async.AbstractAsyncFuture.invokeCallback (AbstractAsyncFuture.java:217)
на com.ibm.io.async.AsyncChannelFuture.fireCompletionActions (AsyncChannelFuture.java:161)
на com.ibm.io.async.AsyncFuture.completed (AsyncFuture.java:136)
на com.ibm.io.async.ResultHandler.complete (ResultHandler.java:196)
в com.ibm.io.async.ResultHandler.runEventProcessingLoop (ResultHandler.java:751)
на com.ibm.io.async.ResultHandler $ 2.run (ResultHandler.java:881)
на com.ibm.ws.util.ThreadPool $ Worker.run (ThreadPool.java:1473)
Вызывается: javax.xml.bind.MarshalException
- со связанным исключением:
[javax.xml.bind.JAXBException: класс test.javabean.GlassType, ни любой из его суперкласса не известен в этом контексте.]
в com.sun.xml.bind.v2.runtime.MarshallerImpl.write (MarshallerImpl.java:318)
на com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal (MarshallerImpl.java:244)
в javax.xml.bind.helpers.AbstractMarshallerImpl.marshal (AbstractMarshallerImpl.java:74)
в org.apache.cxf.jaxb.JAXBEncoderDecoder.writeObject (JAXBEncoderDecoder.java:540)
в org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall (JAXBEncoderDecoder.java:231)
... еще 36
Вызывается: javax.xml.bind.JAXBException: class test.javabean.GlassType, и ни один из его суперкласса не известен этому контексту.
в com.sun.xml.bind.v2.runtime.XMLSerializer.reportError (XMLSerializer.java:246)
в com.sun.xml.bind.v2.runtime.XMLSerializer.reportError (XMLSerializer.java:261)
в com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType (XMLSerializer.java:653)
в com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody (SingleElementLeafProperty.java:115)
в com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody (ClassBeanInfoImpl.java:340)
в com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType (XMLSerializer.java:696)
в com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody (SingleElementNodeProperty.java:152)
в com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody (ClassBeanInfoImpl.java:340)
в com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType (XMLSerializer.java:696)
в com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl $ 1.serializeBody (ElementBeanInfoImpl.java:152)
в com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl $ 1.serializeBody (ElementBeanInfoImpl.java:189)
в com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody (ElementBeanInfoImpl.java:316)
в com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot (ElementBeanInfoImpl.java:323)
в com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot (ElementBeanInfoImpl.java:72)
в com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot (XMLSerializer.java:494)
в com.sun.xml.bind.v2.runtime.MarshallerImpl.write (MarshallerImpl.java:315)
... еще 40
Вызывается: javax.xml.bind.JAXBException: class test.javabean.GlassType, и ни один из его суперкласса не известен этому контексту.
в com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo (JAXBContextImpl.java:594)
в com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType (XMLSerializer.java:648)
... еще 53
Я провел несколько тестов и заметил, что класс адаптера не вызывается для Unmarshalling GlassType. Я что-то здесь упускаю?
Альтернативное решение также будет полезно.