JAXB XmlJavaTypeAdapter не вызывается, когда Marshalling Object для типа Enum - PullRequest
1 голос
/ 21 марта 2011

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

Альтернативное решение также будет полезно.

1 Ответ

0 голосов
/ 01 июля 2011

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

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

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

...