struts2の最近の情報

twitterと連携するアプリケーション作成のためのAPI群です。

 

OAuthというツイッターの認証機能を利用できる仕組みがあるので、

お手軽に、しかもユーザにとっても安心・安全に利用できる仕組みになってる。

 

OAuthを利用するためには、アプリケーションを登録しないといけないので、

http://twitter.com/apps

上記より、登録します。

 

登録すると、Consumer key、Consumer secret という情報を取得できるので、

その情報を利用して、ユーザを、twitterの認証ページに誘導し、アプリの利用の

同意を頂くと、アプリから、そのユーザができる操作を代行できるようになる。

 

今回は、好きな"お酒"のことに特化したつぶやきをするためのアプリ、

「saketter(さけったー)」というWebアプリを作成してみた。

"いまなにのんだ?"をコンセプトに、飲んだお酒と"つぶやき"を投稿するアプリ。

(また、#sake というカテゴリが自動で設定されるようになってます)

 

1.ログインボタンを押す

2.Consumer key、Consumer secretを 設定しtwitterの認証ページにリダイレクト

3.認証が成功すると、事前に設定したアプリのページに自動で戻ってくる

4.AccessTokenという、認証が成功したユーザを操作するための権限を取得する

5.AccessTokenを利用して、"つぶやく" など、必要な処理を呼び出す。

 

今回は、Java(Struts2)を利用して、Webアプリケーションを作成した。

twitter4jというOAuthも手軽に利用できるライブラリがあったので。

 

要点のコードを抜粋

//最初にtwitterのサイトへ誘導し認証させる

Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer("xxxxxxxxxx", "yyyyyyyyyy");
RequestToken token = twitter.getOAuthRequestToken();
sessionMap.put("twitter", twitter);
response.sendRedirect(token.getAuthenticationURL());

 

//次に認証が成功すると任意のページへリダイレクトされるので権限を取得

Twitter twitter = (Twitter)sessionMap.get("twitter");
if (twitter != null) {
 AccessToken token = twitter.getOAuthAccessToken();
 sessionMap.put("token", token);

}

 

//権限を利用してアプリから"つぶやき"を投稿

AccessToken token = (AccessToken)sessionMap.get("token");
if (token != null) {
 Twitter twitter = (Twitter)sessionMap.get("twitter");
 twitter.updateStatus("つぶやきを投稿");
}

 

※これでひととおりの操作が可能です。

つぶやき以外にも様々な操作がAPIで提供されてます。

 

※携帯からの利用についてですが、twitterの認証機能は、https対応ですが

携帯で表示時にtwitterの証明書ではエラーになるようです。

なので、HTTPリクエストのヘッダーで、携帯からのアクセスかを判断して、

携帯からの場合は、HTTPSを、HTTPへ書き換えてあげるとうまくいきます。

セキュリティが弱くなるけれど、twitterで通常の携帯ログインもHTTPのよう

なので、とりあえず問題はないかと...。


 とりいそぎ最低限のラインで作成してみたので、

また機能アップしていきたいと思います。

 

続 Struts 2入門

| コメント(0) | トラックバック(0)

CodeZineで、Struts2入門(1)?(8) の続編、

続 Struts 2入門が始まりました!!

 

Strutsは以前から利用しているので、Struts 2になった今後も是非とも

発展し続けていってほしいと思う。

自分自身でもStrtuts2でWebアプリケーションを作っているので、

いろいろと情報発信して、Struts2の発展に貢献できればなと思う。

 

Strutsの時よりも、情報源が少なく感じ、なかなか活用しきれていない

面があるので、こういった連載が始まるのはありがたい!!

記事を見てもらうほうが詳細に理解できますが、さわりだけわかれば

良い方は以下を参照してください。

 

続 Struts 2入門

基本機能のおさらいから2.1系で採用された機能の説明や実装例を紹介

(1)Struts 2の同期処理を手助けするExecuteAndWaitインターセプタ

 

処理に時間がかかるActionクラスの処理状況を監視し、その結果を自動的に

判断するためのExecuteAndWaitインターセプタの使用例を解説。

 

Actionクラスにはメインのロジックを記述するだけで、あとは設定のみで、

同期処理を実現することが可能になります。

 

具体的な手法としては、

ブラウザの自動リフレッシュ機能を利用し、Actionクラス内の時間の

かかる処理を、自動で途中中断して、リフレッシュを設定したページを表示。

(Actionの実行は継続されセッションに維持される)

 

再度リフレッシュしてサーバにアクセスすると、中断したActionの状況を

再度監視できるようになっている。

まだ処理中の場合は、再度リフレッシュページへ、処理が完了した場合は

完了用のページが表示されるという仕組みです。

 

これらを、上記のExecuteAndWaitインターセプタ(アノテーションの機能)

を利用することで設定をおこなうことで、簡単に利用することができます。

 

インターセプタ(汗)

まだぜんぜん利用できていないので、実用できるように勉強します。

次回もインターセプタの機能についての記事のようです。

 

<html:base>タグ

<html:base>タグは、Struts1で用意されていたタグライブラリである。

このタグは、HTMLの<base>タグを出力するためのタグです。

<base>タグは、<head>タグ内で記述し、<base href="[絶対パス]"> という書式になります。このタグは、HTMLファイルに相対パスで記述されたURIの基準となるURIを指定します。基準となるURIは、[絶対パス] 部分で指定された絶対パスです。

 

Struts1

このタグは、リクエスト時にフィルターの機能を用い、URL書き換えをおこなう場合に便利です。URL書き換えをした場合に、見かけ上のURLの階層が変わってしまったりすると、相対パスで記述しているリンクや、画像ファイルが正しくリンクされないようになってしまうからです。

この時に<html:base/>タグを記述していると、相対パスの基準となるURIが固定される(出力されるファイルの階層に固定される)ため、URL書き換えで見た目のURLの階層がいくら変化しても、各リソースのリンクには全く問題がなくなります。

 

Struts2

Struts2のタグライブラリには残念ながら、<html:base>に代わるものが存在しません。これは、画像やリンクなどの各リソースのURLの指定をするために、<s:url value="[リソース]"> タグを使うことで、<base> タグを指定する必要がなくなるためだからだろうと思いました。

しかしながら、各リソースのURLを動的に指定する必要がある場合、value属性に、<s:property> タグを入れ込んだりしての、URLの動的作成がうまくいきませんでした(もしかしたら、うまくやれば可能なのかもしれません...) さらに、フィルターによるURLの動的書き換えを組み合わせると、URLが2重になったりと先が見えなかったので、Struts1のように<base>タグを自前で出力させる方法を考えました。

 

<base>タグの出力

発想はいたって単純ですが、フィルターの処理中に、ベースとなるURLをrequestオブジェクトに保存しておき、viewの部分でそれを取り出し、<base>タグのhref属性に指定してあげるという方法です。

ポイントはベースとなるURLをどのように作成するところですが、以下のようにすることで簡単に求められそうです。

 

  //ベースURLの設定
  String url = req.getRequestURL().toString();
  int len = url.length() - req.getRequestURI().length();
  req.setAttribute("htmlbase",  url.substring(0, len) + req.getContextPath() + "/");

 

そして、viewでは以下のように呼び出すだけです。

   

    <%@taglib prefix="s" uri="/struts-tags" %>

    <head>

        <base href="<s:property value="#request.htmlbase"/>"/>

    </head>

 

以上で、Struts1の<html:base/>の処理と同様のことができるようになりました。

※他にもっと良い方法があるかもしれませんが、リソースのURLを動的に作成したり、フィルターにてリクエストのURLを書き換えてフォワードさせたりという処理を組み合わせると、思うような処理ができませんでした。

 

また、Struts2で、リクエストのURLを書き換え、フォワードしてアクションを実行させようとしてもできないトラブルの解決方法は以下を参照ください。

Struts2 RequestDispatcher の動作について

 

getRequestDispatcher foward

Strutsをはじめ、上記のようにリクエストのフォワーディングをおこなうことは少なくないのではないでしょうか?URLReWriteのような形で特定のURLパターンにマッチした場合にアドレスを変換したり、*.html のアドレスでアクセスされた場合に内部的には、*.jsp や、*.do などの動的な処理に転送したい場合などが考えられる。

また、サイトにアクセス制御がかけられている場合は、認証されていない場合にログイン画面に転送するなどにも利用される。

 

Struts2での問題

ここで今まで利用してきた Struts1では、上記のような処理を、通常、web.xml で設定された、フィルターの機能を利用しておこなっていた方も多いのでしょうか?これは非常に簡単なコーディングにてリクエストの転送を問題なくおこなえていました。

 

web.xml

  <filter>
    <filter-name>accessFilter</filter-name>
    <filter-class>com.pg2se.AccessFilter</filter-class>
  </filter>
 
  <filter-mapping>
    <filter-name>accessFilter</filter-name>
    <url-pattern>/security/*</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

com.pg2se.accessFilter#doFilter

  if (checkLogin == false) {

    request.getRequestDispatcher("/login.do").forward(req, res);

  } else {

    chain.doFilter(req, res); 

  }

 

同様の処理を Struts2 に移植または実装しようとした際に、何も考えずコーディングした場合に、リクエストのフォワードがうまく動作しない現象が発生してしまうのではないでしょうか?

 

具体的には、

request.getRequestDispatcher("/login.action").forward(req, res);

 

と記述しても、

"/logon.action" is not available

 

となってしまいます。最初は原因はわからなくて戸惑うかも知れませんが、これは、Struts1 と Struts2 のアクションが起動される仕組みが変更されているからです。

 

web.xml

 <filter>
  <filter-name>AccessFilter</filter-name>
  <filter-class>com.pg2se..AccessFilter</filter-class>
 </filter>

 

 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
 </filter>

 

 <filter-mapping>
  <filter-name>AccessFilter</filter-name>
  <url-pattern>/security/*</url-pattern>
 </filter-mapping>
 

 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 

Struts2 では、一般的に、上記のように記述しているのではないでしょうか?

この、Struts1 の記述と、Struts2 での記述の違いをみると、アクションの起動が、Struts1 では、servlet-mapping が利用されているのに対し、Struts2 は、filter-mappping を利用しているという点です。

 

AccessFilter の中で、Struts1と同じように、getRequestDispatcherで、foward をおこなっても、アクションは起動されないようになっている。なぜなら、Struts2 では、アクションはフィルターで動作するようになっおり、デフォルトでは、リクエスト時にはフィルターが呼び出されるが、foward時にはフィルターが呼び出されないようになっているからである。

 

これを回避するのは意外と簡単で、web.xml で設定できる。

設定の詳細はこちらのページで詳しく書かれています。

 

web.xml

 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>
 </filter-mapping>

 

アクションの、filter-mapping にて、<dispatcher>要素を記述する。

記述できる値は、REQUEST、FORWARD、INCLUDE、ERROR である。

ここで、FORWARDを指定すれば、getRequestDispatcher#foward をおこなった際にも、

該当のフィルターが起動され目的の処理をおこなうことができるようになる。

 

 

はじめに

今回はStruts2を利用した、より実践的なアプリケーションの作成をおこなってみたいと思います。今回も前回と同様、ZeroConfigurationで開発をおこなっています。

Struts2の開発の準備がまだ整っていない場合は以下も参考にしてください。

 

このアプリケーションの解説の中では今後さらにしっかりとしたアプリケーションを開発していくにあたってのポイント、改良点なども記述していますので是非参考にしてください。

 

アプリケーションの概要

このアプリケーションは、シンプルな掲示板アプリケーションです。

複数の端末から共通の掲示板に情報を書き込み、その内容を共有するという単純なものです。情報には、投稿者の名前とメッセージ、そして投稿日時と投稿した端末のIPアドレスを自動で取得した内容が含まれます。

アプリケーションの仕様について簡単にまとめます

  • 掲示板のURLにアクセスすると現在の掲示板の情報が一覧表示されます。
  • "更新"ボタンを押すと、掲示板の情報が最新表示されます。
  • 掲示板の情報は、投稿日が新しいものから順に表示されます。
  • "名前"と"メッセージ"を任意に入力し、"投稿"ボタンを押すと、掲示板に情報が
    登録され、掲示板の内容が最新表示されます。
  • "名前"、"メッセージ"のいずれかが未入力の場合はエラーメッセージが表示され
    掲示板に情報は登録されません。

 

  • アプリケーション画面

simple_board.jpg 

 

ソースコード解説

シンプルな機能の掲示板ではありますが、アプリケーションとしてはMVCモデルを意識し、今後の拡張性も含めながら作成してみました。

 

  • モデル

BoardData .java

掲示板へ登録する情報を格納するデータを保持するクラスです。

データの保持以外の機能は特にありません。  

package com.pg2se.sample.model.board;

public class BoardData {

    private String postDate;
    private String name;
    private String message;
    private String remoteAddress;
   

 public String getPostDate() {
  return postDate;
 }
 public void setPostDate(String postDate) {
  this.postDate = postDate;
 }
 
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
 public String getMessage() {
  return message;
 }
 public void setMessage(String message) {
  this.message = message;
 }
 
 public String getRemoteAddress() {
  return remoteAddress;
 }
 public void setRemoteAddress(String remoteAddress) {
  this.remoteAddress = remoteAddress;
 }

}

 

Board.java

複数の端末で共有する掲示板のオブジェクトと掲示板に情報を登録する機能を持ったクラスです。

package com.pg2se.sample.model.board;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Vector;

public class Board {

    private static List<BoardData> board = new Vector<BoardData>();
    private static SimpleDateFormat sdformat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    
    public static List<BoardData> addChatData(String name, String message, String remoteAddress){
     BoardData data = new BoardData();
     data.setName(name);
     data.setMessage(message);
     data.setRemoteAddress(remoteAddress);
     data.setPostDate(sdformat.format(new Date()));
     board.add(0, data);
     return board;
    }
    
    public static List<BoardData> getChatData(){
     return board;
    }

}

 

  • ビュー
  • board/board.jsp

    掲示板への情報の投稿と掲示板の情報の表示をおこないます。

     

    入力エラーの内容は<s:actionerror/>タグによって出力されます。

     

    "ValueStack"をコードで記述している部分ですが、board.jspをアドレスに指定されて呼び出された場合にアクションが呼び出されず掲示板の最新情報が取得できていないため無理やり取得しています。Struts1の場合は、フォームに関連付けられたformbeanが初期化されるため初期表示も可能だったんですが...。もっと良い方法あればいいんですが。

     

    また、"remoteAddress"をここで取得していますが詳細は後述します。

     

    ボタンは情報投稿用のボタンと、最新情報取得用の更新ボタンがありますが、method属性を指定して、呼び出すアクションクラスのメソッドを指定できます。

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@page import="com.pg2se.sample.model.board.Board"%>
    <%@page import="com.opensymphony.xwork2.util.ValueStack"%>
    <%@page import="org.apache.struts2.ServletActionContext"%><html>
    <%@taglib prefix="s" uri="/struts-tags" %>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>シンプル掲示板</title>
    </head>
    <body>
        <h1>シンプル掲示板</h1>
        <h2>struts2で作成するサンプルアプリケーション</h2><hr/>
       
        <s:form action="board.action" theme="simple">
          <input type="hidden" name="remoteAddress" value="<%= request.getRemoteAddr() %>"/>
          <s:text name="名前"/> <s:textfield name="name" size="10"/>
          <s:text name="メッセージ"/> <s:textfield name="message" size="60" value=""/>
          <s:submit value="投稿"/><s:submit value="更新" method="update"/>
        </s:form><hr/>
       
        <s:actionerror/>
       
        <table border="1">
     <%
      ValueStack stack = (ValueStack)request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
      if(stack!=null && stack.findValue("data")==null){
       stack.set("data", Board.getChatData());
      } 
     %>
        <s:iterator value="data" status="stat">
            <s:if test="#stat.first">
              <th>日時</th>
              <th>名前</th>
              <th>テキスト</th>
              <th>IPアドレス</th>
            </s:if>
            <tr>
              <td><s:property value="postDate"/></td>
              <td><s:property value="name"/></td>
              <td><s:property value="message"/></td>
              <td><s:property value="remoteAddress"/></td>
            </tr>
        </s:iterator>
        </table>
    </body>
    </html>

     

    • コントローラ

    BoardAction.java

    掲示板の情報の登録と最新表示をおこなうためのアクションです。

     

    メッセージの投稿用にはデフォルトのアクションexecuteメソッドを、最新情報取得用のアクションにはupdateを使用します。

     

    ActionSupportクラスを継承することで、validation(バリデーション:検証)やメッセージ・エラーメッセージを簡単に設定することができます。validateメソッドを実装するだけでよいのですが今回は使用しませんでした。理由は、validateメソッドはすべてのアクションに対して実行されてしまうため、今回バリデーションの必要がないupdateメソッドに適用されたくなかったためです。今回は自前のisValidメソッドで検証をおこなっています。※xmlファイルでバリデーションの定義をする場合は検証を除外するメソッドを設定できたりするようです。他にも方法はあるようなのですがわかりませんでした、

     

    "remoteAddress"についてはjspファイルから渡されるようにしています。本来はアクションクラスで、requestオブジェクトから取得したいのですがActionSupportクラスからは取得できないようです。取得するためには、ServletRequestAwareインターフェイスを実装する必要があります。そうすると実行時にHttpServletRequestオブジェクトが注入されるようです。

     

    今後の拡張として、掲示板の情報の編集・削除等のメンテナンスや掲示板の情報をデータベースへ保存し永続化するという点が考えられます。

    package com.pg2se.sample.action.board;

    import java.util.List;
    import com.opensymphony.xwork2.ActionSupport;
    import com.pg2se.sample.model.board.Board;
    import com.pg2se.sample.model.board.BoardData;

    public class BoardAction extends ActionSupport {

     private String name;
        private String message;
        private String remoteAddress;
        private List<BoardData> data;
     private static final long serialVersionUID = 1L;
       
     public String getName() {return name;}
     public void setName(String name) { this.name = name;}

     public String getMessage() {return message;}
     public void setMessage(String message) {this.message = message;}
     
        public String getRemoteAddress() {return remoteAddress;}
     public void setRemoteAddress(String remoteAddress) {this.remoteAddress = remoteAddress;}

     public List<BoardData> getData() {return data; }
     public void setData(List<BoardData> data) {this.data = data;}
     
     //execute
     public String execute() {

      if(isValid()){
      
          data = Board.addChatData(name, message, remoteAddress);
         
         } else {

          data = Board.getChatData();
         }
      
         return "success";
        }
     

     //update
     public String update() {
      
      data = Board.getChatData();
      
      return "success";
        }
     
     //validate
     public boolean isValid() {
      if(name == null || name.equals("")){
       addActionError("名前を入力してください");
      }
      if(message == null || message.equals("")){
       addActionError("メッセージを入力してください");
      }
      
      return !hasActionErrors();
     }
    }

    Zero Configuration

    それでは、Struts2での最初のアプリケーションを作成してみたいと思います。

    Struts2の特徴の一つに"Zero Configuration"があります。

    これは、Struts1で、xml地獄と呼ばれた、一連のアクションを実行するため、

    各コンポーネントを連携するために必要な設定を、xmlの設定ファイルで記述し、

    その設定ファイルが膨大になってしまいがちになる短所を改善するための機構

    です。

     

    Struts1で、JSP-ActionForm-Action-JSPの連携を全てstruts-config.xmlで設定

    していたものを、Struts2では、JSP-POJO-JSPの最小構成で、連携の設定を

    記述することなく動作させることができます。

     

    では具体例を見ていきましょう。

     

    Hello World!!

    例の如く、簡単なHello World!!アプリケーションを作成していきます。

    ポイントを絞って説明しますので不足点あればコメント欄で質問ください。

    (環境)

    eclipse3.4.1(tomcatPlugin)

    jdk1.6.0_02

    tomcat-6.0.14

    struts2.0.14

     

    20090118.jpg

    1. プロジェクトの作成
      "動的Webプロジェクト"を選択しプロジェクトを作成します。
      注)デフォルトの、classesディレクトリがWEB-INFの外にあり、そこに後述の
      struts.xmlを配置しても認識されなかったので、classesは、WEB-INFの下に
      設定してください。

      ライブラリを配置します。struts2のファイルの中から以下をlibに配置します。
      ・commons-logging-1.0.4.jar
      ・freemarker-2.3.8.jar
      ・ognl-2.6.11.jar
      ・struts2-codebehind-plugin-2.0.14.jar
      ・struts2-core-2.0.14.jar
      ・xwork-2.0.7.jar
      ※codebehindプラグインが、Zero Configurationのミソで、JSPが配置されている
      ディレクトリとアクション名より自動的にアクションクラス(POJOでも可)を探します。
      またアクションクラス名と戻り値にて自動的にJSPファイルを探します。

    2. Web.xml
      ポイントは、Struts1と同様、フィルターおよびパターンにてリクエストをStruts2で処理
      できるように設定を書いている点と、またまたZero Configurationの肝になる、
      actionPackagesというパラメータ設定です。ここにパッケージ名を記述しますが、
      指定したパッケージが、Webアプリケーションのトップディレクトリと同じ階層となり
      JSPとアクションの自動での紐づけの対象となります。
      例えば、/webapp/index.jsp の中で、"index.action"を呼び出すと、
      (actionPackages).IndexAction クラスの execute メソッドを実行しようとします。
      下の私の例では、com.pg2se.sample.action を指定していますので、
      com.pg2se.sample.action.IndexAction#executeメソッドが呼び出されます。
      ※何も設定していなければ"execute"メソッドが呼び出されます。

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app id="WebApp_ID" version="2.4" xmlns="
      http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
       
      <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
        <init-param>
          <param-name>actionPackages</param-name>
          <param-value>com.pg2se.sample.action</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      </web-app>


    3. Struts.xml
      Struts.xmlは、classesの直下に置くことで認識されます。冒頭で書いたように、
      WEB-INF以下に配置しないとうまく動作しませんでしたので適宜設定を変更
      してください。
      ※Zero Configurationで作成するため、記述は最低限の以下だけでOKです。

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE struts PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
          "
      http://struts.apache.org/dtds/struts-2.0.dtd">
      <struts>
          <constant name="struts.enable.DynamicMethodInvocation" value="true" />
          <constant name="struts.devMode" value="false" />
      </struts>


    4. index.jsp
      今回は、Webアプリケーションのトップディレクトリのindex.jspにアクセスし、ボタンを
      押すと、"Hello World!!"のメッセージが表示される簡単なアプリケーションにしています。
      ポイントは、Struts2のタグライブラリ(プレフィックス:s)の宣言をしている点と、
      Formのアクション設定に"index.action"を設定している点、プロパティ"message"を
      表示している点です。最初にJSPにアクセスした場合はプロパティは設定されていま
      せんのでボタンのみ表示されます。

      <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
      <%@ taglib prefix="s" uri="/struts-tags" %>
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
      http://www.w3.org/TR/html4/loose.dtd">
      <html>
        <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
          <title>Struts2</title>
        </head>
        <body>
          <s:form action="index.action" theme="simple">
            <s:property value="message"/><br/>
            <s:submit value="メッセージ"/>
          </s:form>
        </body>
      </html>


    5. IndexAction.java
      ここでのポイントは、パッケージの設定を、actionPackagesパラメータに
      合わせている点と、Actionの実行設定をしていない際のデフォルトで実行
      される、executeメソッドを実装している点と、ActionFormが無くなった
      代わりに、このクラスにプロパティを設定し、executeメソッドで、プロパティ
      に値をセットしている点、そしてクラスがPOJOである点です。
      ここまでの設定が正しければ、JSPよりボタンが押されると、execute
      メソッドが実行されるはずです。

      package com.pg2se.sample.action;

      public class IndexAction {
       
        private String message;

        public String getMessage() {
          return message;
        }

        public void setMessage(String message) {
          this.message = message;
        }
       
        public String execute() {
          message = "hello world!!";
          return "success";
        }

      }


    6. 最後に
      Actionが実行した最後に"success"を戻り値で返していますが、今回の場合、
      index-success.jspが優先で呼ばれるのですが、ファイルが存在しない場合は、
      次にindex.jspが呼ばれます。(結果的に再度呼び出し元のJSPが実行される
      ことになります)
      この際に、今度はActionでmessageプロパティが設定されていますので、その
      内容が、JSPの、

      <s:property value="message"/>

      の部分で表示されます。

      以上で、超簡単Struts2アプリが完成しました。

      次回は、より実践的にシンプルな掲示板アプリを作成して見たいと思います。

    最初に

    まずStruts2をインストールする前提条件ですが、

    Java SE(JDK)がインストールされていること、

    Tomcatがインストールされていることを前提としています。

    ※アプリケーションサーバについてはTomcatではなくても問題ないですが、

    その場合は適宜、Tomcatに関連する説明文は読み替えてください。

     

    Struts2について

    Struts2についての説明についてはこちらを参照してください。

    Struts2はフレームワークですので、それの単体では特に意味をなさないものですが、

    サンプルのアプリケーションが添付されているので、サンプルの動作確認と、

    実際に、Strtuts2のフレームワークを利用した最初のアプリケーションを

    作成して見たいと思います。

     

    ダウンロード

    Struts2のダウンロードはここから行います。

    2008年12月22日時点での最新版は、struts-2.0.14です。

    ここでは、Full Distribution である、struts-2.0.14-all.zip を

    上記リンクよりダウンロードして任意の場所に解凍しておきます。

     

    showcase - サンプルアプリケーション

    解凍した場所の/apps/struts2-showcase-2.0.14.warを短い名前に変更します。

     →showcase.war に変更

    変更したファイルを、Tomcatのアプリケーションを配備場所にコピーします。

     →TOMCAT_HOME/webapps/showcase.war

     

    以上でTomcatを起動すると、標準の設定では、

    http://localhost:8080/showcase/ でアクセスすると以下の画面が表示されるはずです。

    20081222_01.jpg

    以下のように様々なサンプルが公開されていますので、

    まずはサンプルを色々と触ってみて動作の確認をしてみてください。

    • Home
    • Ajax Theme for Struts Tags
    • Ajax Chat
    • Action Chaining
    • Config Browser
    • Conversion
    • CRUD
    • Execute & Wait
    • File Download
    • File Upload
    • Freemarker
    • Hangman
    • JavaServer Faces
    • Person Manager
    • Tags
    • Tiles
    • Token
    • Validation
    • Help 

     

    次回は実際に、Struts2のフレームワークを利用して、

    オリジナルのアプリケーションを作成してみます。

     

     

     

    背景

    JavaのWebアプリケーションフレームワークのデファクトなった、Struts。しかしその後、Webアプリケーションフレームワークはさらに進歩を続けてゆき、今ではさまざまなWebアプリケーションフレームワークが登場することになった。

     

    Seasar2JSF(Java Server Faces)、Spring、Java以外でも、ASP.NETRuby on Railsなどなど。もちろんこれらのフレームワークにも、Strutsの影響が少なからずあるということは間違いないと思う。

     

    Struts 1

    そして、そのStrutsも、もちろんバージョンアップを続け、2008年6月22日現在、1.3.8 までバージョンアップを遂げている。このStrutsは、Struts 1(Struts1.x系)と呼ばれ、今でも、多くのユーザで使用され続けている。

     

    WebWork

    そして、この記事で紹介する、Struts2 とは、上記の Struts 1 の後継となるバージョンというのは名前からも容易に想像できる。しかし、後継となるバージョンとなっていながら、この2つの Struts には、互換性はなく、フレームワークとしても全く別のものになっている。もちろん内部的な処理・エンジン部分についても違いは大きい。

    その理由としては、Struts2 の開発は、Struts1 をベースに開発されたのではなく、先にも紹介した、Struts に影響を受けたWebアプリケーションフレームワークのひとつである、WebWork というフレームワーク(実際はWebWork2)が元になっているからである。Struts の欠点を補うために、Struts チームは、WebWork チームと力を合わせ、Struts2 として生まれ変わったのです。

     

    機能

    詳細の内容については別途、必要に応じて説明していきますが、Struts1 から受け継がれてきている機能が洗練されていたり、最新の技術にも対応した構造となっている。Struts1 と互換性がない点、アプリケーションの作成手法が大きく異なる点から、なかなかユーザ側の移行は進んでいないようだが、インストール方法、Webアプリケーションの作成方法など解説しながら、Struts2 の良さを伝えていきたいと思う。

      • MVCフレームワーク
      • 洗練されたプラグイン機能
      • アクションクラスのPOJO(Plain Old Java Object)への対応
      • アノテーションによる設定ファイルの削減
      • DIコンテナ(Dependency Injection)による依存関係の分離

     

    このサイトでは今後、Struts2 のインストール方法、Struts2 によるWebアプリケーション作成方法、実用的なサンプルなど色々と紹介していきたいと思います。