Vraptor + Rest + LocalDateTime[RESOLVIDO]

Bom dia!

Eu tenho duas aplicação uma em java desktop e outra em Java Web

e quero fazer um post do meu desktop para a web via Rest do Vraptor.

Objeto que estou fazendo o post (mesmo no web e desktop):

package br.com.coliseu.model;

// Generated 24/08/2012 21:53:13 by Hibernate Tools 3.4.0.CR1

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Type;
import org.joda.time.LocalDateTime;

import com.thoughtworks.xstream.annotations.XStreamAlias;

/**
 * Versaotabelas generated by hbm2java
 */
@Entity
@Table(name = "versaotabelas", schema = "coliseuarena")
@XStreamAlias("versaotabelas")
public class Versaotabelas implements java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3553821381592680404L;
	private long idversaotabelas;
	private Filial filial;
	private String nometb;
	private String descricao;
	private Integer versao;
	private LocalDateTime dttimealter;

	public Versaotabelas() {
	}

	public Versaotabelas(long idversaotabelas) {
		this.idversaotabelas = idversaotabelas;
	}

	public Versaotabelas(long idversaotabelas, Filial filial, String nomeobj,
			String descricao, Integer versao, LocalDateTime dttimealter) {
		this.idversaotabelas = idversaotabelas;
		this.filial = filial;
		this.nometb = nomeobj;
		this.descricao = descricao;
		this.versao = versao;
		this.dttimealter = dttimealter;
	}

	@Id
	@Column(name = "idversaotabelas", unique = true)
	public long getIdversaotabelas() {
		return this.idversaotabelas;
	}

	public void setIdversaotabelas(long idversaotabelas) {
		this.idversaotabelas = idversaotabelas;
	}

	@Column(name = "nomeobj", length = 40)
	public String getNomeobj() {
		return this.nometb;
	}

	public void setNomeobj(String nomeobj) {
		this.nometb = nomeobj;
	}

	@Column(name = "descricao", length = 40)
	public String getDescricao() {
		return this.descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	@Column(name = "versao")
	public Integer getVersao() {
		return this.versao;
	}

	public void setVersao(Integer versao) {
		this.versao = versao;
	}

	@ManyToOne
	@JoinColumn(name = "estab")
	public Filial getFilial() {
		return filial;
	}

	public void setFilial(Filial filial) {
		this.filial = filial;
	}

	@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
	@Column(name = "dttimealter")
	public LocalDateTime getDttimealter() {
		return dttimealter;
	}

	public void setDttimealter(LocalDateTime dttimealter) {
		this.dttimealter = dttimealter;
	}

}

Parte do java desktop (ele chama apliacação web e tal mas quando vai deserializar o objeto da pau)


 restfulie = Restfulie.custom();
        restfulie.getMediaTypes().register(new XmlMediaType().withTypes(Grupo.class, Produto.class, Item.class, Versaotabelas.class));

   ....

  VersaoTabelasTemp.versaoItem = respositoryVersaotabelas.dateItem(2);
        //pego a data
       LocalDateTime date = VersaoTabelasTemp.versaoItem;
     
        Versaotabelas versaotabelas = new Versaotabelas();
        versaotabelas.setDttimealter(date);

        Response response = restfulie.at("http://localhost:8080/CP/comunicador/atualizaItem").accept("application/xml").as("application/xml").post(versaotabelas);

Apl web:

	@Post
	@Path("atualizaItem")
	@Consumes
	public void atualizaItem(Versaotabelas versaotabelas) {
		try {
			sessionUser.setEstab(2);
			List<Item> itemProduto = repositoryItem.atualizaItem(versaotabelas.getDttimealter());

...

CustomXStreamXMLDeserializer (Aqui que esta dando o erro)

package br.com.coliseu.util;

import br.com.caelum.vraptor.deserialization.XStreamXMLDeserializer;
import br.com.caelum.vraptor.http.ParameterNameProvider;
import br.com.caelum.vraptor.ioc.ApplicationScoped;
import br.com.caelum.vraptor.ioc.Component;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
@ApplicationScoped
@Component
public class CustomXStreamXMLDeserializer extends XStreamXMLDeserializer {

	public CustomXStreamXMLDeserializer(ParameterNameProvider provider) {
		super(provider, null);
	}

	/**
	 * Extension point to configure your xstream instance.
	 * @return the configured xstream instance
	 */
	@Override
	protected XStream getXStream() {
		XStream xStream = new XStream(new DomDriver());
		xStream.alias("versaotabelas", br.com.coliseu.model.Versaotabelas.class);
		return xStream;
	}


}

Erro:


11:14:26,118 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/CP].[default]] (http--127.0.0.1-8080-1) Servlet.service() for servlet default threw exception: com.thoughtworks.xstream.io.StreamException:  : Element type "org.joda.time.chrono.ISOChronology" must be followed by either attribute specifications, ">" or "/>".
	at com.thoughtworks.xstream.io.xml.DomDriver.createReader(DomDriver.java:86) [xstream-1.3.1.jar:]

