Boa Tarde, e o seguinte nao sei se isto e BUG ou e a forma convencao do VRaptor 3.
@Resource
public class CadUfController {
private final Result result;
private final BeanCadUf beanCadUf;
private Validator validator;
private CadUf cadUf = new CadUf();
private List<CadUf> lista = new ArrayList<CadUf>();
public CadUfController(Result result, Validator validator, BeanCadUf beanCadUf) {
// TODO Auto-generated constructor stub
this.result = result;
this.beanCadUf = beanCadUf;
this.validator = validator;
}
//Editar
@Get
@Path("/caduf/{caduf.uf}")
public void editar(CadUf caduf) {
// TODO Auto-generated method stub
........
this.result.use(Results.logic()).forwardTo(getClass()).formulario();
}
//Localizar
@Get
@Path("/caduf/localizar")
public void localizar(ParametrosWeb parametrosweb) {
// TODO Auto-generated method stub
......
this.result.use(Results.logic()).forwardTo(getClass()).formulario();
}
}
Exception
2009-12-07 14:37:21.361:WARN::/jvds/caduf/localizar
java.lang.IllegalStateException: There are two rules that matches the uri '/caduf/localizar' with method GET: [[FixedMethodStrategy: uri /caduf/{caduf.uf} methods [GET]], [FixedMethodStrategy: uri /caduf/localizar methods [GET]]] with same priority. Consider using @Path priority attribute.
at br.com.caelum.vraptor.http.route.DefaultRouter.checkIfThereIsAnotherRoute(DefaultRouter.java:106)
at br.com.caelum.vraptor.http.route.DefaultRouter.parse(DefaultRouter.java:97)
at br.com.caelum.vraptor.http.DefaultResourceTranslator.translate(DefaultResourceTranslator.java:52)
at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:64)
at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:46)
at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:59)
at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:62)
at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:91)
at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:55)
at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:88)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:547)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Ja sei o porque deste erro no metodo localizar e so vc mudar o @Path("/caduf/localizar") para @Path(priority=2, value="/caduf/localizar") devido o metodo editar esta esperando o valor de {caduf.uf} = String entao ele esta entendo a URI /caduf/localizar como string tambem e esta dando conflito.
Pergunto ao pessoal ai o que voces acham sobre isso ?
Mas me parece confuso usar dois métodos com o mesmo path. Totalmente correto o vraptor lançar essa exception.
No caso do priority funcionar é que se você colocar o priority=2 no método localizar ele procura pelo path primeiro alí. Caso ele não achou passa pelo próximo conforme o que você indicou em priority.
Aliás isso não é rest, mas sim nice-urls. Rest é quando você trabalha com os estados do http: get, post, delete, trace, etc…
[quote=garcia-jj]Não entendi muito bem a pergunta…
Mas me parece confuso usar dois métodos com o mesmo path. Totalmente correto o vraptor lançar essa exception.
No caso do priority funcionar é que se você colocar o priority=2 no método localizar ele procura pelo path primeiro alí. Caso ele não achou passa pelo próximo conforme o que você indicou em priority.
Aliás isso não é rest, mas sim nice-urls. Rest é quando você trabalha com os estados do http: get, post, delete, trace, etc…[/quote]
Ok desculpa ai errei, mas pelo que entedi o @Path("/caduf/localizar") isto e diferente do primeiro metodo @Path("/caduf/{caduf.uf}") pq quando quero acessar metodo localizar eu digito no http://caduf/localizar certo ?
jvds, na verdade /caduf/{caduf.uf} indica que onde está {caduf.uf} é um wildcard. Sendo assim /caduf/{caduf.uf} e /caduf/localiza indicam a mesma coisa, já que internamente o vraptor usa um *.
O priority indica que o teste é feito na sequencia do menor para o maior. No seu exemplo colocando um priority=1 no /caduf/localiza e priority=2 em /caduf/{caduf.uf} o teste será feito primeiro no localiza. Então quando der true, ele executa e fim. Porém se você não indicar esse priority quando o vraptor for testar a url /caduf/localiza o teste em /caduf/{caduf.uf} vai retornar true, pois como já falei, {caduf.uf} é um wildcard.
[quote]Definindo prioridades para seus paths É possível que algumas das nossas URIs possa ser tratada por mais de um método da classe: @Resource
public class PostController {
@Get @Path("/post/{post.autor}")
public void mostra(Post post) { … }
@Get @Path("/post/atual")
public void atual() { … }
} A uri /post/atual pode ser tratada tanto pelo método mostra, quanto pelo atual. Mas eu quero que quando seja exatamente /post/atual o método executado seja o atual. O que eu quero é que o VRaptor teste primeiro o path do método atual, para não correr o risco de cair no método mostra. Para fazer isso, podemos definir prioridades para os @Paths, assim o VRaptor vai testar primeiro os paths com maior prioridade, ou seja, valor menor de prioridade: @Resource
public class PostController {
@Get @Path(priority = 2, value = “/post/{post.autor}”)
public void mostra(Post post) { … }
@Get @Path(priority = 1, value = “/post/atual”)
public void atual() { … }
}
Assim, o path “/post/atual” vai ser testado antes do “/post/{post.autor}”, e o VRaptor vai fazer o que a gente gostaria que ele fizesse. Você não precisa definir prioridades se tivermos as uris: /post/{post.id} e /post/atual, pois na /post/{post.id} o vraptor só vai aceitar números.[/quote]
[quote]Definindo prioridades para seus paths É possível que algumas das nossas URIs possa ser tratada por mais de um método da classe: @Resource
public class PostController {
@Get @Path("/post/{post.autor}")
public void mostra(Post post) { … }
@Get @Path("/post/atual")
public void atual() { … }
} A uri /post/atual pode ser tratada tanto pelo método mostra, quanto pelo atual. Mas eu quero que quando seja exatamente /post/atual o método executado seja o atual. O que eu quero é que o VRaptor teste primeiro o path do método atual, para não correr o risco de cair no método mostra. Para fazer isso, podemos definir prioridades para os @Paths, assim o VRaptor vai testar primeiro os paths com maior prioridade, ou seja, valor menor de prioridade: @Resource
public class PostController {
@Get @Path(priority = 2, value = “/post/{post.autor}”)
public void mostra(Post post) { … }
@Get @Path(priority = 1, value = “/post/atual”)
public void atual() { … }
}
Assim, o path “/post/atual” vai ser testado antes do “/post/{post.autor}”, e o VRaptor vai fazer o que a gente gostaria que ele fizesse. Você não precisa definir prioridades se tivermos as uris: /post/{post.id} e /post/atual, pois na /post/{post.id} o vraptor só vai aceitar números.[/quote][/quote]
um jeito de resolver isso, é transformar seu campo uf em uma enum (que é o certo, já que uf só tem um cj fixo de elementos)… daí as duas uris vão ser diferentes, e vc não vai ter que ficar validando se a UF é correta…
faça isso:
public enum UF {
SP, RJ, MG, ....
}
na sua classe Caduf (supondo que é do hibernate)
public class Caduf {
//...
@Enumerated(EnumType.STRING)
private UF uf;
}
[quote=lucascs]um jeito de resolver isso, é transformar seu campo uf em uma enum (que é o certo, já que uf só tem um cj fixo de elementos)… daí as duas uris vão ser diferentes, e vc não vai ter que ficar validando se a UF é correta…
faça isso:
public enum UF {
SP, RJ, MG, ....
}
na sua classe Caduf (supondo que é do hibernate)
public class Caduf {
//...
@Enumerated(EnumType.STRING)
private UF uf;
}