Subversion Repositories bacoAlunos

Rev

Rev 1782 | Blame | Compare with Previous | Last modification | View Log | RSS feed

GENSON SERIALIZAÇÃO

O modo default de uso do Genson é
com metodos e fields ativos
Isto serializa gets is's e vars publicas
Outra coisa que deve ser utilizada na serialização são as datas como Timestamp

A utilização dos RuntimeTypes so faz sentido com o uso de MetaDataClass para
o genson descobrir o tipo das classes polimorficas em tempo real
e cria-las de acordo com a verdadeira classe

gensonGenericLoad = new GensonBuilder()
                //Usa ClassMetadata nos objectos contidos se houver
                // porque no principal já foi buscar antes fazendo parse ao JSON no metodo fromJson e fazendo get("@class")
                //porque no genson o @class tem de vir em primeiro e pode não
                // se nos outros não vier info da class ele falha
                .useMethods(true) //only bean proerties
                .useFields(true) //pode existir uma var com campos publicos esses ele serializa
                .useRuntimeType(true)
                .useClassMetadata(true)
                .useDateAsTimestamp(true)
                .create();

A desserialização é menos problematica que a serialização porque
apenas temos para serializar o que vem no JSON

A única lacuna é que o campo @class tem de vir em primeiro na lista
mas o org.json nao preve isso e pode trocar as ordens
Isto é facilmente resolvido fazendo um preparse do objecto
e mandando o GENSON desserializar com a class correcta
No entanto em classes contidas umas nas outras isto é de momento impossivel
de solucionar uma vez que é o genson no processo de parse que lhes em acesso
A menos que sejam corridas todas as estruturas num preparse
Portanto a desserialização default do DomainObject desserializa tudo o que conseguir
mas pode falhar tipos contidos e usar apenas os genericos que estão no set do Metodo da class
por isso não deve ser usada em Heranças com envio total dos Objecto por ajax, as dessearializações
devem ser classe por class de forma parcial quando houver heranças para não dependermos
do campo @class fora de sitio. Sempre que não houver herança podemos usar o deserializa
à vontade mesmo o do domain Object que o resultado vai ser 100% de acerto no objecto obtido.

Ja a serialização pode enveredar por caminhos estranhos como metodos com
proxies no hibernate ou metodos que devolvam Class como resultado como o metodo
getReferenceClass no DomainObject
Por essa razão a serialização deve fazer um exclude da classe Object e de seguida
incluir tudo o que faça falta.


Coisas a melhorar no BACO

Todas a propriedades de get e de is não podem ter argumentos ou então não podem
começar por is ou get, têm de começar por checkIs ou obtain

Expressão Regular para encontrar casos de falha

boolean[ ]{1,4}is(.*)\(.{1,1000}\)
boolean[ ]{1,4}get(.*)\(.{1,1000}\)


Serialização d Listas

O Genson permite serializar Lists, Sets e Maps sem ser necessário incluir as classes
List, Set ou Map nos includes do Builder
Incluir estas classes nos Builders implica serializar coisas que não queremos
serializar, por exemplo se incluirmos apenas os métodos que queremos
 e nesses métodos não incluirmos um getSchools por exemplo
 e depis incluirmos as Listas isso vai fazer com que este metodo seja serializado sem de facto querermos

ATENÇÃO: por vezes acontece que uma falha de serialização de uma lista pode ocorrer por falha de um campo interno
Para isso é necessário analizar todas as entradas do Log e procurar pela verdadeira causa:
O Tomcat não mostra a Wrapped Exception, tem de se entrar em debug para ver a verdadeira excepção

Erros comuns: Metodos get ou is com parametros, forma rápida de resolução do erro: usar a diretiva useMethods(false)
no genson builder e incluir apenas os metodos desejados, assim evitamos serializações inexperadas de futuro

Mais um problema Comum com os Overrides, serialização de uma List com o metodo static toJson
Se passamos uma lista de SuperClasses Geradas (exemplo: ConfigurationSeparator) e incluimos um Metodo
na classe implementação, exemplo ConfigurationSeparatorImpl.getSchoolIds esse metodo não vai ser invocado
mesmo que coloquemos o include ao mesmo porque o Genson vai olhar apenas para a classe ConfigurationSeparator
nesse sentido necessitamos de usar .useClassMetadata(true) e useRuntimeTypes o problema
é que a lista poderá ter os classMetadata fora do lugar isto só é seguro
no sentido serialização imediatamente

NOTA INCLUDES EXCLUDES
Os includes têm ordem
Se excluirmos todos os objetos antes depois temos de adicionar
ou o nome do metodo ou o tipo
Se adicionarmos por exemplo o Tipo Boolean todos os getBoolean são usados
mesmo que não incluiamos o isMetodo especifico e isto pode adicionar metodos
não desejados

