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!
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.
[quote=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.[/quote]
Lucas, pode me dar um exemplo?
Muito Obrigado cara!
@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
}
}
Lucas, pode me dar um outro exemplo? Alguma implementação.
Não sei como usar essa classe.
Obrigado cara!
os métodos protected tem nomes razoavelmente claros… dá uma olhada na implementação padrão:
/***
* Copyright (c) 2009 Caelum - www.caelum.com.br/opensource
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package br.com.caelum.vraptor.http.route;
import static com.google.common.base.Preconditions.checkArgument;
This file has been truncated. show original
Tem razão Lucas, vi a implementação padrão.
Vou implementar aqui e depois posto como fiz.
Valeu! Abração!
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!
precisa sobrescrever outro componente, o PathResolver…
a implementação padrão é a DefaultPathResolver.
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!
Desculpe, falha minha. Era um erro no controller.
Está tudo certo agora!
Obrigado Lucas!
[quote=bglbruno]Tem razão Lucas, vi a implementação padrão.
Vou implementar aqui e depois posto como fiz.
Valeu! Abração![/quote]
Bruno, voce teria condições de postar a solução de seu problema? estou com o mesmo desafio!
Grato,
Jorel
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.
[code]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];
}
}[/code]
Espero que minha solução tenha ajudado.
mr Lucas, sera que da forma que eu fiz ta muito primata?
[code]@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();
}
}[/code]
eu só usaria ao invés do stringBuilder:
return String.format("/WEB-INF/jsp/%s/%s/%s.jsp", modulo[4], controller, method);
f4314n0
Abril 26, 2012, 10:03pm
#16
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);
}
}
é quase isso… só olhar a implementação padrão
}
protected String getPrefix() {
return "/WEB-INF/jsp/";
}
protected String getExtension() {
return "jsp";
}
protected String extractControllerFromName(String baseName) {
baseName = lowerFirstCharacter(baseName);
if (baseName.endsWith("Controller")) {
return baseName.substring(0, baseName.lastIndexOf("Controller"));
}
return baseName;
}
private static String lowerFirstCharacter(String baseName) {
return baseName.toLowerCase().substring(0, 1) + baseName.substring(1, baseName.length());
}
f4314n0
Abril 26, 2012, 10:47pm
#18
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!