....


	at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_03]
Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 297; Element type "org.joda.time.chrono.ISOChronology" must be followed by either attribute specifications, ">" or "/>".
	at org.apache.xerces.parsers.DOMParser.parse(DOMParser.java:244)
	at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:285)
	at com.thoughtworks.xstream.io.xml.DomDriver.createReader(DomDriver.java:79) [xstream-1.3.1.jar:]
	... 47 more


Aguém sabe como eu resolvo isso?

possivelmente o melhor jeito de resolver é criar converters pras datas tanto na serialização qto na deserialização…

daí vc converte pra dd/MM/yyyy HH:mm:ss e dá tudo certo

Eu tenho o converter assim:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.coliseu.util;

import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormat;

import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;

/**
 * Classe utilizada para converter datas
 * @author valde
 */
public class LocalDateTimeConverter extends AbstractSingleValueConverter {


	@Override
	public boolean canConvert(Class type) {
		return LocalDateTime.class.equals(type);
    }

    @Override
    public String toString(Object obj) {
        try {

        return DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss").print((LocalDateTime) obj);
        } catch (Exception e) {
            return "ERRO";
        }

    }
    @Override
    public Object fromString(String string) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}

isso que você se refere?

vc tá registrando esse cara em algum lugar?

precisa implementar o toString E o fromString e registrar esse cara tanto no processo de serializar qto no de deserializar.

isso na parte web e na parte desktop

Eu tenho na apl web.

eu devo colocar no desktop também?

eu coloquei o converter no desktop também acontece o mesmo erro, devo fazer algo mais?

se ele vai gerar/consumir xml, tb

dá uma olhada no xml que está sendo gerado… e ve se não tem nenhum problema nele

Desculpe Lucas eu estou aprendo agora a trabalhar com rest e xml, como eu faço para eu visualizar o xml que esta sedo gerado na hora de enviar, quando eu envio ele vai direto no


package br.com.coliseu.util;

import br.com.caelum.vraptor.deserialization.XStreamXMLDeserializer;
import br.com.caelum.vraptor.http.ParameterNameProvider;
import br.com.caelum.vraptor.ioc.ApplicationScoped;
import br.com.caelum.vraptor.ioc.Component;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
@ApplicationScoped
@Component
public class CustomXStreamXMLDeserializer extends XStreamXMLDeserializer {

	public CustomXStreamXMLDeserializer(ParameterNameProvider provider) {
		super(provider, null);
	}

	/**
	 * Extension point to configure your xstream instance.
	 * @return the configured xstream instance
	 */
	@Override
	protected XStream getXStream() {
		XStream xStream = new XStream(new DomDriver());
		xStream.alias("versaotabelas", br.com.coliseu.model.Versaotabelas.class);
		return xStream;
	}


}

acessa a url no browser, que vai aparecer o xml

Lucas eu coloquei um breakpoint no:

     return DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss").print((LocalDateTime) obj);

ele nem passa ali.

vc registrou o converter em algum lugar?

Não registrei, aonde eu faço isso?
quando eu estou na minha aplicação web, e chama um autocomplete por exemplo, que tem LocalDateTime, ele passa pelo converter.

no CustomXStreamXMLDeserializer, fazendo xstream.registerConverter(…) ou coisa do tipo

eu fiz isso:


	@Override
	protected XStream getXStream() {
		XStream xStream = new XStream(new DomDriver());
		xStream.alias("versaotabelas", br.com.coliseu.model.Versaotabelas.class);
		xStream.registerConverter(new LocalDateTimeConverter());
		return xStream;
	}

eu fiz na aplicação web, e continua dando o mesmo erro.

