Een gids voor het Front Controller-patroon in Java

1. Overzicht

In deze tutorial gaan we dieper in op de Voorste controllerPatroon, deel van de Enterprise-patronen zoals gedefinieerd in Martin Fowler‘S boek "Patronen van Enterprise Application Architecture".

Voorste controller wordt gedefinieerd als "een controller die alle verzoeken voor een website afhandelt". Het staat voor een webapplicatie en delegeert verzoeken naar volgende bronnen. Het biedt ook een interface naar algemeen gedrag, zoals veiligheid, internationalisering en het presenteren van bepaalde standpunten aan bepaalde gebruikers.

Hierdoor kan een applicatie zijn gedrag tijdens runtime veranderen. Bovendien helpt het om een ​​applicatie te lezen en te onderhouden door codeduplicatie te voorkomen.

De Front Controller consolideert alle afhandeling van verzoeken door verzoeken via één handlerobject te kanaliseren.

2. Hoe werkt het?

De Front Controller patroon is hoofdzakelijk verdeeld in twee delen. Een enkele dispatchingcontroller en een hiërarchie van opdrachten. De volgende UML geeft klassenrelaties weer van een generieke Front Controller-implementatie:

Deze enkele controller verzendt verzoeken naar opdrachten om gedrag te activeren dat aan een verzoek is gekoppeld.

Om de implementatie ervan te demonstreren, implementeren we de controller in een FrontControllerServlet en commando's als klassen die zijn geërfd van een abstract FrontCommand.

3. Installatie

3.1. Afhankelijkheden van Maven

Eerst gaan we een nieuw Maven WAR project met javax.servlet-api inbegrepen:

 javax.servlet javax.servlet-api 4.0.0-b01 voorzien 

net zoals steiger-maven-plugin:

 org.eclipse.jetty jetty-maven-plugin 9.4.0.M1 / front-controller 

3.2. Model

Vervolgens definiëren we een Model klasse en een model Opslagplaats. We zullen het volgende gebruiken Boek klasse als ons model:

openbare klasse Boek {privé Stringauteur; private String-titel; privé Dubbele prijs; // standaard constructeurs, getters en setters}

Dit wordt de repository, u kunt de broncode opzoeken voor concrete implementatie of u kunt er zelf een opgeven:

openbare interface Bookshelf {default void init () {add (new Book ("Wilson, Robert Anton & Shea, Robert", "Illuminati", 9,99)); add (new Book ("Fowler, Martin", "Patterns of Enterprise Application Architecture", 27.88)); } Bookshelf getInstance (); boolean add (E-boek); Boek findByTitle (String-titel); }

3.3. FrontControllerServlet

De implementatie van de Servlet zelf is vrij eenvoudig. We extraheren de opdrachtnaam uit een verzoek, maken dynamisch een nieuwe instantie van een opdrachtklasse en voeren deze uit.

Dit stelt ons in staat om nieuwe commando's toe te voegen zonder de codebasis van onze Voorste controller.

Een andere optie is om de Servlet te implementeren met behulp van statische, voorwaardelijke logica. Dit heeft het voordeel van foutcontrole tijdens het compileren:

openbare klasse FrontControllerServlet breidt HttpServlet uit {@Override beschermde ongeldige doGet (HttpServletRequest-verzoek, HttpServletResponse-antwoord) {FrontCommand-commando = getCommand (verzoek); command.init (getServletContext (), verzoek, antwoord); command.process (); } private FrontCommand getCommand (verzoek HttpServletRequest) {probeer {Class type = Class.forName (String.format ("com.baeldung.enterprise.patterns.front." + "controller.commands.% sCommand", request.getParameter ("commando "))); return (FrontCommand) type .asSubclass (FrontCommand.class) .newInstance (); } catch (uitzondering e) {return new UnknownCommand (); }}}

3.4. FrontCommand

Laten we een abstracte klasse implementeren met de naam FrontCommand, wat het gedrag vasthoudt dat alle commando's gemeen hebben.

Deze klasse heeft toegang tot het ServletContext en zijn verzoek- en antwoordobjecten. Bovendien verwerkt het de weergaveresolutie:

openbare abstracte klasse FrontCommand {beschermde ServletContext-context; beveiligd HttpServletRequest-verzoek; beschermde HttpServletResponse-reactie; public void init (ServletContext servletContext, HttpServletRequest servletRequest, HttpServletResponse servletResponse) {this.context = servletContext; this.request = servletRequest; this.response = servletResponse; } public abstract void process () gooit ServletException, IOException; protected void forward (String target) gooit ServletException, IOException {target = String.format ("/ WEB-INF / jsp /% s.jsp", target); RequestDispatcher dispatcher = context.getRequestDispatcher (doel); dispatcher.forward (verzoek, antwoord); }}

Een concrete implementatie van dit abstract FrontCommand zou zijn SearchCommand. Dit omvat voorwaardelijke logica voor gevallen waarin een boek is gevonden of wanneer een boek ontbreekt:

public class SearchCommand breidt FrontCommand uit {@Override public void process () gooit ServletException, IOException {Book book = new BookshelfImpl (). getInstance () .findByTitle (request.getParameter ("title")); if (boek! = null) {request.setAttribute ("boek", boek); doorsturen ("boek gevonden"); } else {forward ("book-notfound"); }}}

Als de applicatie actief is, kunnen we dit commando bereiken door onze browser te wijzen naar // localhost: 8080 / front-controller /? Command = Search & title = patterns.

De SearchCommand lost op in twee weergaven, kan de tweede weergave worden getest met het volgende verzoek // localhost: 8080 / front-controller /? command = Search & title = any-title.

Om ons scenario af te ronden, implementeren we een tweede commando, dat in alle gevallen als fallback wordt geactiveerd, een opdrachtverzoek is onbekend voor de Servlet:

public class UnknownCommand breidt FrontCommand uit {@Override public void process () gooit ServletException, IOException {forward ("unknown"); }}

Deze weergave is bereikbaar op // localhost: 8080 / front-controller /? Command = Order & title = any-title of door de URL parameters.

4. Inzet

Omdat we hebben besloten om een OORLOG bestandsproject, hebben we een webimplementatiedescriptor nodig. Hiermee web.xml we kunnen onze webapplicatie in elke Servlet-container draaien:

   front-controller com.baeldung.enterprise.patterns.front.controller.FrontControllerServlet front-controller / 

Als laatste stap zullen we rennen ‘Mvn install jetty: run ' en bekijk onze standpunten in een browser.

5. Conclusie

Zoals we tot nu toe hebben gezien, zouden we nu bekend moeten zijn met de Front Controller patroon en de implementatie ervan als Servlet en commandohiërarchie.

Zoals gewoonlijk vind je de bronnen op GitHub.