Vous êtes sur la page 1sur 37

Web 3

Lesson 10: Front controller continued

OP HET EXAMEN

Leg het Front Controller patroon uit.



Verschillende stukjes code kunnen uitleggen van de verschillende opties die
er hier in de slides worden getoond.

Voor- en nadelen van de verschillende opties kunnen uitleggen.

Option 4 moet je NIET kunnen implementeren!

FRONT CONTROLLER
Single Point of Entry:

handles requests

delegates

business processing

choice proper view

Single point of Entry

public class Controller extends HttpServlet {


protected void processRequest(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
String destination = "index.jsp";
String action = request.getParameter("action");

!


















}

if (action == null) {
destination = "index.jsp";
}
else if (action.equals("overview")) {
destination = getOverview(request, response);
}
else if (action.equals("signUp")) {
destination = "signUp.jsp";
}
else if (action.equals("productOverview")) {
destination=getProductOverview(request,response);
}
else if (action.equals("addProduct")) {
destination="addProduct.jsp";
}
request.setAttribute("action", action);
RequestDispatcher view = request.getRequestDispatcher(destination);
view.forward(request, response);

Ca
to perfo ll model
rm bus
iness lo
gic

atcher
p
s
i
d
e
s
U
oper view
r
p
o
t
e
t
a
to navig

Single point of Entry


public class Controller extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {

!
String action = request.getParameter("action");
RequestHandler handler = null;

Use he
to deleg lpers
ate to m
odel

if (action.equals("overview")) {
handler = new PersonOverviewHandler(personModel);
} else if (action.equals("signUp")) {
handler = new SignUpHandler();
} else if (action.equals("productOverview")) {
handler = new ProductOverviewHandler(productModel);
} else if (action.equals("addProduct")) {
handler = new AddProductHandler();
}
String destination = handler.handleRequest(request, response);
RequestDispatcher view = request.getRequestDispatcher(destination);
view.forward(request, response);
}

!
!
}

atcher
p
s
i
d
e
s
U
oper view
r
p
o
t
e
t
a
to navig

FRONT CONTROLLER

