Spring MVC - Como acessar um Controller a partir de outro?

Olá!

Estou usando Spring MVC.

Quero criar um método que alguns Controllers compartilhem.

Como faço para acessar um Controller a partir de outro Controller?

Obrigado!

Oi,
Crie um servico em comum, e então use esse service nos controllers.
[]s,
Thiago.

Você pode criar um objeto comum quem ambos os controllers utilizam. Caso você precise que um controller chame o outro, pode fazer um redirect. Dê uma lida nesse post, pode te ajudar.

Obrigado, pessoal.

von.juliano, Tentei fazer do modo como está no post, mas não funcionou, o método do controller chamado não recebia os argumentos.

tveronezi, acabei fazendo o código em comum em um serviço mesmo, mas acredito que não deve ser a melhor solução. No caso do método precisar acessar atributos que estão nos controllers, será preciso passá-los por parâmetro. Acho que o método fica meio “deslocado” estando no serviço.

Tem a opção de colocar o método em um GenericController, mas como o método também não é usado por todos os controllers, não sei se fica bom.

O que será que geralmente é feito nesse caso (de código comum em alguns controllers)?

[quote=rt]Obrigado, pessoal.

von.juliano, Tentei fazer do modo como está no post, mas não funcionou, o método do controller chamado não recebia os argumentos.

tveronezi, acabei fazendo o código em comum em um serviço mesmo, mas acredito que não deve ser a melhor solução. No caso do método precisar acessar atributos que estão nos controllers,[/quote]

Como diria João Cleber ; pára, pára, pára, pára!

Controllers não têm atributos. Se vc está fazendo desse jeito está errado. Não admira que vc precise de acessar outros controlers.
O estado está todo no objeto de modelo nunca nos controlers.

No projeto que estou trabalhando, a arquitetura parece estar bem feita. Realmente, os controllers não têm atributos, exceto pelos services com anotação autowired.

Vou detalhar um pouco mais o meu caso:

As páginas do sistema têm um header em comum. Pensei em fazer um método para carregar as informações do header. Para não ficar replicando o mesmo método nos controllers, gostaria de criar o método em apenas um lugar.

Pensei em criar no GenericController (todos os controllers herdam ele), mas nem todos usuariam o método.

Acabei fazendo em um service. O controller que precisar carregar o header, chama o service, passa o usuário (que está na session), o ModelAndView (para ser populado com as informações) e mais algumas informações específicas da página.

Funciona, mas ao que me parece, não é papel de um service ter um método como esse, afinal, nem acessa o banco diretamente (mas chama outros services).

Como essa arquitetura poderia ser melhorada?

Será que usar um Interceptor do SpringMVC não seria melhor?

Você pode herdar de HandlerInterceptorAdapter, sobrescrever o postHandle e adicionar as informações que precisa no modelo. Como o Interceptor é um bean você pode injetar o seu serviço nele.

Você ainda tem a flexibilidade de escolher as requisições que serão interceptadas.

[quote=rt]No projeto que estou trabalhando, a arquitetura parece estar bem feita. Realmente, os controllers não têm atributos, exceto pelos services com anotação autowired.

Vou detalhar um pouco mais o meu caso:

As páginas do sistema têm um header em comum. Pensei em fazer um método para carregar as informações do header. Para não ficar replicando o mesmo método nos controllers, gostaria de criar o método em apenas um lugar.

Pensei em criar no GenericController (todos os controllers herdam ele), mas nem todos usuariam o método.

Acabei fazendo em um service. O controller que precisar carregar o header, chama o service, passa o usuário (que está na session), o ModelAndView (para ser populado com as informações) e mais algumas informações específicas da página.

Funciona, mas ao que me parece, não é papel de um service ter um método como esse, afinal, nem acessa o banco diretamente (mas chama outros services).

Como essa arquitetura poderia ser melhorada?[/quote]

Realmente um service não é uma boa. Pela simples razão que um service não pode acessar o ModelAndView

Uma opção é a que o wagnerfrancisco falou. Que é talvez a menos intrusiva. Mas isto é tipicamente um caso onde vc usaria uma método utilitário. Então vc pode criar um AbstractHeaderAwareControler que tem esse método como um protected e os outros controllers filhos dele podem usar. Repare que está usando herança, mas nada tão poderoso quanto GenericControler. Não são todos os controlers que precisam herdar deste abstract (como vc mesmo falou).

Se não quiser usar herança pode usar um Utils da vida , por exemplo HeaderReaderUtils, mas quando vc passa o usuário isso significa que existe uma regra de negocio em algum ponto ai, e o utils começa a ficar estranho. Nesse caso vc pode usar uma classe normal, um HeaderReader ou HeaderProcessor que vc injeta no controler que vc quiser usar e usa do mesmo jeito que vc está usando o serviço ( na realidade é só renomear o seu serviço e colocá-lo no pacote dos controlers ( ou perto).

Em web ha muitas opções e sem saber mais sobre o que realmente faz esse metodo e porque ele precisa do user , não ha uma solução vencedora.
Eu desconfio que tenha alguma coisa que ver com cookies e algum tipo de control de segurança ou sessão. Se é isso então o filtro ( o interceptor) é realmente a melhor opção, porque isso é um cross-cutting concern que nenhum controle deveria ter comando sobre. O controler simplesmente usa a info que estiver no modelView e pronto. Quem a pôs lá não importa.