3

Je travaille sur une application Java simple. Actuellement, j'ai deux vues, une pour la connexion et une autre une fois que vous êtes connecté.Un contrôleur crée-t-il de nouvelles vues?

Donc, ma question est, une fois que l'utilisateur s'est connecté, le contrôleur de la vue de connexion devrait-il créer la deuxième vue?

Le problème est, le premier contrôleur a besoin de connaître toutes les dépendances du second point de vue ...

Edit: c'est pas une application web.

+0

Ajout du tag java. –

Répondre

1

Si votre objet a besoin d'instancier une classe, mais que vous ne voulez pas qu'il dépende des détails de l'instanciation de la classe, injectez une fabrique (comme you've suggested).J'aime utiliser des interfaces pour pouvoir brancher différentes implémentations de mes dépendances. Voici un exemple:

public class RealLoginController implements LoginController { 
    private LoginViewFactory viewFactory; 

    public LoginController(LoginViewFactory viewFactory) { 
     this.viewFactory = viewFactory; 
    } 

    public ModelAndView handleRequest(HttpServletRequest request, 
             HttpServletResponse response) { 
     if (isLoggedIn()) { 
      return viewFactory.createLoggedInView(); 
     } else { 
      return viewFactory.createLoggedOutView(); 
     } 
    } 

    // ... 
} 

public class RealLoggedInView implements LoginView { 
    // Implementation for rendering stuff 
} 

public class RealLoggedOutView implements LoginView { 
    // Implementation for rendering stuff 
} 


public interface LoginViewFactory { 
    public LoginView createLoggedInView(); 
    public LoginView createLoggedInView(); 
} 


public class RealLoginViewFactory implements LoginViewFactory { 
    private FooModel fooEngine; 
    private BarConfig barConfig; 

    public RealLoginViewFactory(FooModel fooLayer, BarConfig barConfig) { 
     this.fooEngine = fooEngine; 
     this.barConfig = barConfig; 
    } 

    public LoginView createLoggedInView() { 
     if (fooEngine.hasBaz()) { 
      return new RealLoginView(barCongig.getQux()); 
     } else { 
      return new RealLoginView(barCongig.getQux(), 
            fooEngine.getBaz()); 
     } 
    } 

    public LoginView createLoggedOutView() { 
     // ... 
    } 
} 

public class RealLoginController implements LoginController { 
    private LoginViewFactory viewFactory; 

    public LoginController(LoginViewFactory viewFactory) { 
     this.viewFactory = viewFactory; 
    } 

    public ModelAndView handleRequest(HttpServletRequest request, 
             HttpServletResponse response) { 
     if (isLoggedIn()) { 
      return viewFactory.createLoggedInView(); 
     } else { 
      return viewFactory.createLoggedOutView(); 
     } 
    } 

    // ... 
} 

Vous pouvez alors utiliser le contrôleur avec des vues que vous aimez:

public class LoginControllerTest { 
    public void testSomething() { 
     // ... 
     controller = new RealLoginController(fakeViewFactory); 
     assertHasTag("td#row1", controller.getRenderedStuff()); 
     // ... 
    } 
} 

Vous pouvez être en mesure d'éviter le problème (comme bpappa suggests) si vous n'avez pas besoin instanciation complexe logique et votre cadre sait comment obtenir des dépendances pour vous par son nom.

0

Ceci est avec Spring MVC?

Si vous utilisez Spring MVC 2.5 ou une version antérieure sans annotations, à la fin de la méthode handleRequest, un objet ModelAndView est renvoyé. Cela contient les informations sur la vue (qu'il s'agisse de la vue elle-même dans une vue de redirection ou simplement du nom d'une vue). Vous pouvez renvoyer conditionnellement une vue différente selon une logique. Par exemple -

handleRequest(HttpServletRequest request, HttpServletResponse response) { 
    // get user from session 
    if (user.isLoggedIn()) 
     return new ModelAndView("loggedInView"); 
    else 
     return new ModelAndView("notLoggedInView"); 
} 

Si c'est un nouveau projet cependant, et vous avez accès à Java 1.5, je recommande d'utiliser plutôt le annotations-based Spring MVC, car alors vous pouvez retourner quel que soit le Frik que vous voulez.

+0

Désolé, non. Ce n'est pas une application Web. – subb

0

Je pense qu'une usine pourrait faire l'affaire:

public class LoginViewFactory 
{ 
    private depA; 
    private depB; 

    public LoginViewFactory(dependencyA, dependencyB) 
    { 
     depA = dependencyA; 
     depB = dependencyB; 
    } 

    LoginView create() 
    { 
     return new LoginView(depA, depB); 
    } 
} 


//and then pass this factory to my controller 
new Controller(new LoginViewFactory(new A(), new B()); 

Que pensez-vous?

0

Vous devriez adopter la même approche qu'avec Spring et demander à votre contrôleur de renvoyer un nom de vue. Ensuite, une autre classe gère la création de la vue en fonction du nom de la vue.

0

Je pense que votre première "vue" (la page de connexion) peut être considérée comme une page statique, comme d'habitude elle sera la première page accessible, donc il n'y a probablement pas de contrôleur derrière elle. Mais supposons qu'il existe d'autres pages dans votre application Web et que vous ayez un contrôleur A (sorte de DispatchController) qui dirige l'utilisateur vers la page de connexion.

Une fois que cette page est soumise, vous aurez normalement un autre contrôleur (dire LoginController) qui dirigera (si la connexion réussie) l'utilisateur à votre deuxième page d'affichage (connecté Page)

ligne Donc fond est : Pour moi, il semble que vous avez besoin de deux contrôleurs, chacun avec une responsabilité différente.

1

Je ne pense pas que le LoginController devrait créer le SecondView du tout. Une fois que l'utilisateur s'est connecté, le LoginController doit déclencher un événement dont la connexion a réussi et tout Contrôleur qui s'en occupe doit prendre les mesures appropriées.

Si vous utilisez DI, vous souhaitez idéalement injecter la vue dans un contrôleur.

Vous ne savez pas exactement ce que vous voulez dire par rapport à votre dernière affirmation, alors laissez-vous sans réponse.

+0

Eh bien, disons que le constructeur de ma deuxième vue a besoin d'un modèle, l'objet responsable de la création de cette vue (ici, mon contrôleur) a besoin de connaître ce modèle, héritant des dépendances de la vue. – subb

0

Si votre connexion est un formulaire POST (ce qui devrait être le cas) je ferais une redirection vers la page d'accueil après une connexion réussie. Cela signifie que si l'utilisateur consulte l'actualisation sur la page d'accueil après s'être connecté, il ne reçoit pas l'avertissement du navigateur concernant la nouvelle soumission d'un POST.
La même chose s'applique si vous cliquez sur un lien de la page d'accueil puis cliquez sur le bouton Précédent.

Au printemps, vous pouvez le faire avec cette syntaxe.

return new ModelAndView(new RedirectView(homepage, true), model); 

Le paramètre « page d'accueil » sera configuré dans la configuration de votre ressort et injecté en tant que paramètre - il doit être une URL par rapport à la page d'accueil sur votre site. Étant donné que vous redirigez le contrôleur de page d'accueil est exécuté de sorte que cela traite votre problème de dépendances.

Questions connexes