[RESOLVIDO] VRaptor - Redirect não funciona corretamente

12 respostas
denilsont

Ao salvar um ítem ocorrendo sucesso, capturo o id e tentamos redirecionar pra view(id)

public void salvar(Objeto objeto) {
    ...
     result.use(Results.logic()).redirectTo(NomeController.class).view(registro.getId());
}

@Get({ "/{id}", "/", ""})
public void view(long id) throws Exception {
 ...
}

Estou usando um controlador genérico para tanto, a view é executada corretamente, e o objeto do modelo é preenchido corretamente, mas o redirect está indo para a defaultview, ou seja, está indo para a ação (url) da view sem o parâmetro.

Pelo debug parece que está tudo certo, mas a url final está errada, faltando o parametro.

[/code]
17:25:36,483 DEBUG [DefaultLogicResult ] redirecting to class TurmaController
17:25:36,548 DEBUG [CglibProxifier ] a proxy for class br.com.flexait.esab.controller.curso.TurmaController is created as class br.com.flexait.esab.controller.curso.TurmaController$$EnhancerByCGLIB$$7ff53851
17:25:36,551 DEBUG [DefaultLogicResult ] redirecting to /esab/admin/curso/turma/
17:25:36,554 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ForwardToDefaultViewInterceptor
17:25:36,554 DEBUG [ForwardToDefaultViewInterceptor] Request already dispatched and commited somewhere else, not forwarding.
17:25:36,585 DEBUG [VRaptor ] VRaptor ended the request
17:25:36,613 DEBUG [VRaptor ] VRaptor received a new request
17:25:36,637 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor
17:25:36,637 DEBUG [DefaultResourceTranslator] trying to access /admin/curso/turma/
17:25:36,639 DEBUG [DefaultResourceTranslator] found resource [DefaultResourceMethod: TurmaController.viewTurmaController.view(long)]
17:25:36,642 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor FlashInterceptor
17:25:36,651 DEBUG [LazyInterceptorHandler] Invoking interceptor ParametersInstantiatorInterceptor
17:25:36,652 DEBUG [ParametersInstantiatorInterceptor] Parameter values for [DefaultResourceMethod: TurmaController.viewTurmaController.view(long)] are [20]
17:25:36,653 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor InstantiateInterceptor
17:25:36,670 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExceptionHandlerInterceptor
17:25:36,672 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor EnvironmentInterceptor
17:25:36,674 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor FlexaInterceptor
17:25:36,676 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor HibernateTransactionInterceptor
17:25:36,677 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExecuteMethodInterceptor
17:25:36,678 DEBUG [ExecuteMethodInterceptor] Invoking TurmaController.view(long)

17:26:14,858 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ForwardToDefaultViewInterceptor
17:26:14,858 DEBUG [ForwardToDefaultViewInterceptor] forwarding to the dafault page for this logic
17:26:14,877 DEBUG [DefaultPageResult ] forwarding to /WEB-INF/jsp/curso/turma/view.jsp
17:26:14,878 DEBUG [DefaultStaticContentHandler] Deferring request to container: /esab/WEB-INF/jsp/curso/turma/view.jsp
[code]

12 Respostas

Lucas_Cavalcanti

registro.getId() está preenchido?

denilsont

sim, tanto que no log está printando

TurmaController.viewTurmaController.view(long)] are [20]

Lucas_Cavalcanti

o problema é que no método view ele tá redirecionando pra página errada, eh isso?

denilsont

exatamente

as actions view são para list e edit

com parametro id é edit e sem é list

view //listagem
view/1 //edição do ítem 1

após o save vai pra view e não view/1 como desejado

esta mensagem parece ser o problema, mas não entendo como resolver
Request already dispatched and commited somewhere else, not forwarding

Lucas_Cavalcanti

com certeza esse erro dá uma dica: tem duas manipulaçoes do response acontecendo (tipo dois forwards ou redirects)…

posta aqui os métodos que participam dessa requisição problemática… posta pelo as partes que interagem com o vraptor.

denilsont
public abstract class BaseCrudController<T> {

        @Post
	public void salvar(T objeto) throws Exception{
		try {
			IModel registro = (IModel) classeDao.saveOrUpdate(objeto);
		    //Incluo uma variavel informando que o registro acabou de ser salvo com sucesso
			result.include("salvocomsucesso", "1");
			
			//Redireciono para a view relativa a classe em questao
			Long id = registro.getId();
			result.redirectTo(TurmaController.class).view(id); //coloquei diretamente o TurmaController para testar
			
		} catch (Exception e) {
			showError(e.getMessage(), true);
		} 
	}
}
@Resource
@Path("/admin/turma")
public class TurmaController extends BaseCrudController<Turma>{
  ...
  o método salvar está sendo invocado do base
}
public abstract class GenericCrudDao<T> implements Serializable{
     public T saveOrUpdate (T p) throws Exception
	{
		T saida = null;
	    saida  =  (T) session.merge(p);
	    
	    return saida;
	}
}
[/code] public class TurmaDao extends GenericCrudDao{ ... a função saveOrUpdate é chamada do Generic pelo BaseController } [code]

tenho outros controllers com a mesma estrutura que funciona, alguns não funcionam, como exemplo este.
será que não pode ter haver com o bug reportado em https://github.com/caelum/vraptor/issues/464, pois são justamente as classes que o linkTo não funciona
estou usando JDK 7

Lucas_Cavalcanti

com o redirect direto pra TurmaController tb não funciona, eh isso?

existe mais de um método view no controller?

e tenta trocar isso:

@Get({ "/{id}", "/", ""})

por isso:

@Get("/{id}")
denilsont

Funcionou Lucas.

Eu inverti a ordem no array assim e também funcionou: //na verdade esta éra a ordem do BaseController

@Get({ "/{id}", "/ajax/{id}", "/" })

Você acha que tem problema usar a mesma action para duas opções, como add e edit.
Estamos usando:

view(0) //add
view(id) //edit do ítem id

Lucas_Cavalcanti

problema é se metade do método tá no if e a outra tá no else… daí seria melhor ter feito métodos diferentes.

se vc vai reaproveitar a grande maioria dos métodos, não tem problema.

denilsont

Entendi,

Neste caso, como está no BaseController, eu preticamente não escrevo este método nos especializados, e quando quero uma logica a mais, apenas sobrescrevo executando o super.
Mas realmente ele cai vezes no if e vezes no else, sendo transparente pra mim.
Neste caso que você disse melhor ser diferente?
Por causa de performance, ou apenas legibilidade?

Após esta resposta, como marca como resolvido, apenas mudando o título?

Muito obrigado pelo help.

Lucas_Cavalcanti

é mais legibilidade… a diferença de performance é indiferente nesse caso… é melhor ter 2 métodos de 15 linhas do que ter 1 de 30…

pra colocar resolvido é só mudar o título sim.

denilsont

vlw Lucas

Criado 26 de outubro de 2012
Ultima resposta 3 de nov. de 2012
Respostas 12
Participantes 2