[RESOLVIDO] VRaptor - Módulos ERP - URL

17 respostas
B

Olá Galera!

Meu sistema ERP, tem vários módulos (Financeiro, Operacional, Compras, RH, etc), estou usando VRaptor.

Gostaria de implementar o seguinte

Suponhamos que eu tenha um FuncionarioController, que pertence ao módulo RH.
Então, na WEB-INF/jsp eu tenho a pasta funcionario/ com todos .jsp’s necessário dele. E a URL padrão seria /sistema/funcionario

O que eu quero, é mudar essa URL, fazer por exemplo /sistema/rh/funcionario, ou então numa outra situação /sistema/operacional/frete

Só que não quero anotar todos os métodos com o @Path.

Há uma forma de fazer isso?
Gostaria de dicas. Como vocês implementariam algo assim?

Obrigado!

17 Respostas

L

você pode sobrescrever o componente RoutesParser do VRaptor, colocando a convenção que você quiser.

um dos jeitos é criar uma classe que estende PathAnnotationRoutesParser, e sobrescreve um dos métodos protected dela.

B

Lucas Cavalcanti:
você pode sobrescrever o componente RoutesParser do VRaptor, colocando a convenção que você quiser.

um dos jeitos é criar uma classe que estende PathAnnotationRoutesParser, e sobrescreve um dos métodos protected dela.

Lucas, pode me dar um exemplo?

Muito Obrigado cara!

L
@Component
@ApplicationScoped
public class MeuRoutesParser extends PathAnnotationRoutesParser {
    
    //delegate constructor

    @Override
    protected String[] urisFor(Method method, Class<?> type) {
         // sua convenção aqui, talvez usando o super.urisFor
    }
}
B

Lucas, pode me dar um outro exemplo? Alguma implementação.
Não sei como usar essa classe.

Obrigado cara!

L

os métodos protected tem nomes razoavelmente claros… dá uma olhada na implementação padrão:

B

Tem razão Lucas, vi a implementação padrão.
Vou implementar aqui e depois posto como fiz.

Valeu! Abração!

B

Cara, consegui implementar, mas notei que preciso fazer uma outra coisa também.
Por exemplo, A url padrão agora é /sistema/operacional/frete, certo, mas o vraptor procura em WEB-INF/jsp/frete

Como faço para o vraptor procurar em WEB-INF/jsp/operacional/frete?

Obrigado!

L

precisa sobrescrever outro componente, o PathResolver…

a implementação padrão é a DefaultPathResolver.

B

Lucas, eu implementei o meu PathResolver

@Component
public class ModuloPathResolver extends DefaultPathResolver{

	private FormatResolver resolver;

	public ModuloPathResolver(FormatResolver resolver) {
		super(resolver);
		this.resolver = resolver;
	}
	
	@Override
	public String pathFor(ResourceMethod method) {
		String format = this.resolver.getAcceptFormat();

		String suffix = "";
		if (format != null && !format.equals("html")) {
			suffix = "." + format;
		}
        String name = method.getResource().getType().getSimpleName();
        String folderName = extractControllerFromName(name);
        
		return this.getPrefixo(folderName) + folderName + "/" + method.getMethod().getName() + suffix
				+ "."+getExtension();
	}
	
	private String getPrefixo(String controller) {
		return "/WEB-INF/jsp/" + this.getModulo(controller);
	}

	private String getModulo(String controller) {
		String modulo = "";
		if( controller.contains("frete") ){
			modulo = "operacional/";
		}	
		return modulo;
	}
}

Mas, quando tento acessar /sistema/operacional/frete ele não procura no lugar correto, ou não acha o controller, não sei.

No log normalmente aparece assim, quando acesso uma outra url qualquer do sistema

16:28:20,721 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ForwardToDefaultViewInterceptor
16:28:20,721 DEBUG [ForwardToDefaultViewInterceptor] forwarding to the dafault page for this logic
16:28:20,739 DEBUG [DefaultPageResult   ] forwarding to /WEB-INF/jsp/funcionario/list.jsp
16:28:20,741 DEBUG [DefaultStaticContentHandler] Deferring request to container: /sistema/WEB-INF/jsp/funcionario/list.jsp 
16:28:20,814 DEBUG [VRaptor             ] VRaptor ended the request

Mas quando acesso a url que estou tentando “filtrar”, aparece assim

16:29:00,026 DEBUG [VRaptor             ] VRaptor received a new request
16:29:00,056 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor
16:29:00,056 DEBUG [DefaultResourceTranslator] trying to access /operacional/frete
16:29:00,057 DEBUG [VRaptor             ] VRaptor ended the request

Preciso fazer mais alguma configuração?

Obrigado!

B

Desculpe, falha minha. Era um erro no controller.
Está tudo certo agora!

Obrigado Lucas!

J

bglbruno:
Tem razão Lucas, vi a implementação padrão.
Vou implementar aqui e depois posto como fiz.

Valeu! Abração!

Bruno, voce teria condições de postar a solução de seu problema? estou com o mesmo desafio!

Grato,

Jorel

N

Eu consegui resolver o problema da seguinte forma.

Meu sistema esta distribuído em pacotes.
Ex:
br.com.exemplo.modulo
br.com.exemplo.modulo2
e assim por diante, queria identificar automaticamente o modulo de acordo o pacote então consegui através da seguinte.

package br.com.exemplo.modulo.http;

import br.com.caelum.vraptor.http.FormatResolver;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.resource.ResourceMethod;
import br.com.caelum.vraptor.view.DefaultPathResolver;