public class Controller extends HttpServlet {


protected void processRequest(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {

!
String action = request.getParameter("action");
RequestHandler handler = null;

OCP ?

if (action.equals("overview")) {
handler = new PersonOverviewHandler(personModel);
} else if (action.equals("signUp")) {
handler = new SignUpHandler();
} else if (action.equals("productOverview")) {
handler = new ProductOverviewHandler(productModel);
} else if (action.equals("addProduct")) {
handler = new AddProductHandler();
}
String destination = handler.handleRequest(request, response);
RequestDispatcher view = request.getRequestDispatcher(destination);
view.forward(request, response);

How to avoid?

!
!
}

Option 1

CONTROLLER
protected void processRequest(HttpServletRequest request,

HttpServletResponse response) throws ServletException, IOException {
try {
String action = request.getParameter("action");
RequestHandler handler = controllerFactory.getController(action);
String destination = handler.handleRequest(request, response);
RequestDispatcher view = request.getRequestDispatcher(destination);
view.forward(request, response);
} catch (Exception e) {
throw new ServletException(e.getMessage(), e);
}
}

CONTROLLERFACTORY
public class ControllerFactory {

public RequestHandler getController(String action) {
RequestHandler handler = null;

!
if (action.equals("overview")) {
handler = new PersonOverviewHandler(personModel);
} else if (action.equals("signUp")) {
handler = new SignUpHandler();
} else if (action.equals("productOverview")) {
handler = new ProductOverviewHandler(productModel);
} else if (action.equals("addProduct")) {
handler = new AddProductHandler();
}

}
}

CONTROLLERFACTORY
public class ControllerFactory {
private Map<String, RequestHandler> handlers = new HashMap<>();

public ControllerFactory(PersonService personModel, ProductService


productModel) throws ServiceException {
handlers.put("overview", new PersonOverviewHandler(personModel));
handlers.put("signUp", new SignUpHandler());
handlers.put("productOverview", new ProductOverviewHandler(productModel));
handlers.put(addProduct", new AddProductHandler());
}

!
public RequestHandler getController(String key) {
return handlers.get(key);
}
}

OPTION 1
Factory class hardcoded:

- code not Closed for modification



+ isolated

Option 2

CONTROLLERFACTORY
public class ControllerFactory {

private RequestHandler createHandler(String handlerName, ShopService model)


throws ServiceException {
RequestHandler handler = null;
try {
Class handlerClass = Class.forName("controller."+ handlerName);
Object handlerObject = handlerClass.newInstance();
handler = (RequestHandler) handlerObject;
handler.setModel(model);
} catch (ClassNotFoundException e) {
throw new ServiceException(e);
}

!


}

return handler;
}

FACADE
We need a facade

a class which consists both services, the person


service and the product service

as such we only need to pass one model each


time instead of two as done in option 1

SHOPSERVICE
public class ShopService {

private PersonService personService;
private ProductService productService;

public ShopService () {
personService = new PersonService();
productService = new ProductService();
}

!

}

OPTION 2
Factory using reflection:

+ code is Closed for modification



- name action should match name handler
tight coupling view - controller !

Option 3

CONTROLLER.XML

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="userOverview">controller.handler.UserOverviewHandler</entry>
<entry key="productOverview">controller.handler.ProductOverviewHandler</entry>
<entry key="signUp">controller.handler.SignUpHandler</entry>
<entry key="addProduct">controller.handler.AddProductHandler</entry>
</properties>

CONTEXTLISTENER
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
try {
service = new ShopService();

!
InputStream input = context.getResourceAsStream(/WEB-INF/controller.xml");
Properties properties = new Properties();
properties.loadFromXML(input);

ControllerFactory controllerFactory = new ControllerFactory(properties, service);


context.setAttribute("controllerFactory", controllerFactory);
} catch (Exception ex) {

}

CONTEXTLISTENER

EVEN BETTER
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
try {
String dbType = context.getInitParameter("database");
service = new TourismService(dbType);

ame of
n
e
h
t
e
defin
the file
ml
in web.x

!
String fileName = context.getInitParameter("controllerpropertyfile");
InputStream input = context.getResourceAsStream("/WEB-INF/" + fileName);
Properties properties = new Properties();
properties.loadFromXML(input);

!
ControllerFactory controllerFactory = new ControllerFactory(properties, service);
context.setAttribute("controllerFactory", controllerFactory);
} catch (Exception ex) {
Logger.getLogger(ContextListener).log(Level.SEVERE, null, ex);
}
}

CONTROLLERFACTORY
public class ControllerFactory {
private Map<String, RequestHandler> handlers = new HashMap<>();

!
public ControllerFactory(Properties controllers, ShopService model)
throws ServiceException {
for(Object key : controllers.keySet()) {

RequestHandler handler = null;
String handlerName = controllers.getProperty((String) key);
try {
Class<?> handlerClass = Class.forName(handlerName);
Object handlerObject = handlerClass.newInstance();
handler = (RequestHandler) handlerObject;
} catch (ClassNotFoundException e) {

}
handler.setModel(model);
handlers.put(key, handler);
}

!
public RequestHandler getController(String key) {
return handlers.get(key);
}
}

SERVLETCONTEXTLISTENER
interface

receivers notification events



about ServletContext lifecycle changes

!

annotated with @WebListener

READ PROPERTIES

CLASS

annotation

CONTEXTLISTENER.JAVA
implement interface

@WebListener
public class ContextListener implements ServletContextListener {

!
public void contextInitialized(ServletContextEvent sce) {
// TODO Auto-generated method stub
}

!
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}

implement methods

<web-app>
<context-param>

</context-param>

</web-app>

web.xml

contextListener

1
When the application is deployed, the container creates a ContextListener object to monitor changes in the lifecycle of the ServletContext

<web-app>
<context-param>

</context-param>

</web-app>

contextListener

web.xml
servletContext

2
Then the container creates 1 ServletContext object to store meta-information about the application

<web-app>
<context-param>

</context-param>

</web-app>

contextListener

web.xml
servletContext
properties

3
The ContextListener is notified that the ServletContext is created and the method contextInitialized() is called. In this method we get the context
parameters from the ServletContext and store them in a Properties object

<web-app>
<context-param>

</context-param>

</web-app>

contextListener

web.xml
servletContext
properties

shop

4
In the ContextListener we then create a Shop object and pass the Properties object with the constructor

<web-app>
<context-param>

</context-param>

</web-app>

contextListener

web.xml
servletContext
properties

shop

5
We store the Shop object as an attribute on the ServletContext object

<web-app>
<context-param>

</context-param>

</web-app>

contextListener

web.xml
servletContext
properties

shop

servlet1

servlet2

5
The servlets need the Shop object

<web-app>
<context-param>

</context-param>

</web-app>

contextListener

web.xml
servletContext
properties

shop

servlet1

servlet2

6
The servlets have access to the ServletContext object (method getServletContext()), so they can ask for the Shop object

<web-app>
<context-param>

</context-param>

</web-app>

contextListener

web.xml
servletContext
properties

shop
request

servlet1

servlet2

6
By the way, a request object also has a method getServletContext()

OPTION 3
Factory with configuration file:

+ code is Closed for modification



+ name action should not match name handler

- a lot of XML

Option 4

ANNOTATIONS

@RequestMapping(action="specialties")
public class GetSpecialtiesHandler extends RequestHandler {

}

ANNOTATIONS
You only need to implement this option if
you need a challenge or if you have some
time left

Implementation is no exam material


Create your own annotations


more information on Toledo

OPTION 4
Annotations:

+ code is Closed for modification



+ name action should not match name servlet

+ no configuration file

Vous aimerez peut-être aussi