também coloquei no desktop e continou dando erro

vc ainda não viu o xml gerado, né? tenta ver isso, que é mais fácil entender o que está acontecendo.

Não consegui retornar o xml, na verdade não sei como enviar um objeto pela url…

uma coisa que estava a versão do vraptor que tenho ele espera mais um parametro um

aqui:

	public CustomXStreamXMLDeserializer(ParameterNameProvider provider) {
		super(provider, null);
	}

eu estou passando null

eu tentei fazer isso:

	public CustomXStreamXMLDeserializer(ParameterNameProvider provider, XStreamBuilder builder) {
		super(provider, builder);
	}

e dá esse erro ao iniciar a apl web.


19:34:07,262 WARN  [org.springframework.web.context.request.FacesRequestAttributes] (MSC service thread 1-2) Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@1880573] for attribute 'messageConverter' because FacesRequestAttributes does not support such callbacks
19:34:07,265 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/CP]] (MSC service thread 1-2) Exception starting filter vraptor: java.lang.UnsupportedOperationException
	at java.util.AbstractMap.put(AbstractMap.java:203) [rt.jar:1.7.0_03]

.....

19:34:07,305 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-2) Error filterStart
19:34:07,305 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-2) Context [/CP] startup failed due to previous errors
19:34:07,327 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC00001: Failed to start service jboss.web.deployment.default-host./CP: org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./CP: JBAS018040: Failed to start context
	at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:95)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_03]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_03]
	at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_03]

acho que não é só esse o erro que tá acontecendo…

na versão do vraptor que vc tá, vc não deveria sobrescrever o Serialization, e sim o XStreamBuilder, que tem os mesmos métodos protected que esse.

dessa forma que você diz:

package br.com.coliseu.util;

import br.com.caelum.vraptor.deserialization.XStreamXMLDeserializer;
import br.com.caelum.vraptor.http.ParameterNameProvider;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class XStreamBuilder extends XStreamXMLDeserializer{

	public XStreamBuilder(ParameterNameProvider provider,
			br.com.caelum.vraptor.serialization.xstream.XStreamBuilder builder) {
		super(provider, builder);
		// TODO Auto-generated constructor stub
	}

	
	
	@Override
	protected XStream getXStream() {
		XStream xstream = new XStream(new DomDriver());
		xstream.registerConverter(new LocalDateTimeConverter());
		xstream.alias("versaotabelas", br.com.coliseu.model.Versaotabelas.class);
		return xstream;
	}

}

depois que eu fiz dessa forma ele deu classnotfound daí eu add a lib xmlpull_1_1_3_1.jar e ele começou a dar esse erro:

 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/CP]] (http--127.0.0.1-8080-1) Unhandled exception occurred whilst decorating page: com.thoughtworks.xstream.io.StreamException: Cannot create XmlPullParser
	at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:56) [xstream-1.4.2.jar:]
	at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:65) [xstream-1.4.2.jar:]

...

ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/CP].[default]] (http--127.0.0.1-8080-1) Servlet.service() for servlet default threw exception: com.thoughtworks.xstream.io.StreamException: Cannot create XmlPullParser
	at com.thoughtworks.xstream.io.xml.AbstractXppDriver.createReader(AbstractXppDriver.java:56) [xstream-1.4.2.jar:]

Eu tinha esquecido de fazer a anotação

@ApplicationScoped
@Component
public class XStreamBuilder extends XStreamXMLDeserializer{

mas agora deu erro de antes:

09:53:38,506 WARN  [org.springframework.web.context.request.FacesRequestAttributes] (MSC service thread 1-6) Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@1d8bd60] for attribute 'messageConverter' because FacesRequestAttributes does not support such callbacks
09:53:38,508 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/CP]] (MSC service thread 1-6) Exception starting filter vraptor: java.lang.UnsupportedOperationException
	at java.util.AbstractMap.put(AbstractMap.java:203) [rt.jar:1.7.0_03]


....


09:53:38,553 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-6) Error filterStart
09:53:38,553 ERROR [org.apache.catalina.core.StandardContext] (MSC service thread 1-6) Context [/CP] startup failed due to previous errors
09:53:38,574 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-6) MSC00001: Failed to start service jboss.web.deployment.default-host./CP: org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./CP: JBAS018040: Failed to start context
	at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:95)