Olá…
O LinkTo me abriu o olho…
e realmente não to afim de repetir as URI… Ficou facil fazer isto na view com o linkTo…
Porém eu preciso pegar a URI de um método no lado servidor.
Existe uma maneira facil e ‘clean’ de fazer isso ?
obrigado!
EDIT
Eu quero pegar a URI do método, pq eu to fazendo uma feature que vou mandar
um link no email do cliente. Quero montar esse link dinamicamente.
E eu não quero correr o risco de mudar a URI do método mais tarde
e depois enviar emails com links quebrados. Isso seria mto feio né ?
kkkkkkkkk
Ja peguei o Host e o Context Path do request. Só falta a URI.
Existe… Use o result.redirectTo(Controller.class).action()…
não quero usar redirect !
Quero saber o path anotado do método
@Get("/get/algo")
public void index(){
}
algo tipo
String uri = LinkToHandler.getURI(ExemploController.class).index();
**EDIT
o valor da var uri seria “/get/algo”
Eu não sei se o VRaptor tem algo para isso… Podemos pesquisar.
Eu faria com reflection pegando o @Get e/ou @Path daquela action…
Existe um componente do VRaptor que sabe gerar as rotas: o Router
String url = router.urlFor(ExemploController.class, ExemploController.class.getDeclaredMethod("index"));
Ou seja, vc passa pra ele a classe, o método e os parâmetros desse método, e ele te dá a url.
o problema que isso lança exceptions chatas, vc pode usar o mirror pra refletir o método pra se livrar delas:
Method method = new Mirror().on(ExemploController.class).reflect().method("index").withoutArgs();
se vc acha que vai usar isso bastante, me dá um toque que eu te ajudo a escrever um componente maroto que faz isso de um jeito mais fácil
[quote=Lucas Cavalcanti]Existe um componente do VRaptor que sabe gerar as rotas: o Router
String url = router.urlFor(ExemploController.class, ExemploController.class.getDeclaredMethod("index"));
Ou seja, vc passa pra ele a classe, o método e os parâmetros desse método, e ele te dá a url.
o problema que isso lança exceptions chatas, vc pode usar o mirror pra refletir o método pra se livrar delas:
Method method = new Mirror().on(ExemploController.class).reflect().method("index").withoutArgs();
se vc acha que vai usar isso bastante, me dá um toque que eu te ajudo a escrever um componente maroto que faz isso de um jeito mais fácil ;)[/quote]
cara… legal !
não sei se vou usar bastante… mas bora fazer o componente ?
blz, a graça desse componente é vc conseguir descobrir a classe e o método ‘magicamente’. Tipo isso:
Linker linker = //
linker.buildLinkTo(ExemploController.class).index();
String url = linker.getUrl();
não dá pra fazer em um passo só, pq o index retorna void
a idéia é esse Linker receber um proxifier no construtor e gerar um proxy no buildLinkTo que captura o método invocado e os parâmetros e no getUrl usa essas informações para passar para o Router.
Se precisar de mais ajuda dá um toque.
Legal…
Acho que entendi a ideia…
Mas vou precisar de uma aulinha sua !!
Você se impota?
Eu fiz um esboço… Mas fiz seguindo tuas palavras e sem entender
muito bem o que estou fazendo… O que é horrível
Então… O que o Proxifier retorna? (Não me diga um Object ! kkk)
Como que funciona ? Quem que vai pegar o retorno dele?
Se eu quiser fazer uns testes de unidade no Linker, como injeto componentes do VRaptor no meu test?
Ta aqui o que eu fiz até agora:
@Component
public class Linker {
private Logger logger = Logger.getLogger(Linker.class);
private Proxifier proxifier;
private Router router;
private Class<?> clazz;
private Method invokedMethod;
private Object[] arguments;
public Linker(Proxifier proxifier, Router router) {
this.proxifier = proxifier;
this.router = router;
proxifier.proxify(Linker.class, new MethodInvocation<Linker>() {
@Override
public Object intercept(Linker proxy, Method method, Object[] args, SuperMethod superMethod) {
invokedMethod = method;
arguments = args;
return null;
}
});
}
public String getURI(){
return router.urlFor(clazz, invokedMethod, arguments);
}
public <T> T buildLinkTo(Class<T> clazz){
this.clazz = clazz;
try {
return clazz.newInstance();
} catch (InstantiationException e) {
logger.error("Can´t instanciate class: "+clazz.getSimpleName(), e);
e.printStackTrace();
} catch (IllegalAccessException e) {
logger.error("Error on "+clazz.getSimpleName(), e);
e.printStackTrace();
}
return null;
}
}
Obrigado
O proxifier retorna um proxy da classe que vc passou…
e daí vc passa um interceptor que executa o código que vc quiser. Nesse caso o que vc quer fazer é capturar o método.
a sua classe está quase pronta, só que ao invés do proxifier.proxify estar no construtor ele tem que estar no buildLinkTo:
public <T> T buildLinkTo(Class<T> clazz){
this.clazz = clazz;
return this.proxifier.proxify(clazz, new Method.....) {..};
}
para testar, vc tem que passar um proxifier de verdade (é meio difícil de testar), pode ser o new JavassistProxifier(), e passar um mock do Router. Daí vc verifica que ele chamou o urlFor passando a classe e o método esperados.
[quote=Lucas Cavalcanti]O proxifier retorna um proxy da classe que vc passou…
e daí vc passa um interceptor que executa o código que vc quiser. Nesse caso o que vc quer fazer é capturar o método.
a sua classe está quase pronta, só que ao invés do proxifier.proxify estar no construtor ele tem que estar no buildLinkTo:
[/quote]
ta… mas o que o meu método intercept tem que retornar? Pq eu to retornando null…
Aqui com as modificações que vc falou
...
@SuppressWarnings("unchecked")
public <T> T buildLinkTo(Class<T> clazz){
this.clazz = clazz;
return (T) proxifier.proxify(Linker.class, new MethodInvocation<Linker>() {
@Override
public Object intercept(Linker proxy, Method method, Object[] args, SuperMethod superMethod) {
invokedMethod = method;
arguments = args;
return null;
}
});
}
pode retornar null sem problemas… a gente não usa o retorno do método pra nada.
cara,
como que a proxy vai ficar na classe que o cara passou se eu não posso:
return (T) proxifier.proxify(clazz, new MethodInvocation<clazz>() {
?
bom , eu pensei…
vou olhar no vraptor como que o Result funciona né…
ai olhei esta classe:
/***
* 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.core;
import static br.com.caelum.vraptor.view.Results.logic;
import static br.com.caelum.vraptor.view.Results.page;
import static br.com.caelum.vraptor.view.Results.status;
This file has been truncated. show original
e MANO do céu, de onde saiu esse método use() ?
a gente tem ele na interface:
/***
* 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;
import java.util.Map;
This file has been truncated. show original
mas onde que ele é implementado ?
falei brincando com um amigo meu que o pessoal da Caelum tava mexendo com bruxaria…
Agora eu tô com medo de que seja verdade!
asdjiashudahusdhuasd
abraços
é implementado no DefaultResult…
vc pode fazer:
return (T) proxifier.proxify(clazz, new MethodInvocation<T>() {
afinal, o clazz é um Class
Nossa que mancada!
x]
vlww mano…
muito obrigado !!!