Utilizando @Component do VRaptor no JSP

Olá amigos do fórum.

Estou mexendo em um projeto com o VRaptor, e surgiu um cenário onde pensamos em fazer da seguinte forma

um @Component que vai manter alguns dados globais da aplicação, nossa idéia era tambem anotar o cara com @ApplicationScoped

public class Enviroment {
    public getTeste(){
        return "teste";
    }
}

e queriamos acessar esse cara diretamente no jsp, com EL

${environment.teste}

Mas nao tá funfando… :cry: …primeiramente, isso aí DEVERIA funcionar? Os componentes do VRaptor são acessiveis via EL?

Se não, que abordagem eu poderia utilizar aqui amigos?

Obrigado!

Pelo o que eu sei, somente os @SessionScoped são acessados por EL (posso estar enganado)

Mas existe solução sim. Cria um interceptor que vai receber essa classe no construtor e depois você joga ela para a view usando o result.include(“varNaEL”, instancia);

[quote=Rafael Guerreiro]Pelo o que eu sei, somente os @SessionScoped são acessados por EL (posso estar enganado)

Mas existe solução sim. Cria um interceptor que vai receber essa classe no construtor e depois você joga ela para a view usando o result.include(“varNaEL”, instancia);[/quote]

Eu faria desse modo também.

[quote=Rafael Guerreiro]Pelo o que eu sei, somente os @SessionScoped são acessados por EL (posso estar enganado)

Mas existe solução sim. Cria um interceptor que vai receber essa classe no construtor e depois você joga ela para a view usando o result.include(“varNaEL”, instancia);[/quote]

[quote=Rafael Guerreiro]Pelo o que eu sei, somente os @SessionScoped são acessados por EL (posso estar enganado)

Mas existe solução sim. Cria um interceptor que vai receber essa classe no construtor e depois você joga ela para a view usando o result.include(“varNaEL”, instancia);[/quote]

Obrigado, cara :wink: . Eu estou anotando a classe como @ApplicationScoped (desculpe, faltou isso no codigo que postei), é um escopo maior que o SessionScoped né…então não deveria funcionar?

Segui a sua sugestão e resolveu

@Component @ApplicationScoped
public class Environment {
	
	public String getStaticContext(){
		return "/static-resources";
	}
}

//interceptador
@Intercepts
public class EnvironmentInterceptor implements Interceptor {
	
	private Environment environment;
	private Result result;
	
	public EnvironmentInterceptor(Environment environment, Result result){
		this.environment = environment;
		this.result = result;
	}
	
	@Override
	public void intercept(InterceptorStack stack, ResourceMethod method, Object resourceInstance) throws InterceptionException {
		
		result.include("environment", environment);
		
		stack.next(method, resourceInstance);
	}
	
	@Override
	public boolean accepts(ResourceMethod method) {
		return true;
	}
}

mas se desse pra acessar na EL direto era bom né :lol: …não tem jeito mesmo nao?

Valeu amigos.

Espera… Antes de você criar o interceptor, ela não estava anotada com @ApplicationScoped?

Sim, já estava anotada com @ApplicationScoped. Daí veio minha duvida, se esse cara deveria ser visivel no JSP…

Olá alias,

o Environment não deveria estar disponível nos jsps por padrão mesmo. O fato dos componentes @SessionScoped (e @RequestScoped também) serem acessíveis via jsp é um bug que virou feature :wink: o Spring gerencia esses escopos colocando atributos na sessão e no request, e a gente acabou levando isso pros outros providers também…

já o applicationScoped a gente resolveu não fazer isso, por ser um componente mais geral que não tem a ver com requests. Mas vc pode resolver isso recebendo um servletContext no construtor e usando um método @PostConstruct assim:

@Component @ApplicationScoped
public class Environment {
   public Environment(ServletContext context) {
       //guarda num field
   }
   @PostConstruct
   public void registra() {
       context.setAttribute("environment", this);
   }
}

assim ele fica acessível do jeito que vc quer.

[quote=Lucas Cavalcanti]Olá alias,

o Environment não deveria estar disponível nos jsps por padrão mesmo. O fato dos componentes @SessionScoped (e @RequestScoped também) serem acessíveis via jsp é um bug que virou feature :wink: o Spring gerencia esses escopos colocando atributos na sessão e no request, e a gente acabou levando isso pros outros providers também…

já o applicationScoped a gente resolveu não fazer isso, por ser um componente mais geral que não tem a ver com requests. Mas vc pode resolver isso recebendo um servletContext no construtor e usando um método @PostConstruct assim:

@Component @ApplicationScoped
public class Environment {
   public Environment(ServletContext context) {
       //guarda num field
   }
   @PostConstruct
   public void registra() {
       context.setAttribute("environment", this);
   }
}

assim ele fica acessível do jeito que vc quer.[/quote]

então Lucas eu imaginei que o Environment já estaria disponível dentro do ServletContext, dessa forma acessível no JSP. Eu acho razoável o que voce disse (que os objetos @ApplicationScoped não tem lá muito a ver com requests), mas por outro lado o próprio funcionamento do JSP garante que os objetos do escopo do contexto são visíveis para a EL…então não seria correto expor esses objetos da mesma forma que os @Session e @Request? Ou o Spring não coloca mesmo esses objetos @ApplicationScoped como atributos do contexto?

Aí Lucas tive aula na Caelum ano passado contigo mano :lol: , de EJB. Mundo pequeno, hehe. Valeu pela dica.

até poderíamos colocar no contexto sim… abre lá uma issue:

Pois eh… mundo pequeno :wink:

Beleza Lucas criei a feature lá…se sobrar um tempinho vou ver se rola de eu fazer um fork lá e implementar essa bagaça aí :stuck_out_tongue: , de qualquer forma acho que seria uma feature interessante e útil.

Valeu.

Estou usando a versao do vraptor 3.4.1

@Component
public class HoldingHelper {

private HoldingService holdingService;

public HoldingHelper(HoldingService holdingService) {
	this.holdingService = holdingService;
}

public List<Holding> getListaTudo() {
	return holdingService.listaTudo();
}

public List<Holding> listaTudo() {
	return holdingService.listaTudo();
}

}

e tentei usar na jsp ${holdingHelper.listaTudo} mas nao funcionou, fiz algo errado?

esse cara só vai ficar disponível se alguem pedí-lo como dependência, senão ele não é nem criado.

receba-o no construtor do controller onde vc quer usar isso, ou crie um interceptor que não faz nada, mas o recebe no construtor.