2

継承された jsp/java ee アプリケーションを開発しており、アプリケーションに Guice IoC コンテナーを導入したいと考えています。しかし、いくつかの障害が見つかりました。異なる URL を使用して単一のサーブレットに複数のルーティングがある場合、web.xml エントリを Guice 登録に変換できません。問題は init-parameters にあります。

これが私の 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>

面倒なのは次の2つです。

<!-- 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) );
    }
}

それをguiceに翻訳しようとすると(そしてこのモジュールを登録します):

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 に関係なく、最初の登録からのパラメータを持つことです。現在のユーザーの役割を考慮して、ユーザーを別のサイトにルーティングする他のソリューションはありますか? 2 つの異なる構成で同じサーブレット クラスを構成することは可能ですか?

4

1 に答える 1

3

解決策を見つけましたが、完全には満足していません。偽りのないソリューションでは、Web コンテナー (Tomcat) が同じサーブレット クラスを使用し、異なる init パラメーターを挿入する 2 つの別個のサーブレットを作成することがわかりました。Guice はデフォルトでサーブレットをシングルトンに制限しているため、web.xml ソリューションからデフォルトの動作をコピーするには、同じクラスの 2 つのインスタンスを作成し、異なるパラメーターで 2 回登録する方法を見つける必要がありました。これを解決するには、サーブレット クラスに 2 つのサブクラスを作成し、両方ともボディを空にしてから、それらを異なるパラメーターで登録しました。

この解決策は機能しますが、満足できない空のボディ サブクラスを作成する必要があります。サブクラスが 2 つあれば問題ありませんが、サブクラスが増えるとコードが煩雑になります。

于 2011-10-08T14:42:56.730 に答える