Integrating the Presenter in a HttpServlet

117 views
Skip to first unread message

Jop van Raaij

unread,
Jan 4, 2014, 5:05:33 PM1/4/14
to clean-code...@googlegroups.com
How should I implement a Presenter in a ServletContainer context?

I have an application and I want to use Servlets to manage the user input and output. After doing TDD to evolve some usecases towards the Interactor - Boundary - Entity pattern, I want to implement the Servlet to use the Interactors and implement the Presenters.

Example:

First the application code:

class GetLoginCountInteractor()  {

 
private Presenter presenter;

 
public setPresenter(GetLoginCountPresenter presenter) { this.presenter = presenter; }

 
public void getLoginCountForUser(GetLoginCountRequest request) {
   
GetLoginCountResponse response = new GetLoginCountResponse();
    response
.loginCount = // insert code to determine loginCount by request.userId here
   
this.presenter.present(response);
}

class GetLoginCountRequest() {
 
int userId;
}

class getLoginCountResponse() {
  public
int loginCount;
}

interface GetLoginCountPresenter() {
 
public present(GetLoginCountResponse response);
}


Now the client, aka the ServletContainer side:
package some.package.with.servlets

class GetLoginCountPresenterImpl implements GetLoginCountPresenter {

  private httpRequest;

 
@Override
  public present(GetLoginCountResponse response) {
    httpRequest.setAttribute("loginCount", response.loginCount);
  }


  public void setHttpRequest(HttpServletRequest httpRequest){
    this.httpRequest = httpRequest;
  }
}

class showLoginCount extends HttpServlet {

  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
   
GetLoginCountRequest request = new GetLoginCountRequest();
    request.userId = 2;
   
GetLoginCountInteractor interactor = new GetLoginCountInteractor();
    interactor.setPresenter(new GetLoginCountPresenterImpl());

    interactor.getLoginCountForUser(request);

    RequestDispatcher requestDispatcherObj = req.getRequestDispatcher("showLoginCount.jsp");
    requestDispatcherObj.forward(req, resp);
  }
}

My points/questions:
  • What should the Presenter do? It only sets a parameter in the httpRequest, which is used in the JSP file later. I feel like the Presenter should 'present' or make something 'presentable' for the user: something more as in this example.
  • It feels odd to create the requestdispatcher outside the Presenter, but calling the requestDispatcher.forward inside the Presenter forces me to catch the IOException and ServletException inside the Presenter (and not be able to use the exception mapping/handling from the servletContainer in the web.xml). Throwing it in the present method would leak those Exceptions inside my application.

Maybe I'm missing the point about the Presenter exactly is in this situation. I think the HttpServlet is the controller, driving the usecase (interactor), but part of it feels like the Presenter as well (the request manipulation to define the parameters for the JSP view). Or does the design of Servlets simply not encourage the use of Presenters?

A more generic question emerging is "how to handle Exceptions from code coming used in the implementation of the Presenter?". My intuition says it should be handled in the Presenter, but I'm not so sure in this Servlet Example.


Sebastian Gozin

unread,
Jan 4, 2014, 7:23:42 PM1/4/14
to clean-code...@googlegroups.com
Would it be the responsibility of the the presenter to transform usecase response data in a structure the web understands?

In that sense moving the login count onto the http request/response seems correct. It could also do more complex stuff such as translation and formatting.
As I ponder on this I'm thinking much of this kind of work we already do in JSP templates using taglibs. If we would replace JSP with for example Jackson (JSON/XML) then I imagine we may need to things a bit differently.

Jop van Raaij

unread,
Jan 5, 2014, 9:02:58 AM1/5/14
to clean-code...@googlegroups.com
Thank you for the input Sebastan.

The Presenter.present(Response response) presents the response information to the user. Because the client can(must) implement the method, the client can do whatever he wants. The client can use jsp (or other templating feature) to place the data inside HTML, or send it directly to an outputstream. It can use frameworks(like another MVP)/objects/templating/... as long as the user (which can be another system) gets a useful view and the view does not contain any business logic.

In my example however, I have to break the Servlet framework when I use only the Presenter to present: catching the exceptions inside the presenter which would otherwise be handles by the servletcontainer. Doing the exception method calls inside the doGet itself, makes the controller (Servlet) do some of the presenting. Which also feels awkward.

Uncle Bob

unread,
Jan 7, 2014, 10:02:22 AM1/7/14
to clean-code...@googlegroups.com
Jop,

In a very simple flow like this, I would probably drop the Request and Response data structures and just pass the user id and login count as arguments to the interactor and presenter repectively.  Also, in this very simple case, the presenter has very little presenting to do.  It just moves the login count to a place where the JSP can get it.  

But let's make the presenter a little more interesting.  Remember the old McDonald's signs from the 70s.  One year they said "Over 120 Million sold".  The next year it was "Over 250 Million sold".  The year after that it was "Over One Billion Sold".  And then they just permanently changed it to "Billions and Billions Sold".  What if we wanted to do that with the login count.

For numbers less than 100 we simply show: "Login Count: xx" where xx is the number.  But for login counts above 100 we say: "Login Count: more than x hundred."  And for a count more than 1000 we simply say: Login Count: Thousands.

It's the job of the presenter to make these transformations.  The presenter uses the data returned from the interactor to construct the string that the JSP will display.

Jop van Raaij

unread,
Jan 7, 2014, 10:41:02 AM1/7/14
to clean-code...@googlegroups.com
Especially the last line in your answer is very interesting, thank you. The job of the presenter is not always very clear to me. At first glance, I would consider the requirement for the specific textual representations of the usercount a business rule (as the business explicitly told me the application should do this) and therefor put it into the interactor. But when the application is able to present text in multiple languages, I would consider this to be a job for the presenter. After reading your text, I can also see how the number conversion can be part of the Presenter instead of the Interactor. I feel getting tossed around by arguments for both solutions, without an argument to make a clear decision. Maybe I should work on my definition of 'business rule', or introduce the principle of 'when presentation (size, format, location, representation) is a factor, it should be inside the presenter'. Thinking about is aloud, makes me agree on your solution.

I tried to make the example as simple as possible to focus on the problem at hand: handling the exceptions originating from method invocations in the implemented presenter. Could you comment on this more generic topic?
Reply all
Reply to author
Forward
0 new messages