2011-05-18 5 views
5

Tengo un servicio web creado en Java (1.6), con metro (2.0), usando maven, bajo Tomcat 6. En todos los métodos web, el tipo de devolución es genérico clase:Unmarshal genera un campo nulo genérico con un campo de lista <T>

public class WsResult<T> { 
    protected T result;   // the actual result 
    protected Code requestState; // 0K, or some error code if needed 
    protected String message; // if error, instead of result, insert a message 
} 

Por ejemplo:

public WsResult<OtherClass> someMethod(...); 
public WsResult<Foo> someMethod_2(...); 

Y en el cliente:

MyServiceService service = new MyServiceService(); 
MyService port = service.getMyServicePort(); 

WsResult result = port.someMethod(...); 
OtherClass oc = (OtherClass) result.getResult(); 

WsResult res = port.someMethod_2(...); 
Foo o = (Foo) res.getResult(); 

En algunos métodos web está funcionando. Pero cuando el resultado es una clase con un atributo List<? class>, no se puede eliminar.

Este proyecto es uno de los más grandes. Entonces, para fines de prueba, creé uno nuevo, más simple, solo el proyecto, con el mismo modelo de datos, y copié uno de los métodos web, en este caso funcionó, y después del desempate, obtuve un resultado que podría enviar al tipo esperado

¿Qué podría estar pasando?

EDIT:

La respuesta es una solución que sí, pero genera un captador para cada tipo de agregado a la declaración del campo. ¿Hay una manera mejor?

+1

¿Se pueden publicar los fragmentos relacionados del proyecto de prueba? –

+0

Disculpe por solo comentar ahora, pero estoy muy ocupado. Editó la publicación, con el ejemplo de uso. –

Respuesta

3

No estoy muy seguro si entiendo completamente su problema, pero a mí me parece que espera demasiado de JAXB aquí. Su WsResult es genérico en el parámetro no restringido T, lo que significa que en el tiempo de ejecución no queda nada más que una referencia Object para que JAXB juegue.

Lo que JAXB realmente necesita para hacer frente a una situación de este tipo es, en términos generales, una pista sobre qué clase instanciar para llenar el campo result. Para llenar este en el que o bien debe

  • crear subclases concretas de WsResult (como, después de su ejemplo, class OtherClassResult extends WsResult<OtherClass> - cuando se lanza el OtherClassResult en JAXB, que sabrán que result necesita ser una instancia de OtherClass y tiene la oportunidad de actuar en consecuencia o
  • Anotar el campo result con @XmlElements, así:
@XmlElements({ 
    @XmlElement(name = "text", type = String.class), // add more elems here 
    @XmlElement(name = "other", type = OtherClass.class)}) 
protected Object result; 
+0

Para que funcione, estoy usando subclases concretas de WsResult, pero me gustaría cambiarlo a un genérico. No entendí la segunda opción, ¿qué campo de resultados? No tengo campos ¿La variable del cliente o la variable del cuerpo del método web? –

+0

Así que supongo que tendrías que ir con la opción 2 (o alguna otra opción que no conozco). – Waldheinz

+0

Quise decir el 'resultado T protegido 'en' WsResult', esto debería obtener las anotaciones. Están disponibles en tiempo de ejecución para que JAXB pueda decidir qué hacer. – Waldheinz

Cuestiones relacionadas