Problemas com recursividade em Web Service

5 respostas
andre_a_s

Senhores 8)

Estou com um problema chato aqui.
Tenho uma estrutura de objeto que funciona perfeitamente no meu sistema de cadastro de propostas.
Implementei um web service que pega uma proposta qualquer baseado em seu id.
O problema é que muitos objetos tem obetos recursivos.
Por exemplo:
Proposta tem DocumentoNecessario e DocumentoNecessario tem o objeto Proposta.
Tenho o seguinte código:

Proposta proposta = new Proposta();
Set documentos = new HashSet();
DocumentoNecessario documentoNecessario = new DocumentoNecessario();
documentoNecessario.setEntregue("S");
documentoNecessario.setProposta(proposta);

documentos.add(documentoNecessario);
proposta.setDocumentosNecessarios(documentos);

return proposta;

Quando meu web service tenta pegar essa proposta, recebo o seguinte erro:

Jul 31, 2007 9:40:50 AM org.codehaus.xfire.jaxb2.JaxbType readObject
SEVERE: com.ctc.wstx.exc.WstxEOFException: Unexpected end of input block; expected an identifier
 at [row,col {unknown-source}]: [1,527472]
Exception in thread "main" org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: Could not unmarshall type : Unexpected end of input block; expected an identifier
 at [row,col {unknown-source}]: [1,527472]
org.codehaus.xfire.fault.XFireFault: Could not unmarshall type : Unexpected end of input block; expected an identifier
 at [row,col {unknown-source}]: [1,527472]
	at org.codehaus.xfire.jaxb2.JaxbType.readObject(JaxbType.java:219)
	at org.codehaus.xfire.aegis.AegisBindingProvider.readParameter(AegisBindingProvider.java:169)
	at org.codehaus.xfire.service.binding.AbstractBinding.read(AbstractBinding.java:206)
	at org.codehaus.xfire.service.binding.DocumentBinding.readMessage(DocumentBinding.java:35)
	at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)
	at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
	at org.codehaus.xfire.client.Client.onReceive(Client.java:406)
	at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:139)
	at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:48)
	at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
	at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
	at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:79)
	at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:114)
	at org.codehaus.xfire.client.Client.invoke(Client.java:336)
	at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
	at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
	at $Proxy12.obterProposta(Unknown Source)
	at com.rural.webservices.PropostaServiceClient.main(PropostaServiceClient.java:98)
Caused by: com.ctc.wstx.exc.WstxEOFException: Unexpected end of input block; expected an identifier
 at [row,col {unknown-source}]: [1,527472]
	at com.ctc.wstx.sr.StreamScanner.throwUnexpectedEOB(StreamScanner.java:675)
	at com.ctc.wstx.sr.StreamScanner.loadMoreFromCurrent(StreamScanner.java:1029)
	at com.ctc.wstx.sr.StreamScanner.getNextCharFromCurrent(StreamScanner.java:786)
	at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2913)
	at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2846)
	at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1019)
	at org.codehaus.xfire.util.stax.DepthXMLStreamReader.next(DepthXMLStreamReader.java:252)
	at org.codehaus.xfire.util.stax.DepthXMLStreamReader.next(DepthXMLStreamReader.java:252)
	at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:151)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:337)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:316)
	at org.codehaus.xfire.jaxb2.JaxbType.readObject(JaxbType.java:201)
	... 17 more

Se eu não fizer a associação(documentoNecessario.setProposta(proposta)) ele funciona perfeitamente.

O que posso fazer? Existe algum jeito de falar pro meu web service ignorar esse tipo de recursividade?

5 Respostas

Luca

Olá

Se entendi seu problema, uma alternativa seria criar wrappers mais coesos, isto é, que não possuam os tais elementos que você chamou de recursivos que não precisam ser expostos como web services.

[]s
Luca

andre_a_s

Olá Luca.
Sim, é isso mesmo que você entendeu.
Nesse caso, o problema é que meu objeto “Proposta” vem do Hibernate, e ele já vem com esses tais “objetos recursivos”.
Não encontrei um jeito de ignorar isso pelo Hibernate. A minha estrutura atual de objeto é bem grande, acho que seria inviável fazer isso via Criteria.
Tem alguma sugestão para contornar esse problema com o Hibernate?

Luca

Olá

Então… pode ser que o problema seja outro. Mas para resolver rapidamente pergunto:

É possível você criar um novo objeto contendo os resultados do Hibernate sem a tal recursividade e expor este tal objeto como web service?

[]s
Luca

andre_a_s

Possível é.
Mas dá um trabalho considerável.
Eu teria que criar um novo objeto "Proposta" e popular seus dados com os que vieram do objeto do hibernate tirando a tal da recursividade.
Por exemplo:

Proposta proposta = dao.findById(propostaId); //Essa vem do hibernate
Proposta propostaTemp = new Proposta();

for (DocumentoNecessario documentoNecessario : proposta.getDocumentosNecessarios()) {
	DocumentoNecessario documentoNecessarioTemp = new DocumentoNecessario();
	BeanUtils.copyProperties(documentoNecessarioTemp, documentoNecessario);
	documentoNecessarioTemp.setProposta(null);
	propostaTemp.addDocumentoNecessario(documentoNecessarioTemp);
}


return propostaTemp;

Mas como eu disse, minha estrutura é grande e tenho muita dessas supostas recursividades.
Não é impossivel, mas pra dar manutenção nisso seria caótico!

jeffmor

Estou com o mesmo problema andre_a_s, como vc resolveu isso?
A forma que encontrei foi retornar do meu webservice uma interface DTO(menos objetos recursivos) do meu objeto, na verdade isso não resolve pq precisaria dos objetos recursivos, ou seja, está funcionando mas não da maneira que preciso.

alguém tem alguma dica de como resolver isso? será que o problema é na serialização do objeto?

Criado 31 de julho de 2007
Ultima resposta 17 de out. de 2007
Respostas 5
Participantes 3