Dúvida com FrontController?

Olá galera…
eu tenho uma pergunta meu boba…
Por acaso se eu criar om FrontController (Servlet) eu poderia redirecionar ela pra outra servlet?
Digamos, estaria saindo da “função” do FrontController?

Valeu

Eu acredito que a função de redirecionamento entre recursos de uma aplicação, é função do controller.
Mas não sei até onde é gerar trabalho desnecessário enviar a requisição para um controller pra depois re-enviar para outro front controller, se pode-se enviar de um front controller diretamente para outro.

De qualquer forma, um trecho da especificação do front controller:

[quote=Rafael Nunes]Mas não sei até onde é gerar trabalho desnecessário enviar a requisição para um controller pra depois re-enviar para outro front controller, se pode-se enviar de um front controller diretamente para outro.
[/quote]
Desculpe não consegui entender totalmente o que você quis dizer com isso.
Quanto ao redirecionar a requisição eu entendi.
Você está pensando que a minha intenção seria isso?
FrontController -> FrontController ->Servlet?
[obs]
não que o FrontController não deixe de ser um servlet(neste caso)
[/obs]
outro dia eu estava vendo um código ± assim:
frontController

getActionCollection():
  return actions;

doPost:
Hashtable actions = getActionCollection();
BaseAction action = actions.get("pagina");
if (action==null) synchronized (actions) {
    action = instantiate(mapName("pagina"));
// instantiate
// gera uma nova instancia do  servlet
// mapName pega o caminho completo
    actions.put(actionName,action);
}
action.doPost(req,resp);

Por acaso teria algum problema em fazer isso?
ou seria melhor eu dar um dispatcher nele?

valeu

Li alguns autores que recomendam vc ter uma frontcontroler que realiza todas as ações relacionadas.
ex:

Você tem uma tela que tem vários passos:
1-2-3…

O FrontController realizaria todos os passos epoderia redirecionar para diversos views diferentes.
Nunca vi ninguém especificar que um view tenha que ser uma JSP.
Pode ser um HTML, um XML, e porque não uma servlet.
Agora se sua servlet contém lógica de negócios é melhor deixar tudo m um único controler desde de que essa lógica esteja relacionada com a mesma tarefa.

É, nunca tinha pensado nisso.
Se eu tiver um FrontController, eu vou precisar de um Controller?
Minha idéia era de se usar o FrontController pra executar os processamentos necessários, e um Controller só para receber e direcionar requisições.

Ex:
FontrControlle->Controller->FrontController2->View

[edit]
É, pelo que vi no Core J2EE Patterns, é assim mesmo como eu imaginei, o Controller recebe e dispacha requisições, o FrontController as processa.

Na prova isso apesar de ser simples pode confundir um pouco.
MVC e FrontController.

A arquitetura que tem o controller principal é o MVC.
Cada unidade de processamento seria o FrontController neste caso.

EDITADO:

Aqui em cima escrevi errado, queria escrever frontcontroller

Kina… eu costumo utilizar a estratégia front-controller e command!

Então fica assim:

view- --> FrontController --> Command --> negocio --> persistencia

Você pode também criar uma fábrica de commands para facilitar sua vida!
No meu caso, meu frontcontroller recebe a requisição, pega um atributo chamado op (operação), e de acordo com o valor deste atrributo eu sei qual é a operação que ele irá realizar! Então é só vc chamar um command apropriado para executar aquela função. O command por sua vez, executa todo o processamente relacionada a esta operação, e retorna para o frontController o resultado, que no meu caso, é a página que o frontcontroller deverá redirecionar!

O FrontController é um servlet, mas o command é uma classe normal, que não estende servlet. Não sei se é uma boa prática, mas meus commands receber o HttpRequest e o HttpResponse em um método chamado execute!

Tirei este exemplo do livro Core J2ee patterns!

Abraços!
Thiago

Você tem um FrontController único que recebe o parâmetro ‘op’ e dispacha para o Command apropriado?

Exatamente!!! Eu meu sistema inteiro eu tenho um único Controle!

Então você não tem um FrontController, você tem um Controller. FrontController seria específico de cada serviço.

[edit]Se bem que na documentação, diz que você pode ter mais de um controller, nãoq ue você deva ter. Sendo assim, não vejo a diferença entre um MVC e um FrontController com um único controller

Rafael!

Esse diagrama que você colocou em cima é uma Herança!

Isso quer dizer que o ServletFront ou o JSPFront herdam características do controle!

Vc pode ou usar JSP como camada de controle(não recomendado) ou uma Servlet!

No meu caso, eu não criei uma interface ou classe abstrata com o nome Controle, mas é uma estratégia interessante também.

Também não há problemas em ter mais de um FrontController. Mas eu pessoalmente prefiro um único controle!!!

E qual a diferença entre um MVC e um FrontController com um único Controller?

Pelo que vi um MVC se caracteriza por ter vários views diferentes para o mesmo seviço.
EDITADO:
Como o Thiago disse não precisa ser um ambiente web.

Eu entendi essa como a principal diferença.

Agora o Thiago colocou uma coisa super importante:

Deixar o controller desacoplado do ambiente web o maior possivel, pois se uma dia precisar mudar para desktop ou outra coisa será bem mais fácil.

Agora JSP como controller fica muito ruim.
Código java no JSP vira uma meleca…

