[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends-ml 10868] Re: 権限により表 示内容を変えたい



こんばんは。伊藤です。


On Fri, 24 Oct 2003 21:45:55 +0900
Yan Kanai <ykanai@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> MenuBar.jspには、次のようなメニューコンポーネントが挿入されるタグを書いてや
> ればよいということですよね?
すみません。かなり大雑把に書いたのでもうちょっと詳しく書きます。
(あと、definitions.xmlの書き方も微妙に変だった 汗)

まず、各画面でのパーツを定義します。
<definition name="menu.superuser.editGroup">
  <put name="title" value="グループ編集"/>
  <put name="link" value="/group/edit.jsp"/>
</definition>
<definition name="menu.superuser.editUser">
  <put name="title" value="ユーザ編集"/>
  <put name="link" value="/user/edit.jsp"/>
</definition>
<definition name="menu.user.viewGroup">
  <put name="title" value="グループ閲覧" />
  <put name="link" value="/group/view.jsp"/>
</definition>

権限によってメニュー表示を切り替えるjsp
<definition name="menu.menubar" path="menubar.jsp" />

メニューコンポーネントを並べるjsp
<definition name="menu.menulist" path="menulist.jsp" />

各権限ごとにパーツを定義します。
<definition name="menu.user" extends="menu.menulist">
  <putList name="menus">
    <add name="definitions" value="menu.user.viewGroup"/>
  </putList>
</definition>
<definition name="menu.superuser" extends="menu.menubar">
  <putList name="menus">
    <add name="definitions" value="menu.superuser.editUser"/>
    <add name="definitions" value="menu.superuser.editGroup"/>
    <add name="definitions" value="menu.user.viewGroup"/>
  </putList>
</definition>

メニューコンポーネントを並べるmenulist.jspはこんなコードです
<tiles:importAttribute />
<table width="20%">
  <logic:iterate id="list" name="menus">
  <tr>
    <td>
      <tiles:insert attribute="list"/>
    </td>
  </tr>
  </logic:iterate>
</table>

権限によってメニューの表示切り替えるmenubar.jspはこんなコードです。
<logic:if 管理者>
  <logic:then>
    <tiles:insert definition="menu.superuser"/>
  </logic:then>
  <logic:else>
    <tiles:insert definition="menu.user"/>
  </logic:else>
</logic:if>

で、最終的にアクセスするjspでは
<tiles:insert definition="menu.menubar"/>と書くとメニューが挿入されます。


と、ここまで書いて気づいたのですが、宮本さんのおっしゃっているroleが
tilesでも利用可能なんですよね。ですので。先のmenubar.jspでの条件分岐が
必要ないですね。roleにマッチしない場合、そのタグは無視されるので
menubar.jspでは
<tiles:insert definition="menu.superuser" role="superuser"/>
<tiles:insert definition="menu.user" role="user"/>
と書けば十分ですね。

このようにすればメニューの定義、メニューのデザイン、権限によって変化する
メニューとがすべて分離されます。「メンテナンス容易さ要求度」が低ければも
っと簡単に書くこともできますね。


> 回のアプリは、画面は多いのですが、デザインは共通にしてしまってよいので、大量
> のJSPをサーブレットにまとめられるんであれば、そうしたいのですが。もう少し、
> 詳しく教えていただけないでしょうか?
そうですね〜 自分がこの間作成したサイトでも基本デザインをBasicLayout.jsp
で決定し、基本デザインの中のコンポーネントをdefinitions.xmlで記述したので
各jspでは<tiles:insert definition="hogehoge"/>があるだけでした。

ここで、URLという物理名からdefinitionという論理名へのマッピングが個々のファ
イルに分散している、という気持ち悪い状況が発生します。そこでこれを解決すべく
でっち上げたのが話題のサーブレットです。

それは *.viewにマッチするサーブレットで、物理名から論理名へのマッピングを行
います。(作成したサイトではURLは論理名と一致させていたのでパス中の'/'を'.'
に置換しただけです)コードを見ていただければ分かると思いますが、サーブレット
内で<tiles:insert definition="hogehoge"/>を呼び出し、その結果を返しているだけ
です。(jasperの出力したjspを参考にしました)

public class jsp2definition extends HttpServlet {
  public void service(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException {
    
    // INCLUDE_SERVLET_PATH is set by RequestDispatcher
    String path = (String)request.getAttribute(RequestProcessor.INCLUDE_SERVLET_PATH);
    if(null == path) {
      path = request.getServletPath();
    }
    
    String definition = 物理名から論理名へのマッピング(path);
    MyInsertTagJSP myjsp = new MyInsertTagJSP();
    
    myjsp.setDefinition(def);
    myjsp.setParent(this);
    myjsp._jspService(request, response);
  }
  private class MyInsertTagJSP extends HttpJspBase {
    private Servlet parent;
    private String definition;
    private void setParent(Servlet sv) { parent = sv; }
    private void setDefinition(String str) { definition = str; }
    
    public void _jspService(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {
      
      long start = System.currentTimeMillis();
      JspFactory _jspxFactory = null;
      PageContext pageContext = null;
      HttpSession session = null;
      ServletContext application = null;
      ServletConfig config = null;
      JspWriter out = null;
      Object page = this;
      String  _value = null;
      try {
        _jspxFactory = JspFactory.getDefaultFactory();
        response.setContentType("text/html;charset=Shift_JIS");
        pageContext = _jspxFactory.getPageContext(parent, request, response,
                                                  "", true, 8192, true);
        application = pageContext.getServletContext();
        config = pageContext.getServletConfig();
        session = pageContext.getSession();
        out = pageContext.getOut();
        
        /* ----  tiles:insert ---- */
        InsertTag mytag = new InsertTag();
        mytag.setPageContext(pageContext);
        mytag.setParent(null);
        mytag.setDefinition(definition);
        mytag.setFlush("true");
        try {
          int i = mytag.doStartTag();
          if(i == BodyTag.EVAL_BODY_BUFFERED)
            throw new JspTagException("Since tag handler class org.apache.struts.taglib.tiles.InsertTag does not implement BodyTag, it can't return BodyTag.EVAL_BODY_TAG");
          if(i != Tag.SKIP_BODY) {
            do { } while (mytag.doAfterBody() == BodyTag.EVAL_BODY_AGAIN);
          }
          if(mytag.doEndTag() == Tag.SKIP_PAGE)
            return;
        } finally {
          mytag.release();
        }
        out.write("<!-- Creating this page took ");
        out.write(String.valueOf(System.currentTimeMillis() - startTime));
        out.write(" milliseconds. -->");
<後略>

以上です。


-- 
Tetsu Ito <vfe03165@xxxxxxxxx>