JAXB XmlJavaTypeAdapter не вызывается при преобразовании объекта в тип Enum

Я конвертирую свое веб-приложение в веб-службы с помощью CXF. В моем веб-приложении есть классы, которые работают как перечисление. Пример:

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 на тип перечисления, я сделал адаптер, чтобы этот класс отображался как перечисление в 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.

Страница Стандарты для аннотирования служб и типов с помощью JAX-WS и JAXB говорят

Когда мой клиент веб-службы отправляет значение GlassType, адаптер вызывается для Marshall myEnum в GlassType. НО, когда мой веб-сервис отвечает клиенту с помощью GlassType, выдается следующая ошибка:

Я провел несколько тестов и заметил, что класс Adapter не вызывается для Unmarshalling GlassType. Я что-то здесь упустил?

Также было бы полезно альтернативное решение.

ПРОБЛЕМА:


person Ajay    schedule 21.03.2011    source источник
comment
Вы пробовали использовать @XmlJavaTypeAdapter в качестве аннотации уровня параметра для параметра типа GlassType?   -  person bdoughan    schedule 21.03.2011
comment
Да. Он по-прежнему вызывает ту же ошибку. Я также пробовал несколько других комбинаций, таких как адаптер Class-to-String, Enum-to-String. все работает нормально. Методы адаптера marshall и unmarshall вызываются каждый раз. Но то же самое не работает с этой комбинацией адаптера Class-to-Enum.   -  person bdoughan    schedule 26.03.2011
comment
[20.03.11 20: 43: 48: 078 CDT] 00000023 PhaseIntercep W org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging Interceptor для {http: //webservices.test/} TestWebServiceImplService # {http: //webservices.test /} getTestResult сгенерировал исключение, теперь откручивается org.apache.cxf.interceptor.Fault: Ошибка маршаллинга: класс test.javabean.GlassType, и ни один из его суперклассов не известен этому контексту. в org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall (JAXBEncoderDecoder.java:256) в org.apache.cxf.jaxb.io.DataWriterImpl.write (DataWriterImpl.java:169) в org.AncceptorCcept .writeParts (AbstractOutDatabindingInterceptor.java:110) в org.apache.cxf.interceptor.BareOutInterceptor.handleMessage (BareOutInterceptor.java:68) в org.apache.cxf.phase.PhaseInterceptorChain25.Interceptava: или apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage (OutgoingChainInterceptor.java:77) в org.apache.cxf.phase.PhaseInterceptorChain.doIntercept (PhaseInterceptorChain.java.Intercept (PhaseInterceptorChain.java.InterceptorChain.java.InterceptorChain.java.InterceptorChain. java: 113) в org.apache.cxf.transport.servlet.ServletDestination.invoke (ServletDestination.java:97) в org.apache.cxf.transport.servlet.ServletController.invokeDestination (ServletController.java:461) в org.ap ache.cxf.transport.servlet.ServletController.invoke (ServletController.java:188) на org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke (AbstractCXFServlet.java:148) на org.apacheport.cxservf.tra. AbstractHTTPServlet.handleRequest (AbstractHTTPServlet.java:179) на org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost (AbstractHTTPServlet.java:103) на javax.servlet.http.HttpServlet.javaService или на сервере javax.servlet. .apache.cxf.transport.servlet.AbstractHTTPServlet.service (AbstractHTTPServlet.java:159) на com.ibm.ws.webcontainer.servlet.ServletWrapper.service (ServletWrapper.java:1143) на com.ibm.ws.webcontainer.service .ServletWrapper.handleRequest (ServletWrapper.java:591) в com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest (ServletWrapper.java:481) в com.ibm.ws.webcontainer.webapp.RejavaApp.hand : 3453) в com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest (WebGroup.java:267) в com.ibm.ws.webcontainer.WebContainer.handleRequest (WebContainer.java:815) в com.ibm.ws.wswebcontainer. WebContainer.handleRequest (WebContainer.java:1466) по адресу com.ibm.ws.webcontainer.channel.WCChannelLink.ready (WCChannelLink.java:119) по адресу com.ibm.ws.http.channel.inbound.impl.HttpInboundcrim.handle ( 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.channelCallback.java:214) по адресу com.ibm.ws.tcp.channelReadCallback.java:214): 113) на com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted (AioReadCompletionListener.java:165) в com.ibm.io.async.AbstractAsyncFuture.invokeCallback (AbstractAsyncFuture.io17.:2 .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: class 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.JAXBEncoderncoderdecoder.md: 1) ... еще 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.serializeBody (SingleElementLeafProperty) atcom.java: .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.pro serializeBody (SingleElementNodeProperty.java:152) в com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody (ClassBeanInfoImpl.java:340) в com.sun.xml.bind.v2.runtime.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 $ 1.serializeBody. 189) в com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody (ElementBeanInfoImpl.java:316) в com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot (ElementBeanInfoImpl.serializeRoot (ElementBean32) в .sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot (ElementBeanInfoImpl.java:72) в com.sun.xml.bind.v2.runt ime.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 более   -  person Ajay    schedule 27.03.2011


Ответы (1)


Очевидный выбор здесь - адаптер XML. Однако на момент написания этой статьи JAXB, похоже, не мог должным образом обрабатывать адаптеры XML, которые используются в перечислениях (независимо от того, что вы делаете, он по-прежнему использует подход xs: enumeration в сгенерированной схеме). Чтобы обойти это, мы должны рассматривать эти значения как простые строки.

Страница была создана 3 марта 2011 г. и последний раз обновлялась 16 мая 2011 г., поэтому кажется, что использование XmlJavaAdapter с перечислениями в JAXB все еще работает некорректно.

Ваш сервис является сервисом JAX-WS?

person mdma    schedule 01.07.2011