Como voc� j� sabe, VRaptor inclue alguns conversores b�sicos. Eles servem para as tarefas mais comuns, como convers�o para String, Double ou Calendar.
Mas existem outros casos quando voc� quiser preencher o seu modelo com um objeto, para qual n�o existe um conversor ainda. Para essa tarefa voc� deve escrever o seu pr�pio conversor.
Por exemplo, imagina se voc� quer instantiar um objeto categoria com uma sub categoria e VRaptor tem que preenche-la automaticamente quando a requisi��o foi enviada.
Ent�o o seu modelo poderia ser:
public class Category {
private Integer id;
private String name;
private Category subCategory;
//getters e setters
}Na sua camada de apresenta��o usa um simples formul�rio com uma caixa de sele��o para o id da sub categoria.
Como VRaptor sabe como criar o objeto subCategory? Ele n�o faz idea e joga uma ConversionException. Se voc� quiser VRaptor para instantiar a subCategory, voc� deveria providenciar o seu pr�pio conversor.
Existem 3 passos para escrever o seu conversor:
Primeiro, criar uma classe que implementa org.vraptor.converter.Converter:
public class CategoryConverter implements Converter {
}Agora, adiciona o m�todo public Class<?>[] getSupportedTypes(); � classe. Esse m�todo retorna um array de tipos que o conversor conhece e sabe tratar:
public class CategoryConverter implements Converter {
public Class<?>[] getSupportedTypes() {
return new Class[] { Category.class };
}
}E por �ltimo, voc� deve escrever o m�todo de convers�o:
/**
* Converts a value to an specific type
*
* @param value
* current value
* @param type
* desired type
* @return the converted value
* @throws ConversionException
* some convertion problem hapenned
*/
public Object convert(String value, Class<?> type, LogicRequest request)
throws ConversionException;Se acontecesse uma exce��o (ConversionException) durante a convers�o, ela ser� jogada e dada para cont�iner de servlet.
Se voc� n�o quiser criar nenhuma exce��o, simplesmente retorne um valor padr�o, nulo ou similar.
Por exemplo:
public Object convert(String categoryId, Class<?> type, LogicRequest request)
throws ConversionException {
Category category = new Category();
try {
category.setId(Integer.parseInt(categoryId));
} catch (NumberFormatException e) {
category = null;
}
return category;
}Se voc� quiser registrar um conversor que n�o foi instalado por padr�o, use o arquivo vraptor.xml.
Depois ele estar� dispon�vel para o sistema inteiro (veja tamb�m o outro tutorial como sobrescrever os conversores b�sicos):
<vraptor>
<converter>org.vraptor.examples.converter.CategoryConverter </converter>
</vraptor>Se um tipo pode ser convertido por dois conversores diferentes, utiliza-se o �ltimo registrado.
Quando o conversor � registrado, o Vraptor cria uma inst�ncia espec�fica. Nenhuma outra jamais ser� criada. Por isso � importante que voc� nunca deixe vari�veis para ler ou escrever no conversor.
Isso tamb�m significa que uma �nica inst�ncia do seu conversor deve ser seguro para threads: dois threads podem e chamar�o o m�todo do seu conversor ao mesmo tempo.
Nota: A anota��o @Conversion descreve conversores que ser�o criados quando necess�rios. Esses conversores podem ficar no cache nas vers�es no futuro .... a regra b�sica �: Jamais deixe vari�veis para leitura ou escrita nas suas classes de conversor.