gpt4 book ai didi

java - 将对象编码为枚举类型时不调用 JAXB XmlJavaTypeAdapter

转载 作者:行者123 更新时间:2023-12-01 05:48:12 29 4
gpt4 key购买 nike

我正在使用 CXF 将我的 Web 应用程序转换为 Web 服务。我的 Web 应用程序构建了作为枚举工作的类。示例:

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());
}

}

适配器使用 package-info.java 中提到的 XmlJavaTypeAdapter 与类 GlassType 进行映射:

@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;
}
}

无论我在何处使用 GlassType,WSDL 都会以正确的类型“myEnum”生成。

问题:

当我的 Web 服务客户端发送 GlassType 的值时,适配器将被调用以 Marshall myEnum to GlassType。但是当我的网络服务使用 GlassType 回复客户端时,会抛出以下错误:

[3/20/11 20:43:48:078 CDT] 00000023 PhaseIntercep W org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging Interceptor for {http://webservices.test/}TestWebServiceImplService#{http://webservices.test/}getTestResult has thrown exception, unwinding now org.apache.cxf.interceptor.Fault: Marshalling Error: class test.javabean.GlassType nor any of its super class is known to this context. at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:256) at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:169) at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:110) at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:255) at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:255) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:113) at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:97) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:461) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:188) at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:148) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103) at javax.servlet.http.HttpServlet.service(HttpServlet.java:763) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159) at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1143) at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:591) at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:481) at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3453) at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:267) at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:815) at com.ibm.ws.wswebcontainer.WebContainer.handleRequest(WebContainer.java:1466) at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:119) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:458) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:387) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:267) at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214) at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113) at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165) at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217) at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161) at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:136) at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:196) at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:751) at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881) at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1473) Caused by: javax.xml.bind.MarshalException - with linked exception: [javax.xml.bind.JAXBException: class test.javabean.GlassType nor any of its super class is known to this context.] at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:318) at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244) at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:74) at org.apache.cxf.jaxb.JAXBEncoderDecoder.writeObject(JAXBEncoderDecoder.java:540) at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:231) ... 36 more Caused by: javax.xml.bind.JAXBException: class test.javabean.GlassType nor any of its super class is known to this context. at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:246) at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:261) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:653) at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:115) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:340) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:696) at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:152) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:340) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:696) at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:152) at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:189) at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:316) at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:323) at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:72) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494) at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315) ... 40 more Caused by: javax.xml.bind.JAXBException: class test.javabean.GlassType nor any of its super class is known to this context. at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:594) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:648) ... 53 more

我已经运行了几次测试,并注意到 Adapter 类没有被调用以进行 Unmarshalling GlassType。我在这里遗漏了什么吗?

替代解决方案也会有所帮助。

最佳答案

页面Standards for Annotating Services and Types with JAX-WS and JAXB

The obvious choice here is an XML adapter. However, at the time of this writing JAXB does not appear to properly handle XML adapters that are used on enums (regardless of what you do, it still uses the xs:enumeration approach in the generated schema). So to get around this, we must treat these values as simple strings.

该页面创建于 2011 年 3 月 3 日,最后更新于 2011 年 5 月 16 日,因此在 JAXB 中使用带有枚举的 XmlJavaAdapter 似乎仍然无法正常工作。

关于java - 将对象编码为枚举类型时不调用 JAXB XmlJavaTypeAdapter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5373083/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com