Cast automatico dos parâmetros de um método(com Reflection)

7 respostas
cleriston

Olá pessoal!!
Vejam o código abaixo

for (Method method : action.getClass().getMethods()) {
	String m = method.getName(); 
	if (m.startsWith("set")) {
		String p = request.getParameter(m.substring(3,4).toLowerCase() + m.substring(4));
		if (p != null) {
			method.invoke(action, p);
		}
	}
}

Este código ele lê os parâmetros que estão no request e procura em uma classe (com reflection) um método set+“nome do parâmetro”.
Se ele encontrar algo, ele invoca o método e passa o valor do parâmetro do request para o parâmetro do método.
Mas tive um problema. O “request.getParameter(“xxx”)” traz sempre uma String. Se meu método receber um Integer dá pau… Tem como através de reflection ver que o parâmetro do método é um Integer(ou qq outra coisa) e fazer um Cast ??

Fonte de onde vi o código: http://www.tatanka.com.br/palestras/cj2005-Web+MVC+IoC+Reflection/

7 Respostas

rodrigo_corinthians

Para saber o tipo do paramêtro vc usa o método "getParameterTypes() " daí vc faz um cast antes de chamar o invoke, maiores informações na API.

Sem mais, Rodrigo.

U

uma alternativa boa para este tipo de tarefa também é o beans utils da apache.

mais informações: http://jakarta.apache.org/commons/beanutils/

cleriston

Pelo q vi aqui
não dá pra fazer o cast

rodrigo_corinthians
Como assim não dá? :( Com Java tudo é possível. :twisted:
...
if (p != null) {
 			cast(action, method, p);
 		}
...

public void cast(Action actionObject, Method method, String value) {
    	if(method != null && value != null && !value.equals("")){
    		Class clazz = method.getParameterTypes()[0];
    		if(clazz.getName().equals("java.lang.Integer")){
    			method.invoke(actionObject, new Integer(value));
    		} else if(clazz.getName().equals("java.lang.Long")){
    			method.invoke(actionObject, new Long(value));
    		} // Aqui se coloca o restante dos cast's...
    	}
    }
Testa ae e depois me fala se funcionou...
cleriston

blz… eu tinha pensado em fazer isso… mas a queria saber se exist uma maneira mais automática, sem “ifs”, pois se um dia aparecer um metodo que recebe um boolean eu teria q adicionar um if nesse código

T

Bom, acho que você vai ter de se virar para isolar essa conversão - principalmente porque a string pode vir formatada (por exemplo, “20/07/2007”) , e aí você é que tem de desformatar a string.
Ou seja, não tenha preguiça de fazer um monte de ifs, porque isso é realmente necessário.
Uma forma de isolar a conversão em uma rotina isolada (e com ifs, é claro) é a seguinte:

static Object convert (Class parameterClass, String value) {
    if (parameterClass == Integer.class) {
        return Integer.valueOf (value); // aqui estou supondo que 
        // o número já venha "desformatado." Senão use a sua 
        // conversão favorita.
    } else if (parameterClass == int.class) {
        return Integer.valueOf (value); // tem de retornar um Integer, não um int
    } else if (parameterClass == String.class) {
        return value;
    } else if (parameterClass == Boolean.class) {
        ...
    } else if (parameterClass == boolean.class) {
        ...
    }
}

E note que Integer.class != int.class, e assim por diante; você tem de levar em conta isso também.

e você a usa assim:

method.invoke (actionObject, convert (clazz, value));
Pedrosa

Talvez você poderia anotar como Vraptor faz:

@Component
public class PersonLogic {

        @Parameter
        private String name, address;
        
        @Parameter
        private int preferredNumber;

        public void add() {
                System.out.printf("Adding %s, %s, %d to the database!%n", name, address, preferredNumber);
        }

}
Criado 20 de julho de 2007
Ultima resposta 20 de jul. de 2007
Respostas 7
Participantes 5