[RESOLVIDO] Interceptor com Annotation no Struts 2

Caros,

Procurei mas não encontrei nada concreto sobre isso, então resolvi postar, vamos lá.

Action

package br.com.teste.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {

	private static final long serialVersionUID = -8536563318993968542L;

	public static final String MESSAGE = "Struts rodando!";

	private String message;

	@Action(value = "/welcome", results = { @Result(name = "success", location = "/HelloWorld.jsp") }, interceptorRefs = { @InterceptorRef("loginStack")})
	public String execute() {
		setMessage(MESSAGE);
		return SUCCESS;
	}

	/**
	 * @param message
	 *            the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}
}

Interceptor

package br.com.teste.action;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

public class LoginCheckInterceptor implements Interceptor {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5361082118609994164L;

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		boolean b = false;
		if (!b) {
			return invocation.invoke();
		} else {
			return "LoginFalha";
		}
	}

}

Primeiro gostaria de saber se, mesmo usando annotations, preciso declarar o interceptor no struts.xml?

Independente do caso acima, eu já tentei das duas formas, mas sempre obtenho a mensagem:

Unable to find interceptor class referenced by ref-name LoginCheckInterceptor - [unknown location]

struts.xml

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<package name="default" extends="struts-default">
		<interceptors>
			<interceptor name="loginInterceptor" class="br.com.teste.action.LoginCheckInterceptor"></interceptor>
			<interceptor-stack name="loginStack">
				<interceptor-ref name="loginInterceptor"></interceptor-ref>
			</interceptor-stack>		
		</interceptors>
	</package>
</struts>

Será que alguém poderia me dizer onde estou errando? Ou então postar algum exemplo funcional de interceptor com annotations?

Desde já obrigado.

Amigo,

uma dica: seu código poderia ficar menor.

@Action(interceptorRefs = @InterceptorRef("loginStack")) public String execute() { setMessage(MESSAGE); return SUCCESS; }

Assim, a url seria “hello-world” (porque sua classe se chama “HelloWorldAction”) e o destino seria “/WEB-INF/content/hello-world.jsp” para qualquer resultado.

Quanto ao Interceptor, você deve estender o AbstractInterceptor e não implementar Interceptor.

Para mapear os interceptors para aplicação realmente só via XML, mesmo com o Convention Plugin do Struts 2.1.x. Mas como existe apenas uma meia dúzia de interceptors por aplicação e só há esse trabalho no inicio de um projeto, isso não chega a ser um problema.

[quote=jyoshiriro]Amigo,

uma dica: seu código poderia ficar menor.

@Action(interceptorRefs = @InterceptorRef("loginStack")) public String execute() { setMessage(MESSAGE); return SUCCESS; }

Assim, a url seria “hello-world” (porque sua classe se chama “HelloWorldAction”) e o destino seria “/WEB-INF/content/hello-world.jsp” para qualquer resultado.

Quanto ao Interceptor, você deve estender o AbstractInterceptor e não implementar Interceptor.

Para mapear os interceptors para aplicação realmente só via XML, mesmo com o Convention Plugin do Struts 2.1.x. Mas como existe apenas uma meia dúzia de interceptors por aplicação e só há esse trabalho no inicio de um projeto, isso não chega a ser um problema.[/quote]

Opa valew pelas dicas, realmente fica mais prático desta forma, mas o interceptor ainda não rolou, meus códigos estão assim:

Action

@Action(interceptorRefs = @InterceptorRef("loginStack")) public String execute() { setMessage(MESSAGE); return SUCCESS; }

Interceptor

[code]package br.com.teste.action;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class LoginCheckInterceptor extends AbstractInterceptor {

private static final long serialVersionUID = 1914103508243933384L;

@Override
public String intercept(ActionInvocation invocation) throws Exception {
	boolean b = false;
	if (!b) {
		return invocation.invoke();
	} else {
		return "LoginFalha";
	}
}

}
[/code]

struts.xml

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <package name="default" extends="struts-default"> <interceptors> <interceptor name="loginInterceptor" class="br.com.teste.action.LoginCheckInterceptor"></interceptor> <interceptor-stack name="loginStack"> <interceptor-ref name="loginInterceptor"></interceptor-ref> </interceptor-stack> </interceptors> </package> </struts>

Ainda estou obtendo a mensagem Unable to find interceptor class referenced by ref-name loginStack - [unknown location] ao startar o tomcat.

Sei lá mó sinistra essa parada, aparentemente tudo certo, existe alguma anotação a ser feita no interceptor? Creio que não, estou perguntando apenas por desencargo.

Vlw

Você criou e mapeou o Interceptor num pacote que chamou de “default”, certo?

Então ou você indica que este é o pacote padrão do seu projeto ou faz com que a Action o use.

  1. pacote padrão do seu projeto: setar a propriedade struts.convention.default.parent.package para default (no struts.xml ou no struts.properties)

  2. fazer com que a Action o use: usar a anotação @ParentPackage(“default”) sobre a assinatura da classe.

E mais: já que pretende usar o convention plugin, sugiro que seu pacote padrão (no caso, o “default”) estenda o “convention-default” e não o “struts-default”.

[quote=jyoshiriro]Você criou e mapeou o Interceptor num pacote que chamou de “default”, certo?

Então ou você indica que este é o pacote padrão do seu projeto ou faz com que a Action o use.

  1. pacote padrão do seu projeto: setar a propriedade struts.convention.default.parent.package para default (no struts.xml ou no struts.properties)

  2. fazer com que a Action o use: usar a anotação @ParentPackage(“default”) sobre a assinatura da classe.

E mais: já que pretende usar o convention plugin, sugiro que seu pacote padrão (no caso, o “default”) estenda o “convention-default” e não o “struts-default”.[/quote]

Mano… você é o cara… agora ta tudo funcionando direitinho. :lol:

Vou postar as classes finais aqui, caso alguma outra pessoa procure um exemplo completinho.

HelloWorldAction.java

package br.com.teste.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport {

	public static final String MESSAGE = "Struts rodando!";

	private String message;

	@Action(interceptorRefs = @InterceptorRef("loginStack"))
	public String execute() {
		setMessage(MESSAGE);
		return SUCCESS;
	}

	/**
	 * @param message
	 *            the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}
}

LoginCheckInterceptor.java

[code]package br.com.teste.action;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class LoginCheckInterceptor extends AbstractInterceptor {

@Override
public String intercept(ActionInvocation invocation) throws Exception {
	boolean b = true;
	if (!b) {
		return invocation.invoke();
	} else {
		return "LoginFalha";
	}
}

}
[/code]

struts.xml

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <constant name="struts.convention.default.parent.package" value="default"/> <package name="default" extends="convention-default"> <interceptors> <interceptor name="login" class="br.com.teste.action.LoginCheckInterceptor" /> <interceptor-stack name="loginStack"> <interceptor-ref name="login" /> </interceptor-stack> </interceptors> </package> </struts>

Obrigado pela ajuda, fica com deus.

T+

Caros,

Segui passo-a-passo até uma “cópia” do código acima, porem tenho o erro abaixo a hora que reinicio o tomcat: Unable to find interceptor class referenced by ref-name sessaoStack - [unknown location]

Isso só acontece quando aplico o annotation @InterceptorRef(“sessaoStack”) na classe action HomeAction.java!!! :evil:

Segue o código:

Action (HomeAction.java)

package br.com.internetsistemas.nucleo.action;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

public class HomeAction extends ActionSupport {
	private static final long serialVersionUID = 1L;

	@Action(value = "home", results = { @Result(name = SUCCESS, location = "/nucleo/home.jsp") }, interceptorRefs = @InterceptorRef("sessaoStack"))
	public String execute() {
		return SUCCESS;
	}
}

Interceptor (LoginInterceptor.java)

package br.com.internetsistemas.nucleo.interceptor;

import br.com.internetsistemas.nucleo.model.bean.Usuario;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class LoginInterceptor extends AbstractInterceptor {
	private static final long serialVersionUID = 1L;
	
	public String intercept(ActionInvocation invocation) throws Exception {
		Usuario usuarioLogado = (Usuario) invocation.getInvocationContext()
				.getSession().get("usuarioLogado");

		if (usuarioLogado == null) {
			return "usuarioNaoLogado";
		} else {
			return invocation.invoke();
		}
	}
}

Config (struts.xml)

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<package name="default" extends="convention-default">
		<interceptors>
			<interceptor name="loginInterceptor"
				class="br.com.internetsistemas.nucleo.interceptor.LoginInterceptor"></interceptor>

			<interceptor-stack name="sessaoStack">
				<interceptor-ref name="loginInterceptor" />
			</interceptor-stack>
		</interceptors>

		<global-results>
			<result name="usuarioNaoLogado">/nucleo/login.jsp</result>
		</global-results>
	</package>
</struts>

Já vasculhei a net e o forum e estou a 5 horas tentanto resolver este problema. :shock:

Se alguem tiver uma luz me passa. Rs

Abraços!

Você criou e mapeou o Interceptor num pacote que chamou de “default”, certo?

Então ou você indica que este é o pacote padrão do seu projeto ou faz com que a Action o use.

  1. pacote padrão do seu projeto: setar a propriedade struts.convention.default.parent.package para default (no struts.xml ou no struts.properties)

  2. fazer com que a Action o use: usar a anotação @ParentPackage(“default”) sobre a assinatura da classe.

Pessoal apesar de tudo no código estiver certo meu struts.xml estava no lugar errado e o struts não “enchergava”. Por isso do erro de package não encontrada.

Abraços!

Vi que o tópico é um pouco antigo, mas descobri o problema e quero disponibilizar a solução:
No Eclipse, coloquei o struts.xml no WEB-INF, conforme o tutorial que utilizei dizia para fazer.
Fiz o deploy no tomcat. Cheguei a testar algumas formas diferentes mas o resultado eram os erros: "Unable to find interceptor class referenced by ref-name x - [unknown location]" ou "Unable to locate parent package [x] - [unknown location]".
Obviamente o struts.xml era inserido na pasta WEB-INF na aplicação.
Depois de alguns testes, consegui que funcionasse quando movi o stuts.xml para a pasta "classes".
Portanto, o local correto para inserir o struts.xml no projeto é na pasta src.
Para isso, no Eclipse, botão direito na pasta src > new > Other > General > File. Selecione a pasta src e crie o arquivo struts.xml.
Depois, é só adicionar o conteúdo do struts.xml, "clean" no tomcat, e realizar novamente o deploy.
Abraços.

Pessoal segui exatamente essas orientações, mas no meu caso a execução está entrando em loop, exemplo: Entra no método execute da Action1 e depois vai pro interceptor, e dentro do interceptor eu dou um invoke, ele vai pro metodo execute da Action1, e assim por diante, até dá um erro de loop. Alguem tem alguma ideia?
Grato