Pegando Instancia do método interceptado

12 respostas
jingle

Oi tem como eu pegar a instancia do método que estou interceptando?

só pra esclarecer melhor:

tenho interceptor normal

public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {

que esta interceptando um método que não é estático, gostaria de pegar esta instância.

12 Respostas

Lucas_Cavalcanti

resourceInstance é uma instancia do controller que está sendo interceptado
method.getMethod() é o método (java.reflect.Method) interceptado

jingle

Lucas Cavalcanti:
resourceInstance é uma instancia do controller que está sendo interceptado
method.getMethod() é o método (java.reflect.Method) interceptado

Estranho pois estou interceptando um método não estatico e o resourceInstance é nullo.

Lucas_Cavalcanti

não dá pra interceptar métodos estáticos…
métodos estáticos não são expostos como URIs…

a ordem de execução dos interceptors é essa:

@PrototypeScoped
public class DefaultRequestExecution implements RequestExecution {

	private static final Logger logger = LoggerFactory.getLogger(DefaultRequestExecution.class);

    private final InterceptorStack interceptorStack;
    private final InstantiateInterceptor instantiator;

    public DefaultRequestExecution(InterceptorStack interceptorStack, InstantiateInterceptor instantiator) {
        this.interceptorStack = interceptorStack;
        this.instantiator = instantiator;
    }

    public void execute() throws InterceptionException {
    	logger.debug("executing stack  DefaultRequestExecution");

    	interceptorStack.add(MultipartInterceptor.class);
        interceptorStack.add(ResourceLookupInterceptor.class);
        interceptorStack.add(FlashInterceptor.class);
        interceptorStack.add(InterceptorListPriorToExecutionExtractor.class); // os interceptors da sua aplicação ficam aqui
        interceptorStack.add(instantiator); //o seu controller é instanciado aqui
        interceptorStack.add(ParametersInstantiatorInterceptor.class); // os parâmetros da lógica são instanciados aqui
        interceptorStack.add(DeserializingInterceptor.class);
        interceptorStack.add(ExecuteMethodInterceptor.class);
        interceptorStack.add(OutjectResult.class);
        interceptorStack.add(DownloadInterceptor.class);
        interceptorStack.add(ForwardToDefaultViewInterceptor.class);
        interceptorStack.next(null, null);
    }
}

isso é código do vraptor… vc pode criar essa mesma classe na sua aplicação, anotá-la com @Component e registrar seu interceptor na mão depois do instantiator (nesse caso seu interceptor tem que estar anotado com @Component, e não com @Intercepts)

vc pode me explicar por favor pq vc precisa da instância do controller, pra eu ver se tem uma solução melhor que essa por favor?

jingle

meu problema todo começou quando quis tratar os erro da aplicaçao:

queria remover os try catch das controller e colocalos em um interceptor, porém nos controller os meus métodos tem redirect diferente pra quando da o erro e para quando da sucesso:

exemplo

public void adiciona(Pais pais){
try{
   //faz a lógica aqui

  //rediciona para tela de novo, para continuar cadastrando.
}catch(Exception){
 //fica na mesma tela pra nao perde os dados.
}

dai eu tinha pensado em criar uma superclasse com métodos que defini para onde vai ir em caso de falha e em caso de sucesso, e no interceptor eu obtinha esses valor e fazia o redirect…

mas me pareceu meio complexo de +++++ e estou já desistindo dessa abordagem.

Lucas_Cavalcanti

o garcia-jj fez algo do tipo já… ele até mandou uma feature request pra colocar isso no vraptor…

o que vc quer é algo genérico?
tipo: se der a ABCException vai pra XYZController.trataException();

ou vc quer algo que depende da lógica?

jingle

que eu queria era fazer algo ± assim no meu interceptor:

public void intercept(InterceptorStack stack, ResourceMethod method,
			Object resourceInstance) throws InterceptionException {

		try {

		//chama o método

		//de acordo com método ia inserir uma mensagem de sucesso aqui.

		//aqui gostaria de fazer o redicionamento de sucesso definido no método.
		} catch (Throwable ne) {
		//de acordo com método ia inserir uma mensagem de erro aqui.

		//aqui gostaria de fazer o redicionamento de erro definido no método.
		}
}
Lucas_Cavalcanti

vc acha que isso é suficiente?

public void minhaLogica() {
    result.on(UmaException.class).redirectTo(UmController.class).umaLogica();
  //sua lógica normal, possivelmente com redirecionamentos

}

daí o vraptor redirecionaria pra UmControlller.umaLogica() se desse a UmaException

jingle

Lucas Cavalcanti:
vc acha que isso é suficiente?

public void minhaLogica() {
    result.on(UmaException.class).redirectTo(UmController.class).umaLogica();
  //sua lógica normal, possivelmente com redirecionamentos

}

daí o vraptor redirecionaria pra UmControlller.umaLogica() se desse a UmaException

Exatamente!!! isso seria mais que suficiente. ainda mais se puder ter varios desse result.on (colocando classes de exception diferentes.)

G

Ahh, bem lembrado. Esse final de semana vou te mandar alguma coisa.

G

Lucas, ví agora o comentário na issue. Até agora eu tinha implementando algo parecido com o seu exemplo:

Se por acaso ele cair nisso, o ExecuteMethodInterceptor pega a exception e joga em uma variável exception e joga para o destino indicado, de forma bem semelhante ao que é feito no Validation.onErrorUse.

Provavelmente eu faça um pull lá no meu fork no sábado.

Lucas_Cavalcanti

ok, espero então =)

G

Para quem acompanha esse tópico, já há um esboço de como será o exception handler no meu fork: http://github.com/garcia-jj/vraptor/tree/exceptionhandler.

Tento em mente as exceptions FooException e BarException filhas de RuntimeException podemos fazer algo como:

// nesse caso tanto FooException quanto BarException serão interceptados
result.on(RuntimeException.class).forwardTo(MeuController.class).meuMetodo();

// nesse caso apenas FooException será interceptada
result.on(FooException.class).forwardTo(MeuController.class).meuMetodo();

E caso não houver declaração de tratamento de exception o vraptor estoura o erro 500 padrão. O mesmo acontece se você declarar, por exemplo, uma FooException e por acaso ocorrer uma NullPointerException, já que o exception handler testa apenas a exception declarada e suas filhas.

Nesse exemplo usei forwardTo, porém pode ser usado qualquer método de Results.*.

Criado 20 de maio de 2010
Ultima resposta 13 de set. de 2010
Respostas 12
Participantes 3