Naum entendi o motivo da pergunta! Mas vamos lá! :smiley:

MVC é uma arquitetura que separa modelo (objetos de negócio), visualização (view) e o controle (operações solicitadas pelo usuário).

Não há igualdade ou diferença dentre FrontController e MVC. O FrontController só é um pattern que você utiliza dentro do MVC para implementar a camada de Controle! Ou seja, FrontController é um pattern, e ele por si só não é MVC.

Imagine também que é possível usar MVC em uma aplicação Swing. Daí eu te pergunto. É possível usasr um servlet como controle em uma aplicação Swing? Bom… talvez até dê… mas é uma verdadeira gambiarra!

Isso só demonstra que existem várias maneiras de você implementar sua camada de controle e ainda atender o padrão MVC.

No livro core j2ee paterns, você perceberá que existe mais de uma estratégia para se implementar a camada de controle. Existe um que o livro aborda com mais profundidade (não sei qual é) e um uma outra estratégia que eles falam bém brevemente, que é o command and controller!

E é exatamente a estratégia Command and Controller que adotei para o sistema que estou desenvolvendo.

Observe que a camada de controle vai além de um FrontController. A camada de controle na verdade é o FrontController junto com todos os commands que realizam as operações solicitadas pelo usuário. Isso tudo junto é a camada de controle! Como eu uso commands, não há motivo de sair criando servlets e outros Fronts controllers, basta receber a requisição do usuário e encaminhá-lo para o command.

Abraços!
Thiago

[quote=JProgrammer] Agora o Thiago colocou uma coisa super importante:
Thiago Senna wrote:

O FrontController é um servlet, mas o command é uma classe normal, que não estende servlet. Não sei se é uma boa prática, mas meus commands receber o HttpRequest e o HttpResponse em um método chamado execute!

Deixar o controller desacoplado do ambiente web o maior possivel, pois se uma dia precisar mudar para desktop ou outra coisa será bem mais fácil. [/quote]

Concordo JProgrammer. Com esssa colocação que você fez já tira uma dúvida minha. Como meu command recebeo request e o response por parâmetro, então seria difícil reaproveitar estes commands fora da aplicação web. Ou seja, seria interessante bolar uma estratégia na qual o command não precise receber o request e o response, daí sim estariamos mais próximo de reaproveitar os commands em uma aplicação desktop por exemplo!

Abraços!
Thiago

Achei bem legal sua ideia.

Bom… não sei se isso vai ajudar muito!
Não é exatamente o que estou fazendo, mas nesta aplicação é um controle para aplicação toda. Acho!

http://java.sun.com/blueprints/code/jps131/src/

Dêem uma cheretada neste link… eu nunca explorei muito este material… mas pode ajudar!

Abraços!

A fonte é esta:

http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html

Para ter uma idéia, meu código do controle é quase isso aqui…

[code]
/** This processRequest method is invoked from both

  • the servlet doGet and doPost methods **/
    protected void processRequest(HttpServletRequest
    request, HttpServletResponse response)
    throws ServletException, java.io.IOException {

String resultPage;
try {
RequestHelper helper = new RequestHelper(request);

/** the getCommand() method internally uses a 
 factory to retrieve command objects as follows:
 Command command = CommandFactory.create(
    request.getParameter("op"));
**/
 Command command =  helper.getCommand();

// delegate request to a command object helper
resultPage = command.execute(request, response);

}
catch (Exception e) {
LogManager.logMessage(“EmployeeController”,
e.getMessage() );
resultPage = ApplicationResources.getInstance().
getErrorPage(e);
}

dispatch(request, response, resultPage);
}[/code]

ùnica observação que tenho para fazer é que tenho um interface que armazena para mim todas as operações possiíveis… tipo assim

interface Operacoes {

public static int INCLUI_EMPRESA = 01;
public static int EXCLUI_EMPRESA = 02;

}

E POR AI VAI!!!

Outra opçção interessante é que você pode ao invés de adotar uma classe ou interface contendo todas as operações, vc pode criar uma classe, um método ou alguma coisa que recebe a a url, e dependendo do nome da url ele identifica qual operação deve ser executada.

tipo assim:

Configure o método ou objeto para pegar apenas o dado “IncluiEmpresa.do” (é possível configurar no web.xml para que todos as chamadas que terminem com .do sejam encaminhados para o FrontController). Já que na URL está a String IncluiEmpresa.do, é só chamar o Command:

IncluiEmpresaCommand

Desta forma vc não precisa ficar passando as operações na requisição.
Vai de vocês escolherem qual é a melhor opção!

Abraços!
Thiago

Obs:
Mas o esquema seria não passar para o command nem request, nem response para que o mesmo fique desacoploado do ambiente web e possa ser reaproveitado mais facilmente.


class Command 
{
   public void execute(Map parameters)
   {
       int valor = ((Integer) parameters.get("valor")).intValue();
       // faz o que tem que fazer
   }
}

[quote=jprogrammer]Obs:
Mas o esquema seria não passar para o command nem request, nem response para que o mesmo fique desacoploado do ambiente web e possa ser reaproveitado mais facilmente.

[code]

class Command
{
public void execute(Map parameters)
{
int valor = ((Integer) parameters.get(“valor”)).intValue();
// faz o que tem que fazer
}
}
[/code][/quote]

Boa!!
Isso para mim era um enigma! :smiley:

Valeu!