title: Routing request to matching pages using guice servlets
body: <p>I am developing inherited jsp/java ee application and I would like to introduce Guice IoC container to my application. However, I found some obstacles. I can't translate web.xml entries into guice registrations if there are more then one routing to single servlet using different urls. Problem is with init-parameters. </p>
  
  <p>Here are some extracts from my web.xml:</p>
  
  <p>This one is unrelated to problem, but it is good example how we are using init parameters. Basically it maps users with different roles in systems to appropriate pages.</p>
  
  <pre><code>&lt;!-- LIST INTERNSHIPS SERVLET  --&gt;
  &lt;servlet&gt;
      &lt;servlet-name&gt;ListInternships&lt;/servlet-name&gt;
      &lt;servlet-class&gt;pl.poznan.put.ims.controllers.ListInternships&lt;/servlet-class&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;CoordinatorPage&lt;/param-name&gt;
          &lt;param-value&gt;WEB-INF/pages/coordinator/listinternships.jsp&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;MentorPage&lt;/param-name&gt;
          &lt;param-value&gt;WEB-INF/pages/mentor/listinternships.jsp&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;AdministratorPage&lt;/param-name&gt;
          &lt;param-value&gt;WEB-INF/pages/administrator/listinternships.jsp&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;AllowedRoles&lt;/param-name&gt;
          &lt;param-value&gt;Coordinator, Mentor, Administrator&lt;/param-value&gt;
      &lt;/init-param&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;ListInternships&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/internships&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  </code></pre>
  
  <p>Those two are the troublesome ones:</p>
  
  <pre><code>&lt;!-- CHANGE PASSWORD SERVLET --&gt;
  &lt;servlet&gt;
      &lt;servlet-name&gt;ChangePassword&lt;/servlet-name&gt;
      &lt;servlet-class&gt;myapp.controllers.ContextForwarder&lt;/servlet-class&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;SharedPage&lt;/param-name&gt;
          &lt;param-value&gt;WEB-INF/pages/shared/password.jsp&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;AllowedRoles&lt;/param-name&gt;
          &lt;param-value&gt;*&lt;/param-value&gt;
      &lt;/init-param&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;ChangePassword&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/changepassword&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  
  &lt;!-- HELP SERVLET --&gt;
  &lt;servlet&gt;
      &lt;servlet-name&gt;Help&lt;/servlet-name&gt;
      &lt;servlet-class&gt;myapp.controllers.ContextForwarder&lt;/servlet-class&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;SharedPage&lt;/param-name&gt;
          &lt;param-value&gt;WEB-INF/pages/help/help.jsp&lt;/param-value&gt;
      &lt;/init-param&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;AllowedRoles&lt;/param-name&gt;
          &lt;param-value&gt;*&lt;/param-value&gt;
      &lt;/init-param&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;Help&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/help&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
  </code></pre>
  
  <p>Here is my servlet:</p>
  
  <pre><code> @Singleton
   public class ContextForwarder extends HttpServlet {
      private static final long serialVersionUID = 1L;
      private final IUserDao dao;
  
      @Inject
      public ContextForwarder(IUserDao dao) {
        this.dao = dao;
      }
  
      protected void doGet(HttpServletRequest request, HttpServletResponse response)
              throws ServletException, IOException {
  
              //trying to get rid of statics, using Ioc
              Validator.checkUserLoggedIn  (request);
              Validator.checkUserAuthorized(this, request);
  
              User currentUser        = UserManager.getCurrentUser(request);
              //pick matching page for user
              String userViewPage     = ServletUtils.getUserURL(this, currentUser, "Page");
  
  
              try {
                      dao.openSession();
                      dao.beginTransaction();
                      currentUser = UserManager.reloadCurrentUser(request, dao);
  
                      ServletUtils.forward(request, response, userViewPage);
                      dao.commit();
              }
              catch(ServletException e) {
                      dao.rollback();
                      throw e;
              }
              catch(Exception e) {
                      dao.rollback();
                      throw new ServletException(e);
              }
              finally {
                      dao.closeSession();
              }
      }
  }
  
  public class ServletUtils {
      public static void forward(HttpServletRequest request, HttpServletResponse     response, String location)
              throws ServletException, IOException {
              RequestDispatcher view = request
                      .getRequestDispatcher( response.encodeRedirectURL(location) );
  
              view.forward(request, response);
      }
  
  
      public static String getUserParameter(GenericServlet servlet, User user, String suffix) {
              return servlet.getInitParameter( user.getRoles() + suffix );
      }
  
      public static String getUserURL(GenericServlet servlet, User user, String suffix)
              throws ResourceNotFoundException {
              String URL = getUserParameter(servlet, user, suffix);
  
              if(URL == null) {
                      URL = servlet.getInitParameter("Shared" + suffix);
                      if(URL == null)
                              throw new ResourceNotFoundException(suffix);
              }
  
              return URL;
      }
  
      public static void redirect(HttpServletRequest request, HttpServletResponse response, String location)
              throws ServletException, IOException {
              response.sendRedirect( response.encodeRedirectURL(location) );
      }
  }
  </code></pre>
  
  <p>When  i try to translate it into guice (and then register this module):</p>
  
  <pre><code>public class MyServletModule extends ServletModule 
  {
  
      @Override
   protected void configureServlets() {
      configureHelp();
      configurePassword();
   }
  
      private void configureHelp()
      {
      Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
      params.put("SharedPage", "WEB-INF/pages/shared/help.jsp");
      params.put("AllowedRoles", "*");
  
      serve("/help").with(ContextForwarder.class, params);
      }
  
      private void configurePassword()
      {
      Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
      params.put("SharedPage", "WEB-INF/pages/shared/password.jsp");
      params.put("AllowedRoles", "*");
  
      // it's routing correctly to servlet, but it uses params from first registration,
      // so that routing to jsp page is incorrect
      serve("/changepassword").with(ContextForwarder.class, params);
      }       
  }      
  </code></pre>
  
  <p>The problem is that guice creates ContextForwarder servlet as a singleton with init parameters from the first registered method and then regardless of the request url it has parameters from the first registration. Is there any other solution to route user to different sites considering current user role? Is it possible to configure the same servlet class with two different configurations?</p>