Я занимаюсь разработкой унаследованного приложения jsp / java ee и хочу представить контейнер Guice IoC для моего приложения. Однако я обнаружил некоторые препятствия. Я не могу перевести записи web.xml в обычные регистрации, если существует более одной маршрутизации на один сервлет с разными URL. Проблема с init-параметрами.
Вот некоторые выдержки из моего web.xml:
Это не связано с проблемой, но это хороший пример того, как мы используем параметры init. В основном он отображает пользователей с разными ролями в системах на соответствующие страницы.
<!-- LIST INTERNSHIPS SERVLET -->
<servlet>
<servlet-name>ListInternships</servlet-name>
<servlet-class>pl.poznan.put.ims.controllers.ListInternships</servlet-class>
<init-param>
<param-name>CoordinatorPage</param-name>
<param-value>WEB-INF/pages/coordinator/listinternships.jsp</param-value>
</init-param>
<init-param>
<param-name>MentorPage</param-name>
<param-value>WEB-INF/pages/mentor/listinternships.jsp</param-value>
</init-param>
<init-param>
<param-name>AdministratorPage</param-name>
<param-value>WEB-INF/pages/administrator/listinternships.jsp</param-value>
</init-param>
<init-param>
<param-name>AllowedRoles</param-name>
<param-value>Coordinator, Mentor, Administrator</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ListInternships</servlet-name>
<url-pattern>/internships</url-pattern>
</servlet-mapping>
Эти двое проблемные:
<!-- CHANGE PASSWORD SERVLET -->
<servlet>
<servlet-name>ChangePassword</servlet-name>
<servlet-class>myapp.controllers.ContextForwarder</servlet-class>
<init-param>
<param-name>SharedPage</param-name>
<param-value>WEB-INF/pages/shared/password.jsp</param-value>
</init-param>
<init-param>
<param-name>AllowedRoles</param-name>
<param-value>*</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ChangePassword</servlet-name>
<url-pattern>/changepassword</url-pattern>
</servlet-mapping>
<!-- HELP SERVLET -->
<servlet>
<servlet-name>Help</servlet-name>
<servlet-class>myapp.controllers.ContextForwarder</servlet-class>
<init-param>
<param-name>SharedPage</param-name>
<param-value>WEB-INF/pages/help/help.jsp</param-value>
</init-param>
<init-param>
<param-name>AllowedRoles</param-name>
<param-value>*</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Help</servlet-name>
<url-pattern>/help</url-pattern>
</servlet-mapping>
Вот мой сервлет:
@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) );
}
}
Когда я пытаюсь перевести его в подсказку (а затем зарегистрировать этот модуль):
public class MyServletModule extends ServletModule
{
@Override
protected void configureServlets() {
configureHelp();
configurePassword();
}
private void configureHelp()
{
Map<String, String> params = new HashMap<String, String>();
params.put("SharedPage", "WEB-INF/pages/shared/help.jsp");
params.put("AllowedRoles", "*");
serve("/help").with(ContextForwarder.class, params);
}
private void configurePassword()
{
Map<String, String> params = new HashMap<String, String>();
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);
}
}
Проблема в том, что guice создает сервлет ContextForwarder в виде синглтона с параметрами init из первого зарегистрированного метода, а затем независимо от URL-адреса запроса он имеет параметры из первой регистрации. Есть ли другое решение для направления пользователя на другие сайты с учетом текущей роли пользователя? Можно ли настроить один и тот же класс сервлетов на две разные конфигурации?