Я использую библиотеку, которая генерирует код на основе определений IDL. Его отличная возможность использовать общие перечисления на разных языках (Java, C и C++), но эти сгенерированные перечисления, похоже, не хорошо работают с JAX-WS.JAX-WS, @XmlJavaTypeAdapter и пользовательское перечисление
В принципе, главный класс enum 'super' состоит из двух членов: порядковый номер и имя. Он похож на это (Примечание: это в библиотеке третьей стороной и не JavaBean дружественных):
public class CustomEnum {
int _ordinal;
String _name;
public CustomEnum(int ordinal, String name) {
this._ordinal = ordinal;
this._name = name;
}
public int ordinal() {
return _ordinal;
}
public String name() {
return _name;
}
}
Итак, в сгенерированном коде на основе определения IDL выглядит примерно так (используя день в качестве примера - но на самом деле у меня есть около 50 «перечислений», которые расширяют CustomEnum, поэтому я бы хотел, чтобы решение не позволяло мне иметь несколько копий переписей, например, сгенерированный тип IDL и java.lang.enum):
public class Day extends CustomEnum {
public static final Day Sunday = new Day(0, "Sunday");
public static final Day Monday = new Day(1, "Monday");
public static final Day Tuesday = new Day(2, "Tuesday");
public static final Day Wednesday = new Day(3, "Wednesday");
public static final Day Thursday = new Day(4, "Thursday");
public static final Day Friday = new Day(5, "Friday");
public static final Day Saturday = new Day(6, "Saturday");
public Day(int ordinal, String name) {
super(ordinal, name);
}
}
Обратите внимание, что я также не хочу вмешиваться/переставлять/комментировать этот класс либо с момента создания кода.
Итак, теперь я хочу использовать этот «день» в качестве @WebParam в JAX-WS @WebMethod. Вот очень простой пример того, что я хочу быть в состоянии сделать:
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@WebService
public class EnumEndpoint {
@WebMethod
public boolean callEndpoint(
@XmlJavaTypeAdapter(CustomEnumAdapter.class) Day day) {
System.out.println(day.ordinal() + " " + day.name());
return false;
}
}
Я надеялся, что, написав XmlJavaTypeAdapter так:
import java.lang.reflect.Type;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class CustomEnumAdapter extends XmlAdapter<CustomEnum, EnumBean>
implements Type {
@Override
public EnumBean unmarshal(CustomEnum v) throws Exception {
EnumBean mine = new EnumBean(v.ordinal(), v.name());
return mine;
}
@Override
public CustomEnum marshal(EnumBean v) throws Exception {
CustomEnum customEnum = new CustomEnum(v.getOrdinal(),v.getName());
return customEnum;
}
}
где EnumBean выглядит следующим образом:
public class EnumBean {
int ordinal;
String name;
public EnumBean(int ordinal, String name) {
this.ordinal = ordinal;
this.name = name;
}
public int getOrdinal() {
return ordinal;
}
public void setOrdinal(int ordinal) {
this.ordinal = ordinal;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
, но когда я объявляю конечную точку сервера следующим образом:
import javax.xml.ws.Endpoint;
public class Server {
/**
* @param args
*/
public static void main(String[] args) {
Endpoint.publish("http://0.0.0.0:7979/enum", new EnumEndpoint());
}
}
Я получаю эту ошибку:
Jun 10, 2012 3:29:21 PM com.sun.xml.internal.ws.model.RuntimeModeler getRequestWrapperClass
INFO: Dynamically creating request wrapper Class test.jaxws.CallEndpoint
Exception in thread "main" javax.xml.ws.WebServiceException: java.lang.IllegalArgumentException: value class test.CustomEnumAdapter
at com.sun.xml.internal.ws.model.WrapperBeanGenerator.createRequestWrapperBean(WrapperBeanGenerator.java:249)
at com.sun.xml.internal.ws.model.RuntimeModeler.getRequestWrapperClass(RuntimeModeler.java:280)
at com.sun.xml.internal.ws.model.RuntimeModeler.processDocWrappedMethod(RuntimeModeler.java:674)
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 test.Server.main(Server.java:11)
Caused by: java.lang.IllegalArgumentException: value class test.CustomEnumAdapter
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.createRequestWrapperBean(WrapperBeanGenerator.java:245)
... 14 more
Что я здесь отсутствует? Я попытался использовать «День» напрямую, но поскольку он не имеет конструктора по умолчанию и не получает/устанавливает дружественный, это тоже не работает. Какие-нибудь советы?
мой ответ (http://stackoverflow.com/a/11090763/383861) вдоль линий, что вы ищете? Если не сообщите мне, я могу помочь дальше. Я лидер EclipseLink JAXB (MOXy), поэтому надеюсь, что смогу помочь вам найти решение, которое будет работать. –
Прошу прощения, я отсутствовал со своего стола последние 2 дня. Сегодня вечером я присмотрюсь к вашему решению. Большое спасибо! – systemoutprintln