struts 1.xからstruts 2(3)OGLLにアップグレード


OGLLはObject-Graph Navigation Languageと全称され、式言語(EL)である.
ELの支持者は、JSPページではできるだけ<%>>のようなマークを避けるべきであり、代わりにTagでページをより簡潔にし、ページとバックグラウンドコードの分離の設計原則を体現しなければならないと考えている.Tagを使用したページの可読性が<%>>より高いとは思わないので、私は意見を保留します.
Struts 2は次のようなELをサポートします.
  • OGLL(Object-graph Navigation Language):オブジェクトのプロパティを簡単に操作できるオープンソース言語
  • JSTL(JSP Standard Tag Library):JSP 2.0に統合された標準的な式言語
  • Groovy:Javaプラットフォームに基づく動的言語で、Python、Ruby、Smarttalkなどの比較的流行している動的言語のいくつかの新しい特性
  • を備えています.
  • Velocity:厳密には式言語ではなくJavaベースのテンプレートマッチングエンジンで、JSPより性能が良いと言われています.
    Struts 2のデフォルトの式言語はOGLLです.他の式言語に比べて次のようなメリットがあります.
  • は、xxx.doSomeSpecial()などのオブジェクトメソッド呼び出しをサポートします.
  • はクラス静的メソッド呼び出しと値アクセスをサポートし、式のフォーマットは@[クラスフルネーム(パッケージパスを含む)]@[メソッド名|値名]であり、例えば:@java.lang.String@format('foo%s','bar')または@tutorial.MyConstant@APP_NAME;
  • は、price=100、discount=0.8、calculatePrice()などの付与操作と式の直列接続をサポートし、この式は80を返します.
  • OGLLコンテキスト(OGLL context)とActionContextにアクセスする.
  • は、集合オブジェクトを操作する.

  • OGLLは、通常、Struts 2のフラグと組み合わせて使用されます.たとえば、<::property value="xx"/>などです.よくある問題は、#、%と$の3つの記号の使用です.この問題について説明します.
    4.1"#"の用途
    OGLLコンテキストとアクションコンテキストへのアクセス
    #ActionContext.getContext()に相当します.次の表に、ActionContextで使用できるプロパティをいくつか示します.
  • parameters:現在のHTTP要求パラメータを含むMap,#parameters.id[0]はrequest.getParameter(「id」)
  • に相当する.
  • request:現在のHttpServeretRequestのプロパティ(attribute)を含むMap、#request.userNameはrequest.getAttribute(「userName」)
  • に相当します.
  • セッション:現在のHttpSessionのプロパティ(attribute)を含むMa、#セッション.userNameはセッション.getAttribute(「userName」)
  • に相当します.
  • アプリケーション:現在のアプリケーションのサーブレットContextのプロパティを含むMap、#アプリケーション.userNameはアプリケーション.getAttribute("userName")
  • に相当します.
  • attr:request>session>applicationの順序でその属性(attribute)にアクセスするために使用されます.#attr.userNameは、見つかるまで3つの範囲(scope)でuserName属性を順番に読み込むことに相当します.
    フィルタと投影(projecting)コレクション
    例えばbooks.{?#this.price<100}
    構築Map
    例えば#{'foo 1':'bar 1','foo 2':'bar 2'}
    この3つの用途について説明します.
    Book.java
    本の情報を記述するためのBeanです
    package example;

    public class Book {
    private String isbn;
    private String title;
    private double price;

    public Book() {
    }

    public Book(String isbn, String title, double price) {
    this.isbn = isbn;
    this.title = title;
    this.price = price;
    }

    public String getIsbn() {
    return isbn;
    }

    public void setIsbn(String isbn) {
    this.isbn = isbn;
    }

    public double getPrice() {
    return price;
    }

    public void setPrice(double price) {
    this.price = price;
    }

    public String getTitle() {
    return title;
    }

    public void setTitle(String title) {
    this.title = title;
    }
    }


    BookDao.java
    擬似DAOクラス
    package example;

    import java.util.Collection;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;

    public class BookDao
    {
    private static final BookDao instance;
    private static final ConcurrentMap<String, Book> data;

    static {
    instance = new BookDao();
    data = new ConcurrentHashMap<String, Book>();
    data.put("978-0735619678", new Book("978-0735619678", "Code Complete, Second Edition", 32.99));
    data.put("978-0596007867", new Book("978-0596007867", "The Art of Project Management", 35.96));
    data.put("978-0201633610", new Book("978-0201633610", "Design Patterns: Elements of Reusable Object-Oriented Software", 43.19));
    data.put("978-0596527341", new Book("978-0596527341", "Information Architecture for the World Wide Web: Designing Large-Scale Web Sites", 25.19));
    data.put("978-0735605350", new Book("978-0735605350", "Software Estimation: Demystifying the Black Art", 25.19));
    }

    private BookDao() {}

    public static BookDao getInstance() {
    return instance;
    }

    public Collection<Book> getBooks() {
    return data.values();
    }

    public Book getBook(String isbn) {
    return data.get(isbn);
    }

    public void storeBook(Book book) {
    data.put(book.getIsbn(), book);
    }

    public void removeBook(String isbn) {
    data.remove(isbn);
    }

    public void removeBooks(String[] isbns) {
    for(String isbn : isbns) {
    data.remove(isbn);
    }
    }
    }


    OgnlAction.java
    OGLLのサーブレットクラスのデモ
    package example;

    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;

    import javax.servlet.ServletContext;
    import javax.servlet.http.HttpServletRequest;

    import org.apache.struts2.interceptor.ServletRequestAware;
    import org.apache.struts2.interceptor.SessionAware;
    import org.apache.struts2.util.ServletContextAware;

    import com.opensymphony.xwork2.ActionSupport;

    public class OgnlAction extends ActionSupport implements ServletRequestAware, SessionAware, ServletContextAware {
    private static final long serialVersionUID = 1L;

    private HttpServletRequest request;
    private Map<String, String> session;
    private ServletContext application;
    private List<Book> books;

    public void setServletRequest(HttpServletRequest request) {
    this.request = request;
    }

    @SuppressWarnings("unchecked")
    public void setSession(Map session) {
    this.session = session;
    }

    public void setServletContext(ServletContext application) {
    this.application = application;
    }

    public List<Book> getBooks() {
    return books;
    }

    @Override
    public String execute() {
    request.setAttribute("userName", "Max From request");
    session.put("userName", "Max From session");
    application.setAttribute("userName", "Max From application");

    books = new LinkedList<Book>();
    books.add(new Book("978-0735619678", "Code Complete, Second Edition", 32.99));
    books.add(new Book("978-0596007867", "The Art of Project Management", 35.96));
    books.add(new Book("978-0201633610", "Design Patterns: Elements of Reusable Object-Oriented Software", 43.19));
    books.add(new Book("978-0596527341", "Information Architecture for the World Wide Web: Designing Large-Scale Web Sites", 25.19));
    books.add(new Book("978-0735605350", "Software Estimation: Demystifying the Black Art", 25.19));

    return SUCCESS;
    }
    }


    Ognl.jsp
    OGLLのJSPのプレゼンテーション
    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
    <%@ taglib prefix="s" uri="/struts-tags" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Struts OGNL Demo</title>
    </head>
    <body>
    <h3> OGNL Action </h3>
    <p>parameters: <s:property value="#parameters.userName" /></p>
    <p>request.userName: <s:property value="#request.userName" /></p>
    <p>session.userName: <s:property value="#session.userName" /></p>
    <p>application.userName: <s:property value="#application.userName" /></p>
    <p>attr.userName: <s:property value="#attr.userName" /></p>
    <hr />
    <h3> (projecting) </h3>
    <p>Books more than $35</p>
    <ul>
    <s:iterator value="books.{?#this.price > 35}">
    <li><s:property value="title" /> - ___FCKpd___3lt;s:property value="price" /></li>
    </s:iterator>
    </ul>
    <p>The price of "Code Complete, Second Edition" is: <s:property value="books.{?#this.title=='Code Complete, Second Edition'}.{price}[0]"/></p>
    <hr />
    <h3> Map</h3>
    <s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
    <p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>
    </body>
    </html>


    example.xml
    struts 2のMVCプロファイル
    <action name="Ognl" class="example.OgnlAction">
    <result>/Ognl.jsp</result>
    </action>


    4.2%の使い方
    「%」記号は、フラグの属性が文字列タイプの場合にOGLL式の値を計算するために使用されます.たとえば、Ognl.jspに次のコードを追加します.
    <h3>%   </h3>
    <p><s:url value="#foobar['foo1']" /></p>
    <p><s:url value="%{#foobar['foo1']}" /></p>


    ページをリフレッシュして、次の内容を表示します.
    %   

    #foobar['foo1']

    bar1


    4.3$の使い方
    「$」には2つの主な用途があります.
  • 国際化リソースファイルにおいて、OGLL式
  • を参照するために使用される
  • Struts 2プロファイルでは、
  • のようなOGLL式が参照されます.
    <action name="AddPhoto" class="addPhoto">
    <interceptor-ref name="fileUploadStack" />
    <result type="redirect">ListPhotos.action?albumId=${albumId}</result>
    </action>