Mesmo que seja incluida uma classe ele não inclui os metodos da classe
inclui sim gets que devolvam essa classe

Usar a primitiva useMethods(false) exclui todos os métodos,
os campos serão todos usados mas se estiverem privados não são copiados
mas se depois incluirmos os nomes dos campos mesmo que privados desejados
( neste caso não importa se é ou nao na classe certa as heranças nao afetam a classe onde queremos ver o campo)

 esses campos
 .include("ocorrenciasGetSetNormal", TestFieldsAndMethodsTogether.class)
 .include("ocorrenciasGetSetNormal", TestFieldsAndMethodsChild.class)
 é igual

 included são usados mas não outros, apenas os publicos  os incluidos
s campos mesmo que tenham metodos e esses metodos sejam declarados
  //No include do Genson, o include serve apenas para Campos e não para
  //metodos, portanto o campo não é copiado se o use metodos estiver a false
  //os campos apenas são copiados se publicos ou incluidos especificamente

  Um metodo TEM PRIORIDADE EM RELACAO AO CAMPO
  Mesmo que o campo seja incluido num include o metodo sobrepõe-se quer o GET quer o SET
  e desde que o useMethods esteja a true, O CAMPO E COPIADO PRIMEIRO E O SET E FEITO DEPOIS

  METODOS EXCLUIDO
  Se usarmos metodos e nao campos e excluirmos um metodo, FUNCIONA
  ou seja os includes apenas servem para campos
  mas os excludes aplicam-se a geters e setters
  Poderá funcionar também

############PROCEDIMENTO ACONSELHADO###########################################
  Se excluirmos o Object.cautomaticamente excluimos todo so Metodos
  mesmo os simples, os Metodos podem ser incluidos e assim só ja temos os
  metodos que queremos e não outros. Classe por classe.
  Ou seja o include sempre funciona para metodos mas temos de os ter ligados
  e com o Object Excluido para depois adiconar os metodos que queremos
  # VER ESTE METODO
  public void testMetodosIncludesEdates() throws JSONException {

NOTA HERANCAS METODOS
Os metodos a incluir devem ser incluidos na classe que os comporta e não nas
classes descendentes, desse modo não funcionam

Na serialização ele usa sempre o Tipo runtime mesmo que não usemos o useClassMetadata
o sistema gera os gets da classe runtime
Ja na descerialização é que temos de usar o class para objetos contidos na
classe a desserializar


DATAS

Nao usar os getDates sempre que se precisar de uma data deve-se criar um Metodo
getDateStr e o setDateSrt usando o DatesUtils para converter a data verdadeira
de string e para string
porque as datas como vêm do MySql são Timestamps e são sempre serializadas para
um formato de texto que depois não se consegue desserializar
Não usar include(Date.class)
nem include("updateDate")
isto apenas funciona com o seMethods a true

Se quisermos proteger os metodos e coloca-los a false necessitamos
de ter um campo auxiliar numa bubclasse e altera-lo quando é feito o setUpdateDate
na de cima fazendo override do campo
Para desserializar esse auxiliar para o verdadeiro, como os metodos não estão a ser
chamados pelo GENSON temos sempre de fazer a passagem à mão para o campo final

Existe uma forma melhorada de proteger os metodos veja o ponto acima
onde diz ###PROCEDIMENTO ACONSELHADO####


NORMAS DE UTILIZACAO DO GENSON

Usar sempre as seguintes diretivas
            .exclude(Object.class)
            .useDateAsTimestamp(true)
            .useRuntimeType(true)
            .useMethods(true)
            .useFields(false)
            .useClassMetadata(true)

usar um include por cada metodo necessário de aceder como property
Assim por segurança se entrarem novos metodos não são serializados sem os
colocarmos na construção do Genson

TODO
VERIFCAR PLANOS DE ESTUDOS EM PARTICULAR OS ECTS eCTS eCts
VERIFICAR INTERFACES DO REPOSITORIO JA ESTA BEM MAS NAO ESTA NORMALIZADO
//VERIFICADO USA APENAS CAMPOS E OS TESTES ESTAO VALIDADOS FALTA TESTAR NAS ATRIBUICOES
VERIFICAR QUESTIONARIOS QUESTÃO DAS TIPOLOGIAS
//VERIFICADO
VERIFICAR IMPORTACOES QUESTÃO DAS TIPOLOGIAS

Verificar como são serializadas as ocorrencias nas tipologias porque não precisam de ser serializadas