@Component
public class ModuloPathResolver extends DefaultPathResolver {

	private FormatResolver resolver;

	public ModuloPathResolver(FormatResolver resolver) {
		super(resolver);
		this.resolver = resolver;
	}

	@Override
	public String pathFor(ResourceMethod method) {
		String format = resolver.getAcceptFormat();

		String suffix = "";
		if (format != null && !format.equals("html")) {
			suffix = "." + format;
		}
		String name = method.getResource().getType().getSimpleName();
		String folderName = extractControllerFromName(name);
		
        // Mágica acontece aqui, onde é identificado o pacote da classe onde será processada a requisição
		String pacote = method.getResource().getType().getPackage().getName();
		String modulo = getModulo( pacote );
		
		return getPrefix() + modulo + "/" + folderName + "/" + method.getMethod().getName()
				+ suffix + "." + getExtension();
	}

	/**
	 * Identifica o modulo de acordo com o 
	 * pacote que esta inserida o Controller que processará a requisição.
	 * 
	 * @param String pacote
	 * @return String
	 */
	private String getModulo(String pacote) {
		String[] pacotes = pacote.split("\\.");
		return pacotes[3];
	}
}

Espero que minha solução tenha ajudado.

F

mr Lucas, sera que da forma que eu fiz ta muito primata?

@Component  
public class JspPathResolver  
    implements PathResolver {  
	
	@Override  
    public String pathFor(ResourceMethod method) {  
    	final Class<?> clazz = method.getResource().getType();  
        final String clazzName = clazz.getSimpleName();  
        final Package pkg = clazz.getPackage();
        String modulo[] = pkg.getName().split("\\.");
        
        final StringBuilder s = new StringBuilder();  
        s.append("/WEB-INF/jsp/");  
        
        s.append(modulo[4]);
        s.append("/");  
        s.append(StringUtils.substringBefore(clazzName, "Controller").toLowerCase());
        s.append("/");
        s.append(method.getMethod().getName().toLowerCase());
        s.append(".jsp");  
  
        return s.toString(); 
    }  
}
L

eu só usaria ao invés do stringBuilder:

return String.format("/WEB-INF/jsp/%s/%s/%s.jsp", modulo[4], controller, method);
F

mmmm como voce pega o controller?
tentei assim mas acho que nao é isso:

@Component  
public class JspPathResolver  
    implements PathResolver {  
	
	@Override  
    public String pathFor(ResourceMethod method) {  
    	final Class<?> clazz = method.getResource().getType();  
        final String clazzName = clazz.getSimpleName();  
        final Package pkg = clazz.getPackage();
        String modulo[] = pkg.getName().split("\\.");
        String controller = StringUtils.substringBefore(clazzName, "Controller").toLowerCase();
        
        return String.format("/WEB-INF/jsp/%s/%s/%s.jsp", modulo[4], controller, method);  
    }  
}
L
é quase isso…  olhar a implementação padrão <img src="//https://cdn.jsdelivr.net/gh/twitter/twemoji@14/assets/72x72/w.pngink.png?v=5" title=":wink:" class="emoji" alt=":wink:">

<aside class="onebox githubblob">
  <header class="source">
      <a href="https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/view/DefaultPathResolver.java#L62" target="_blank">github.com</a>
  </header>
  <article class="onebox-body">
    <h4><a href="https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/view/DefaultPathResolver.java#L62" target="_blank">caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/view/DefaultPathResolver.java#L62</a></h4>
<pre class="onebox"><code class="lang-java"><ol class="start lines" start="52" style="counter-reset: li-counter 51 ;">
<li>	}</li>
<li>
</li>
<li>	protected String getPrefix() {</li>
<li>		return "/WEB-INF/jsp/";</li>
<li>	}</li>
<li>
</li>
<li>	protected String getExtension() {</li>
<li>		return "jsp";</li>
<li>	}</li>
<li>
</li>
<li class="selected">	protected String extractControllerFromName(String baseName) {</li>
<li>	baseName = lowerFirstCharacter(baseName);</li>
<li>	if (baseName.endsWith("Controller")) {</li>
<li>		return baseName.substring(0, baseName.lastIndexOf("Controller"));</li>
<li>	}</li>
<li>	return baseName;</li>
<li>	}</li>
<li>
</li>
<li>	private static String lowerFirstCharacter(String baseName) {</li>
<li>	return baseName.toLowerCase().substring(0, 1) + baseName.substring(1, baseName.length());</li>
<li>	}</li>
</ol>
F

hehe… assim funcionou mestre Lucas:

@Component  
public class JspPathResolver  
    implements PathResolver {  
	
	@Override  
    public String pathFor(ResourceMethod method) {  
    	final Class<?> clazz = method.getResource().getType();  
        final String clazzName = clazz.getSimpleName();  
        final Package pkg = clazz.getPackage();
        
        String modulo[] = pkg.getName().split("\\.");
        String controller = StringUtils.substringBefore(clazzName, "Controller").toLowerCase();
        String metodo = method.getMethod().getName().toLowerCase();
        String recurso = String.format("/WEB-INF/jsp/%s/%s/%s.jsp", modulo[4], controller, metodo);
        
        return recurso;
    }  
}

era isso mesmo?
obrigado e um abraço!

Criado 11 de novembro de 2011
Ultima resposta 26 de abr. de 2012
Respostas 17
Participantes 5
Fiap Graduacao em Tecnologia — FIAP Analise e Desenvolvimento de Sistemas, Engenharia de Software e mais
Casa do Codigo Casa do Codigo — Livros de tecnologia Livros de programacao, infraestrutura e inovacao