Olá caros amigos, gostaria de formatar as datas retornadas pelo vRaptor. Ele está retornando datas como se fossem objetos. Alguém sabe como posso formatar datas?
{"success": true,
"data": [
{
"id": 150,
"nome": "Maria das Dores",
"dataNascimento": {
"@class": "sql-timestamp",
"$": "2011-04-16 00:00:00.0"
},
"cpfCnpj": 123123,
"rg": 0,
"dataExpedicao": {
"@class": "sql-timestamp",
"$": "2011-01-31 00:00:00.0"
},
"orgaoExpedidor": "",
"limiteCredito": 0.0,
"logradouro": "",
"numero": 0,
"bairro": "",
"cidade": {
"id": 126,
"nome": "Cutias",
"estado": {
"id": 3,
"sigla": "AP",
"nome": "Amapá"
}
} ...}
}
você pode sobrescrever o jsonSerialization, como nesse gist:
CustomJSONSerialization.java
import com.thoughtworks.xstream.converters.basic.DateConverter;
@Component
public class CustomJSONSerialization extends XStreamJSONSerialization {
public CustomJSONSerialization(HttpServletResponse response,TypeNameExtractor extractor, ProxyInitializer initializer) {
super(response, extractor, initializer);
}
@Override
public XStream getXStream() {
This file has been truncated. show original
É só criar essa classe no meu projeto e pronto? Não preciso fazer nenhuma indicação em uma annotation?
só @Component nela é o suficiente
Não deu certo.
Olha meu a função que retorna o json:
public void lista(){
List<Cliente> clientes = clienteDao.findAll();
result.use(ExtJSJson.class).from(clientes).success(true).serialize();
}
Detalhe, esse clienteDao está sendo injeto pelo Spring e o Controler é gerenciado pelo vraptor. Tem algum problema?
então ao invés de sobrescrever o XStreamJSONSerialization, sobrescreva ExtJSJsonImpl…
o que eu te passei funcionaria se vc usasse result.use(json())
Tu já viu como está a classe ExtJSJsonImpl?
Não cosigo setar o atributo xstream pq ele não está encapsulado. Não tem como reutilizar essa componente.
Se tivesse bastava fazer:
@Component
public class CustomJSONSerialization extends ExtJSJsonImpl {
public CustomJSONSerialization(HttpServletResponse response) {
super(response);
getXtream().registerConverter(new DateConverter("dd/MM/yyyy", new String[0]));
}
}
opa, sry…
o ExtJSJSon foi uma contribuição externa, então não seguiu muito o jeito normal do VRaptor de programar…
o que vc pode fazer é copiar essa classe para o seu projeto:
https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/util/extjs/ExtJSJsonImpl.java
e mudar o xstream do construtor adicionando o seu converter…
o ideal era que essa classe usasse o JSONSerialization
já tem uma issue pra fazer isso: https://github.com/caelum/vraptor/issues/292
na próxima versão isso vai estar mais configurável
É, o negócio lá tá parecendo uma briga de faca aqui do interior daqui do Ceará.
Lucas, não funcionou. Após as implementações abaixo, continua não formatando a data. É algo que eu estou fazendo errado?
mesmo fazendo isso:
public void lista(){
List<Cliente> clientes = clienteDao.findAll();
result.use(json()).from(clientes, "data").serialize();
}
@Component
public class CustomJSONSerialization extends XStreamJSONSerialization {
public CustomJSONSerialization(HttpServletResponse response,TypeNameExtractor extractor, ProxyInitializer initializer) {
super(response, extractor, initializer);
}
@Override
public XStream getXStream() {
XStream xstream = super.getXStream();
xstream.registerConverter(new DateConverter("dd/MM/yyyy", new String[0]));
return xstream;
}
}
a sua data é um Date ou um Calendar? é Date do java.util ou java.sql?
Taqui a criança:
[code]package br.com.drover.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id ;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import org.springframework.beans.factory.annotation.Autowired;
@Entity
@SequenceGenerator (name=“CLIENTE_S”,initialValue=1,sequenceName=“CLIENTE_S”)
public class Cliente {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CLIENTE_S")
private Integer id;
private String nome;
private Boolean isPessoaJuridica;
private Date dataNascimento;
private Long cpfCnpj;
private Long rg;
private Date dataExpedicao ;
private String orgaoExpedidor;
private Double limiteCredito;
private String logradouro;
private Integer numero;
private String bairro;
private String CEP;
private String nomePai;
private String nomeMae;
@ManyToOne
private Cidade cidade;
public Cliente() {
}
public Cliente(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setName(String nome) {
this.nome = nome;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Long getCpfCnpj() {
return cpfCnpj;
}
public void setCpfCnpj(Long cpfCnpj) {
this.cpfCnpj = cpfCnpj;
}
public String getLogradouro() {
return logradouro;
}
public void setLogradouro(String logradouro) {
this.logradouro = logradouro;
}
public String getBairro() {
return bairro;
}
public void setBairro(String bairro) {
this.bairro = bairro;
}
public Cidade getCidade() {
return cidade;
}
@Autowired
public void setCidade(Cidade cidade) {
this.cidade = cidade;
}
public Double getLimiteCredito() {
return limiteCredito;
}
public void setLimiteCredito(Double limiteCredito) {
this.limiteCredito = limiteCredito;
}
public String getNomePai() {
return nomePai;
}
public void setNomePai(String nomePai) {
this.nomePai = nomePai;
}
public String getNomeMae() {
return nomeMae;
}
public void setNomeMae(String nomeMae) {
this.nomeMae = nomeMae;
}
public Long getRg() {
return rg;
}
public void setRg(Long rg) {
this.rg = rg;
}
public String getOrgaoExpedidor() {
return orgaoExpedidor;
}
public void setOrgaoExpedidor(String orgacaoExpedidor) {
this.orgaoExpedidor = orgacaoExpedidor;
}
public Boolean getIsPessoaJuridica() {
return isPessoaJuridica;
}
public void setIsPessoaJuridica(Boolean isPessoaJuridica) {
this.isPessoaJuridica = isPessoaJuridica;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setCEP(String cEP) {
CEP = cEP;
}
public String getCEP() {
return CEP;
}
public void setNumero(Integer numero) {
this.numero = numero;
}
public Integer getNumero() {
return numero;
}
public Date getDataExpedicao() {
return dataExpedicao;
}
public void setDataExpedicao(Date dataExpedicao) {
this.dataExpedicao = dataExpedicao;
}
public Date getDataNascimento() {
return dataNascimento;
}
public void setDataNascimento(Date dataNascimento) {
this.dataNascimento = dataNascimento;
}
}
[/code]
troca o:
xstream.registerConverter(new DateConverter("dd/MM/yyyy", new String[0]));
por
xstream.registerConverter(new SingleValueConverter() {
public String toString(Object value) {
return new SimpleDateFormat("dd/MM/yyyy").format(value);
}
public boolean canConvert(Class clazz) {
return Date.class.isAssignableFrom(clazz);
}
public Object fromString(String value) {
return null; //não é usado
}
});
Lucas, percebi que o Hibernate está retornando um Timestamp no lugar de um Date. Acho que deve ser por isso que ainda não funcionou. Segue screemshot.
mas se o seu campo está declarado como date não deveria ter problema…
vc colocou o converter implementado como eu te falei? importou de java.util.Date?
Aindan não deu. Ele converte, mas converte dentro de uma estrutura própria. Como se fosse um objeto:
“dataNascimento”: {"@class ": “sql-date”,"$": “2011-03-30”} ,“cpfCnpj”: 1296231305,“rg”: 2002001345512,“dataExpedicao”: {"@class ": “sql-date”,"$": “2011-06-27”}
só pra confirmar, seu custom está assim?
import java.util.Date;
import br.com.caelum.vraptor.ioc.Component;
@Component
public class CustomJSONSerialization extends XStreamJSONSerialization {
public CustomJSONSerialization(HttpServletResponse response,TypeNameExtractor extractor, ProxyInitializer initializer) {
super(response, extractor, initializer);
}
@Override
public XStream getXStream() {
XStream xstream = super.getXStream();
xstream.registerConverter(new SingleValueConverter() {
public String toString(Object value) {
return new SimpleDateFormat("dd/MM/yyyy").format(value);
}
public boolean canConvert(Class clazz) {
return Date.class.isAssignableFrom(clazz);
}
public Object fromString(String value) {
return null; //não é usado
}
});
return xstream;
}
}
inclusive os imports?
o que me parece é que não está passando por essa classe…
Meu custon está assim e está sendo executado. Já executei e confirmei isso. Amanhã eu vou fazer um upload do projeto para o github pra você ver como está tudo certinho.