Toon posts:

[Jsp/Servlets]RequestDispatcher

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben nu voor school met een project bezig met jsp en servlets, de beste manier om alles af te handelen lijkt mij de MVC manier, met de servlet als controller. ALs ik van een jsp pagina dus naar een andere pagina wil gaan gaat ie eerst naar de Servlet en dan met bijv:
RequestDispatcher rd = request.getRequestDispatcher( "/login.jsp" );
rd.forward( request, response );
Alleen zullen er heel wat pagina's gemaakt worden en een ellenlange if-else lijkt me ook niet de mooiste oplossing. Wie heeft er een slimmere oplossing om de pagina's mooi te redirecten( Ik wil geen gebruik maken van libraries als struts etc, omdat ik geen tijd heb om dat eerst onder de knie te krijgen.
tnx

  • Janoz
  • Registratie: Oktober 2000
  • Nu online

Janoz

Moderator Devschuur®

!litemod

Eigenlijk is het gebruikelijker om de controler een andere actie class aan te laten roepen en deze vervoglens te laten forwarden naar de jsp. De controler matched de url dan bij de class (+ eventueel methode in die class) en in die class wordt daadwerkelijk de actie uitgevoerd (bv invoeren in db oid).

Welke acties en welke jsp's er gebruikt worden kun je natuurlijk heel mooi in een configuratie bestand opslaan. Deze lees je dan in de init in en bij elke actie zoek je die gewoon op in je hashmap.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
maar op een jsp pagina kunnen meerdere dingen gebeuren en links staan naar meerdere jsp-pagina's, dan kan je dus niet een jsp pagina aan een andere koppelen en deze waardes van te voren opslaan.

  • Janoz
  • Registratie: Oktober 2000
  • Nu online

Janoz

Moderator Devschuur®

!litemod

Waarom niet?

En wat bedoel je verder met het koppelen van de jsp's en het 'van te voren opslaan van waardes' ?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
nou bijvoorbeeld als je verschillende links hebt dus normaal zou je dou
<a href="blaa.jsp">blaa<a>
<a href="blaa2.jsp">blaa2<a>
<a href="blaa3.jsp">blaa3<a>
Maar alles gaat via de servlet dus dan zul je parameters mee moeten geven die naar de pagina's verwijzen en dus krijg je een lang if-else deel

  • nxt
  • Registratie: November 2001
  • Laatst online: 04-02 09:36

nxt

Verwijderd schreef op 02 september 2004 @ 16:54:
...
Maar alles gaat via de servlet dus dan zul je parameters mee moeten geven die naar de pagina's verwijzen en dus krijg je een lang if-else deel
dat hoeft niet perse
je zou bijvoorbeeld alle acties kunnen bewaren in een Map bijvoorbeeld HashMap
en dan heb je geen uitgebreide if/else constructies nodig
of Properties als je graag een losse file wilt hebben waar je makkelijk alle opties in wilt kunnen wijzigen zonder de hele zooi opnieuw te moeten compileren

  • djengizz
  • Registratie: Februari 2004
  • Niet online
Idd properties lijkt mij een goed idee. En gebruik dan XML dan kun je op een generieke manier later params toevoegen.

  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02-2025
Of je kijkt even naar Maverick. Te vinden op www.sourceforge.net. Een MVC implementatie die heel vrij te gebruiken is, maar daarnaast ook erg veel features heeft, en waarmee je naar smaak een MVC omgeving kunt inrichten.

[edit]Ik gebruik Maverick in mijn huidige project als volgt: maverick mapt commandos naar Controllers. Een controller implementeert een specifieke functie(flow). De bijbehorende BusinessLogic deel ik naar functioneel gebied in BusinessLogic classes. Elke controller heeft 1 of meerdere views, die in jsp gemaakt zijn en alleen maar weergave dingen regelen. Alle inhoudelijke acties worden door de BusninessLogic laag gedaan(Model dus in feite) en de controller doet niet meer dan de juiste BusinessLogic en jsp paginas aansturen en aanroepen.

Elke controller is een 'normale' class (implementatie van een maverick controller) en de 'switch' tussen de verschillende functies vindt plaats aan de hand van een XML config document van maverick. Daar zeg ik bijvoorbeeld: command bekijkorders mapt naar OrdersbekijkenController met view orders.jsp. Met als gevolg dat ik bekijkorders.m kan aanroepen.

Een laatste tip: als je zelf een MVC structuur gaat opzetten, en je bijvoorbeeld niet zo'n redelijk strakke structuur als Struts gaat gebruiken, denk dan goed na over welke verantwoordelijkheden elke laag in je applicatie heeft. Je wilt bijvoorbeeld geen entity wijzigende acties in je jsp's stoppen, en bijvoorbeeld geen bedrijfsspecifieke validaties in je controller.

[ Voor 97% gewijzigd door zneek op 02-09-2004 23:05 ]


Verwijderd

MVC (Model View Controller) draait juist om het feit dat je presentatie (jsp) en logica (Model) van elkaar scheidt. Hierbij draait alles om de combinatie van de controller (servlet), een action Interface, een Map (HashMap) en uiteindelijk de action classes die de action interface implementeren.

Onder de motorkap gebeurt dan het volgende:
request (in querystring action=foobar > servlet > match action ("foobar" met een entry "foobar" in de Map > voor de action uit (databse query's etc) > forward naar jsp. In feite voert de controller alle operaties uit.

Voorbeeld:

De Controller (servlet)
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Controller extends HttpServlet {
  private static final String CONTENT_TYPE = "text/html";
  private ActionMapping mapping;
  private HttpServletRequest request;
  private HttpServletResponse response;

  public void init() throws ServletException {
    mapping = new ActionMapping();
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     this.request = request;
     this.response = response;

     Action a = mapping.findAction(getActionName()); // hier de corresponderende class instantieren (getActioName haalt de action uit de querystring)

     String path = a.perform(request, response); // methode perform uitvoeren (omdat alle *Action classes de interface implementeren, weet je dat ze allemaal deze methode MOETEN bevatten!)

     forward(path); // forwarden naar view (jsp)
   }

   protected String getActionName(){
     String action = request.getParameter("action");
     if ((action==null) || (action.equals(""))) action="Index";
     return action;
   }

   protected void forward(String path)
       throws ServletException, IOException {
     RequestDispatcher disp = request.getRequestDispatcher(path);
     disp.forward(request, response);
   }

  //Clean up resources
  public void destroy() {
  }
}


De Action Interface:
Java:
1
2
3
4
5
6
public interface Action {

  public String perform(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException;

}


De ActionMapper:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
public class ActionMapping {
  private HashMap actionMap;

  public ActionMapping() {
    actionMap = new HashMap();
    actionMap.put("foobar", new FoobarAction());
  }

  public Action findAction(String actionName){
    return (Action) actionMap.get(actionName);
  }
}


En dan zien de logica classes er ongeveer als volgt uit:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class FoobarAction implements Action {
  public FoobarAction () {
  }

  public String perform(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Eventuele variabelen ophalen uit querystring of form
    // Query's uitvoeren
    
    request.setAttribute("resultaat", "De informatie die getoond moet worden komt hier (bijv array)"); // in jsp vervolgens request.getAttribute("resultaat") om de info weer te geven (of door een meegestuurde array te ittereren oid)
    return "foobar.jsp"; // methode forward() in de controller forward naar deze pagina
  }

}


Ik hoop dat je hier wat wijzer van wordt. Dit heb ik het vaak gebruikt als het om een "lichgewicht" mvc implementatie ging.
Als je het gaat gebruiken, hou er dan wel even rekening mee dat de packages en imports gemakshalve zijn weggelaten.
De werking is honderd procent gegarandeert en het is een heuze implementatie van het MVC design pattern.

p.s. sorry voor het ontbreken van commentaar in de code, maar daar ben ik nu even te lui voor ;)

Verwijderd

Topicstarter
tnx, nu snap ik het. Met deze uitleg kan ik aan de slag.

  • |orion
  • Registratie: Juli 2002
  • Laatst online: 16-04 15:16
Een kleine schop, moet de TS maar niet hierheen linken vanaf het schoolforum ;)

Ik vraag me af waarom niemand 'gewoon' (?) voor elke actie (adduser, deluser, etc.) of voor elk type actie (een user servlet, een cms servlet, etc.) een apparte servlet maakt. Is de eerder beschreven methode efficienter, duidelijker of anderzijds beter dan wat ik denk of mis ik gewoon iets?

  • djengizz
  • Registratie: Februari 2004
  • Niet online
Servlets draaien in een ServletContainer en veroorzaken nogal wat overhead. Verder wordt er maar één instantie van een Servlet aangemaakt in die container dus grote kans op problemen met bv. variabelen en queuing als je teveel logica in je Servlet stopt.

edit:
Ook wil je het aantal 'interfaces' (controllers) tussen je JSP's en je Actions zou klein mogelijk houden om ze loosely-coupled te laten zijn.

[ Voor 38% gewijzigd door djengizz op 16-09-2004 19:33 ]


  • Gert
  • Registratie: Juni 1999
  • Laatst online: 05-12-2025
Beide methodes worden toegepast, het hangt voor een groot deel af wat je zelf handiger vindt voor een bepaald probleem.

  • Janoz
  • Registratie: Oktober 2000
  • Nu online

Janoz

Moderator Devschuur®

!litemod

@|Orion :

Het grote voordeel van die ene controller is dat veel generieke taken daarin afgehandeld kunnen worden. Je kunt voor elke actie wel een servlet maken, maar dan zul je ook voor elke servlet security moeten implementeren en voor elke servlet configuratie methodiek.

Wat jij als servlet wilt gebruiken wordt meestal als actie class gebruikt. Daartussen zijn nog verschillende smaken. Sommigen (zoals ik) gebruiken classes per actie (addUser listUsers) anderen gebruiken 1 class voor een groep acties (UserActions). Het voordeel van deze opsplitsing is dat generieke taken in de controler gestopt kunnen worden en userspecifieke taken in de user classes. Wil je een template engine toevoegen, dan roept je controler eerst de betreffende actie aan (adduser) en vervolgens roept hij de template parser aan en stuurt het resultaat naar de client. Voor de ontwikkeling hoef je dan in het template gedeelte alleen rekening te houden met het template, en voor het user gedeelte alleen met het juist uitvoeren van de DB-acties en het juist opslaan van de resultaten in het request.

Door deze opsplitsing is de implementatie van de verschillende delen minder afhankelijk van elkaar en dus veel overzichtelijker. Een aanpassing aan de template parser heeft misschien alleen invloed op de manier waarop de adduser zijn resultaten in het request moet zetten, en met een beetje generieke opslag methode hoeft daar meestal niks aan veranderd te worden. Wil je vervolgens security toevoegen, dan hoeft dit alleen gecontroleerd en afgedwongen te worden in de servlet.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'

Pagina: 1