package ch.heigvd.amt.mvcdemo.web.controllers;
import ch.heigvd.amt.mvcdemo.services.BeersManagerLocal;
import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* This servlet illustrates the MVC design pattern with a simple example.
*
* The first thing to know is that Inversion of Control (IoC) is realized with a
* declaration of a mapping in the web.xml deployment descriptor. This is where
* we tell the application server that whenever it receives an HTTP request
* where the URL is equal to /pages/beers, then it should invoke a callback
* implemented by this class.
*
* When this happens, the servlet acts as a controller. Its role is to invoke a
* service (in the business tier), to receive a model (a Java object, or a graph
* of Java objects), to make it available to the view and finally to delegate
* the generation of HTML markup to a JSP page.
*
* The service is an EJB, injected in the servlet (dependency injection). No
* need to worry about that at this stage, it is a topic that will be studied
* later in the course. All you need to know is that the servlet can get a list
* of beers by calling beersManager.getAllBeers.
*
* Important: the servlet does not know how the service is implemented. In most
* applications, invoking the getAllBeers method would result in a query being
* sent to a database. This could take "some" time (hence affect performance).
*
* @author Olivier Liechti (olivier.liechti@heig-vd.ch)
*/
public class BeersServlet extends HttpServlet {
@EJB
BeersManagerLocal beersManager;
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*
Firstly, we need to get a model. It is not the responsibility of the servlet
to build the model. In other words, you should avoid to put business logic
and database access code directly in the controller. In this example, the
beersManager takes care of the model construction.
*/
Object model = beersManager.getAllBeers();
/*
Secondly, we need to find a way to share the model with the JSP that will
render the view. We have to select a scope (in general, request or session,
sometimes in application or page).
See https://docs.oracle.com/javaee/5/tutorial/doc/bnafo.html for information
about this topic.
The following code puts the model in the request scope. The JSP page will be
able to retrive it by using the "beers" name in an EL expression.
*/
request.setAttribute("beers", model);
/*
The following code would place the model in the session. The good thing is
that we could cache the response sent by beersManager.getAllBeers and increase
performance. The bad thing is that we would consume memory on the server. Think
about what would happen if sessions have a duration of 30 minutes, that we
can have 100'000 concurrent sessions and that the beers list is a 1 MB data
structure.
*/
//request.getSession().setAttribute("beers", model);
/*
Thirdly, this is how we delegate the rendering of the view to the JSP page.
Notice that we specify the full path starting at the project root (in the
file system). It is important to place the JSP pages within the WEB-INF
directory, for security reasons. The Servlet speciciation states that when
this is the case, then it is NOT possible for an HTTP client to access the
JSP directly (short-cutting the MVC pattern). In other words, the JSP can
only be accessed via a controller servlet.
*/
request.getRequestDispatcher("/WEB-INF/pages/beers.jsp").forward(request, response);
}
}