org.w3c.dom.Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            Element rootElement = document.createElement("items");
            document.appendChild(rootElement);
            Element element = document.createElement("item");
            rootElement.appendChild(element);
            Text textContents = document.createTextNode("VALUE");
            element.appendChild(textContents);
            Attr attribute = document.createAttribute("id");
            attribute.setValue("ID");
            element.setAttributeNode(attribute);

・ファイアーウォール停止
systemctl disable firewalld.service

・tomcatインストール
    wget http://ftp.jaist.ac.jp/pub/apache/tomcat/tomcat-8/v8.5.6/bin/apache-tomcat-8.5.6.tar.gz

    useradd -s /sbin/nologin tomcat

    tar -xzvf ~/apache-tomcat-8.5.6.tar.gz

    mkdir /opt/apache-tomcat
    mv ~/apache-tomcat-8.5.6 /opt/apache-tomcat
    chown -R tomcat:tomcat /opt/apache-tomcatjavaインストール
    rpm -ihv /home/rootuser/ダウンロード/jdk-8u101-linux-x64.rpm 
    /usr/sbin/update-alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_101/bin/java 1000
    /usr/sbin/update-alternatives --set java /usr/java/jdk1.8.0_101/bin/java

vim  /etc/profile
JRE_HOME=/usr/java/default
CATALINA_HOME=/opt/apache-tomcat/apache-tomcat-8.5.6/
export JRE_HOME CATALINA_HOME

sudo -u tomcat /opt/apache-tomcat/apache-tomcat-8.5.6/bin/startup.sh
sudo -u tomcat /opt/apache-tomcat/apache-tomcat-8.5.6/bin/shutdown.sh

・ホストOSからゲストOS接続
    Virtualbox ファイルー環境設定
    ホストオンリーネットワーク追加
    192.168.56.1
    255.255.255.0

    192.168.56.100
    255.255.255.0
    192.168.56.101
    192.168.56.254

    Virtualbox 仮想マシンー設定
    ホストオンリーネットワーク追加

    起動しない場合、
    コントロール パネル\ネットワークとインターネット\ネットワーク接続
    のVirtualBox Host-Only Networkを有効か


    ・vim /etc/sysconfig/network-scripts/ifcfg-eth1
    CE=eth1
    TYPE=Ethernet
    ONBOOT=yes
    BOOTPROTO=static
    HWADDR=08:00:27:3A:EA:37
    NAME="System eth1"
    IPADDR=192.168.56.100
    NETMASK=255.255.255.0
    NETWORK=192.168.56.0


・war実行
    find / -name "catalina*"
    vim /etc/profile
    CATALINA_HOME=/opt/apache-tomcat/apache-tomcat-8.5.6/
    →    warプロジェクトコピー




・リモートデバッグ
    vim /opt/apache-tomcat/apache-tomcat-8.5.6/bin/catalina.sh
    →     JPDA_ADDRESS="192.168.56.100:8000"



    vim /opt/apache-tomcat/apache-tomcat-8.5.6/bin/startup.s
    →        exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"


    デバッグデバッグの構成をクリック
    開いたダイアログから「リモートJavaアプリケーション」を探しダブルクリックするとプロジェクト名のデバッグ構成が作成されます

・
        Connection conn =
        DriverManager.getConnection
        ("jdbc:oracle:thin:system/admin@localhost:1521:XE");
        
        Statement stmt = conn.createStatement();
        String sql = "insert into TABLE1 values ('001', 'てすと')";
        int num = stmt.executeUpdate(sql);

プロジェクトを右クリックー実行ー実行の構成
クラスパスタブ
外部jarの追加
C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib

    
セッションの再作成方法
            ((SessionMap<String, Object>)ActionContext.getContext().getSession()).invalidate();
            HttpSession newsession = ServletActionContext.getRequest().getSession(true);
            
            ServletActionContext.getRequest().getSession(true).invalidate();
      だとstruts2でセッションが消えてることに気づけない?

・web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>Struts2InterceptorExample</display-name>

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

<!--     <listener> -->
<!--         <listener-class>com.listeners.SessionListener</listener-class> -->
<!--     </listener> -->

    <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>
    
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>




・welcome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Welcome Page</title>
</head>
<body>
    <h3><s:actionerror/>
        Welcome<br/>
        <s:set var="data" value="#session.userInfo.userId" scope="request"/>
        <s:textfield label="ユーザーID" type="text" value="%{#request.data}" />
        <br/>
        <s:property value="#session.userInfo.password"/>
    </h3>
    <s:form method="post" action="logout">
        <s:submit value="ログアウト" />
    </s:form>
</body>
</html>


・login.jsp
<!DOCTYPE HTML>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Insert title here</title>
</head>
<body>
    <s:actionerror/>
    <s:form method="post" action="auth">
        <s:textfield label="ユーザーID" type="text" name="userInfo.userId" />
        <br/>
        <s:password label="パスワード" type="password" name="userInfo.password" />
        <s:submit value="ログイン" />
    </s:form>
</body>
</html>


・struts.xml
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.convention.result.path" value="/"></constant>
    
    <!-- 任意のメソッドの実行を許可しない -->
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    
    <package name="user" namespace="/" extends="struts-default">
        <interceptors>
            <interceptor name="session"
                class="com.interceptors.SessionInterceptor"></interceptor>
            <interceptor-stack name="sessionStack">
                <interceptor-ref name="session"></interceptor-ref>
                <interceptor-ref name="defaultStack"></interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <default-interceptor-ref name="sessionStack"></default-interceptor-ref>

        <global-results>
            <result name="login" type="redirect">/login.action</result>
<!--             <result name="login">/login.action</result> -->
        </global-results>

<!--         <action name="sessionAuth"> -->
<!--             <interceptor-ref name="sessionStack" /> -->
<!--             <result name="success">/success.jsp</result> -->
<!--             <result name="session">/sessionexpired.jsp</result> -->
<!--         </action> -->

        <action name="login">
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <result>/WEB-INF/pages/login.jsp</result>
        </action>
        
        <action name="logout" class="com.actions.LogoutAction">
            <interceptor-ref name="defaultStack"></interceptor-ref>
        </action>

        <action name="auth" class="com.actions.LoginAction">
            <interceptor-ref name="defaultStack"></interceptor-ref>
            <result name="success" type="redirect">/welcome.action</result>
            <result name="input">/WEB-INF/pages/login.jsp</result>
        </action>

<!--         <action name="welcome" class="com.actions.WelcomeAction"> -->
        <action name="welcome">
            <result name="success">/WEB-INF/pages/welcome.jsp</result>
        </action>
    </package>

</struts>


・SessionListener.java
package com.listeners;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class SessionListener implements HttpSessionBindingListener{
    private String aaa;
    
    @Override
    public void valueBound(HttpSessionBindingEvent arg0) {
        // TODO 自動生成されたメソッド・スタブ
        System.out.println("valueBound");
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent arg0) {
        // TODO 自動生成されたメソッド・スタブ
        System.out.println("valueUnBound");
    }

}


・SessionInterceptor.java
package com.interceptors;

import java.util.Map;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

@Results({
    @Result(name = Action.SUCCESS, location="/WEB-INF/pages/welcome.jsp"),
})
public class SessionInterceptor extends AbstractInterceptor {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        Map<String,Object> session = invocation.getInvocationContext().getSession();
    
        if(session.isEmpty()) {
            return Action.LOGIN;
        } else {
            return invocation.invoke();
        }
    }
}



・UserInfo.java
package com.beans;

public class UserInfo {
    
    private String userId;
    private String password;
    
    public UserInfo(){}
    public UserInfo(String userId, String password) {
        this.userId = userId;
        this.password = password;
    }
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userName) {
        this.userId = userName;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
    

}


・LogoutAction.java
package com.actions;

import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;

public class LogoutAction extends ActionSupport {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    public String execute() {
        HttpSession session = ServletActionContext.getRequest().getSession(true);
        session.invalidate();
        
        return Action.LOGIN;
    }
}



・LoginAction.java
package com.actions;

import javax.servlet.http.HttpSession;
import java.sql.*;

import org.apache.struts2.ServletActionContext;
import com.beans.UserInfo;
import com.opensymphony.xwork2.ActionSupport;


/**
 * ログイン処理を行うアクションメソッドです。
 *
 */
public class LoginAction extends ActionSupport {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    private UserInfo userInfo;
    
    /**
     * @return userInfo
     */
    public UserInfo getUserInfo() {
        return userInfo;
    }

    /**
     * @param userInfo セットする userInfo
     */
    public void setUserInfo(UserInfo userInfo) {
        this.userInfo = userInfo;
    }

//    public String execute() {
//        // ここに処理を記載するとvalidateの後で実行されてしまう。
//        return Action.SUCCESS;
//    }
    
    public void validate() {
        if ("admin".equals(userInfo.getUserId())) {
            ServletActionContext.getRequest().getSession(true).invalidate();
            HttpSession newsession = ServletActionContext.getRequest().getSession(true);
            newsession.setAttribute("userInfo", new UserInfo(userInfo.getUserId(), userInfo.getPassword()));
        } else {
            addActionError("userid または password が違います。");
        }
    }
}

ファサード・パターン
    façade
    複数の関連する機能を、外部から隠蔽するクラス(ファサード)を作成しておくことで、内部の変更を外部に影響をさせないようにするパターン 

・Visual Studio
    ショートカット  Ctrl + - にて戻る前のカーソル位置に移動する

・C#  独自(カスタム)TraceListenerの実装方法 
    web.configにリスナー情報を追加
    ・sharedlistener-system.diagnostics
     ┗<add name=""LogListener"" type=""namespace....class名, アセンブリ情報(プロジェクトのプロパティで見つかる)""/>
     <source name=""Log"" switchValue=""All"">
        <listeners>
          <add name=""LogListener""/>
          <remove name=""Default""/>
        </listeners>
      </source> 

・独自(カスタム)TraceListenerの実装方法2 
    ・tracelistenerを継承したファイルの作成(namespace…class名と名前を一致させること)
    public class DbTraceListener : TraceListener
    {
        public override void Write(string message)
        {
        }

        public override void WriteLine(string message)
        {
        }
    }
    ⇒この中でDB接続~INSERTまで実行する 

・独自(カスタム)TraceListenerの実装方法3
    呼び出し側でTrace.WriteLineとかで呼び出せば。。。うまくいかないはず。
    LogLevel,リスナーによる出しわけ処理は自前で定義する必要あり。 

・ASP.NET MVCでログが出力されない場合に
    気にすること IISの問題の場合⇒IIS Expressをいったん終了させる
    ログのFlushの問題の場合⇒autoFlush=""false""になってないか 

・Excel Grepツール ExcelGrepがいい。
    ExcelSniperで実際に対象がないのに検索結果一覧に出ることがあった。 

・楽観排他 ユーザーが操作する情報を、同時に他のユーザが操作する可能性は少ない、との仮定に基づく排他方式。
    更新したいリソースに対してロックせず、対象リソースの照会時と変更がないことをチェックする。
    複数ユーザーが同一にデータ更新を行う際にエラーを回避するために、アプリケーションにより整合性をチェックしてユーザーに状態を促すことにする。 

・悲観的排他 ユーザーが操作している情報を、他のユーザーも操作する可能性が十分にある、との仮定に基づく排他方式。
    更新しているリソースに対するロックは、対象リソースを照会のために取得した直後から更新が終わるまで維持される。
    バッチ処理では、データ更新が多く、データ整合性に関わる部分を保証する必要があるため、この方式を採用する。 

・反省 自分の伝え方がはっきり?していなかったために、無駄な工数発生
    I/Fは利用しなくてもいい? ⇒ いいよと回答 ⇒ 呼び方も変えていいかの確認が不十分だった。
    get~()で、引数に必要な情報がない場合でもきちんと値を返す方法
    必要な引数がある場所から、今回追加されている、引数がないメソッドがあるクラスに適当な名前でメソッド追加し、
    static メンバ変数に値を持たせる
    引数がないメソッドにて、メンバ変数を取得する

・javascriptのTips 標準コマンドを使用して実行
          if ('getSelection' in window &&
              'createRange' in document &&
              'execCommand' in document &&
              'queryCommandSupported' in document &&
              document.queryCommandSupported('cut')) {
                document.execCommand('cut');
            }
            setTimeout(popup.hide(), 200);

デフォルトのキー入力イベントを排除
    e.preventDefault(); 
    ・失敗 相手にファイルを渡すときのフォルダ構造
        A
    ┗新規ファイル━ファイルA.cs
    ┃      ┗ファイルを置く場所.txt
    ┗差分ファイル━ファイルB.cs.html
           ┗このファイルは直接開いて差分を適用してください 
・HTMLで書いたのと同様に値を表示する方法 valueDataDelimiter = ""&nbsp;"";
    MvcHtmlString.Create(breadcrumb);
    ⇒IHtmlString型。
 ただし、これだと>とかが正しく出ないため、
 WebUtility.HtmlEncode()で文字列を追加しておく 

・settimeout
    メソッド終了後に呼ばれる コンテキストメニューから親画面全選択
                $(contextMenuElement.beforeElement).focus();
                setTimeout(function () {
                    document.execCommand(command);
                }, 0);
    ⇒setTimeoutは最後に呼ぶようにする 
    ・webアプリケーションが動かない
        /エラー 方法1.asp.net のサービスが動いていない可能性
     ファイル名を指定して実行「services.msc」
     ASP.NET 状態サービスを立ち上げ
     (自動開始にしておく)

    方法2.起動時のパス誤り
     プロジェクトのプロパティ

     WEBタブ 開始動作 ページを指定する
     プロジェクトのURL 

・asp.net mvcIPv4アドレスを取得する方法                 string ipa = """";
                    System.Net.IPHostEntry iphEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
                foreach (var ipAddr in iphEntry.AddressList)
                {
                    if (ipAddr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        ipa = ipAddr.ToString();
                        break;
                    }
                } 

・SQL SQLインジェクション対策
    ⇒パラメータクエリ化。しないと任意の箇所でコメントアウト化できてしまう。
    http://npnl.hatenablog.jp/entry/20080412/1207965105

    DbParameter
    DbCommand

・ホスト名とは http://localhost:50563/
    最初のスラッシュまで。 

・  excel 図 圧縮 
    excelで画像のファイルサイズ圧縮が可能

・設計書の書き方 参照するファイル名の指定は「」をつける
    ・設定ファイル
     各設定値の意味、書き換え可能かについて記載

    ・階層で設計書を記載

・C# 改行
    Environment.NewLineだと、環境によって\r\n,\nを切り替えてくれる 

・順番 保証 リスト List<KeyPairValue<string, string>> 
    ⇒順番が保証されたDictionaryとして使用
    List<KeyPairValue<string, string>> 

・  PDF MIME/TYPE
    ロードバランサー
    エイリアス = 仮想ディレクトリ(IISFTPのときにやったやつ) =  

・色のグラデーション 取得
    パワーポイントに画像を貼り付け、図ー塗りつぶしースポイトで色を取得可能 

・リリース資料作成 変更したリソースファイルが全て列挙されているか⇒Winmerge
    変更したリソースファイルが全て列挙されているか⇒Winmerge
    変更したファイルが妥当な区分に記載されているか⇒目視 

・SQL 削除フラグがあるテーブル
    取得時。。。削除フラグがたっていないもの、という条件が必要
    挿入、更新時。。。フラグをどちらにするか判断する必要有。 

・JavaScript
    別画面表示時に考慮すること ・複数画面から同じヘルプ画面を呼ばれることはあるのか

・複数画面から呼ばれたときに画面ごとに別画面を出すのか
 ⇒別画面にしたくないときは、画面の名前を一意の名前にする

・別画面がPDF等のドキュメントの場合、ファイルはどこに置かれる想定か
 ドメインが違う場合、IISの仮想ディレクトリ等で対処する必要がある

・ドキュメントの場合、ファイルがなかった場合の対処
    ・一画面につき何枚まで画面を出すか 

・JavaScript 別画面表示時の実装1             
        var winWidth = 1252;
            var winHeight = 950;

            var winScrX = window.screenX + 20;
            var winScrY = window.screenY + 20;

            // ウィンドウオプションの設定
            // アドレスバー:非表示、ツールバー:非表示、メニューバー:非表示、ステータスバー:表示
            // スクロールバー:表示可能、リサイズ:変更可能
            var winFeatures = ""location=0, toolbar=0, menubar=0, status=1, scrollbars=1, resizable=1"" +
                              "", width="" + winWidth +
                              "", height="" + winHeight +
                              "", top="" + winScrX +
                              "", left="" + winScrY; 

・JavaScript 別画面表示時の実装2
        if (appPath === ""/"") {

                //値が「/」の場合、その値を削除する。
                appPath = appPath.substr(0)
            }

            // 別ウィンドウを開く
            var helpWindow = window.open(window.location.origin + appPath + ""/Content/blank.html?helpUrl="" + helpUrl, formId, winFeatures); 
・JavaScript    別画面表示時の実装3
    blank.html

フォーカス処理は遷移先の画面で実行しないと連打したときにうまく動かなくなる <html>
    <head>
        <title></title>
        <script>
            function changeHelp()
            {
                focus();
                location.href = location.search.split(""="")[1];
            }
        </script>
    </head>
    <body onload=""changeHelp()"">
    </body>
    </html> 

・ドキュメント作成 ドキュメント作成後、各項目に対してテスト項目を作成し、
    ドキュメント作成後、各項目に対してテスト項目を作成し、
    結果が正しいことを担保する。 

・addEventListenerとonの違い
    jqueryのonの違い イベントを追加登録(重複登録不可)するのがaddEventListener
    イベントを上書き登録するのがon
    イベントを追加登録(重複登録可能)がjqueryのon 

・jqueryのoffの注意点
    jqueryで登録したイベントに対する全てのイベントを削除してしまう

・モーダル
    モードレス クローズされるまでプログラム本体の操作が不可
    クローズされなくてもプログラム本体の操作が可能

    ちなみにダイアログは本体の処理を待つのみの為、
    モーダルダイアログ、モードレスダイアログがありえる

・コンテキストメニュー 連想配列
     actions: {
            ""cut"": {
                name: ""切り取り(T)"",
                keyCode: 84
            },
       },

        selectedElement: """", 

・即時実行したい処理を記載する
    (function () {
                $(document).on('blur', ""#test"", function () {
                alert(""!"" + document.getElementById(""test"").selectionStart);
            });
        }());

・cshtmlで画面ごとにjavascriptを任意で追記する方法 
    _Layout.cshtml
    @if (IsSectionDefined(""scripts""))
    {
        @RenderSection(""scripts"", required: false);
    }

    各cshtml
    @section scripts{
        <script src=""~/Scripts/test.js""></script>
    }

・      var groupDatas = from masterData in listData.DisplayRows()
                         group masterData by new
                     {
                         masterData.ID,
                         masterData.NM
                     } into masterDataGroup
                     select new
                     {
                         Id = masterDataGroup.Key.ID,
                         Name = masterDataGroup.Key.NM
                     };
・次案件で考慮する内容 セッション管理   
     セッション設計  
    クッキー設計  

    ルーティング   
    PRGパターン   
    多重クリック(2度押し防止)   
    CSS設計   
    キャメル、パスカル   
    Excel テーブル用マクロ   
    帳票ー署名   
     PDF  
     Excel  
     XML  
    マルチスレッド   
    Ajax-JSON

    ・  SVN   Redmine 連携 
        コミットコメント定義  
   
    仮想セッション   
     モーダル  
     モーダレス 親画面、子が面 
   
・jquery ui 擬似モーダル   
・window.openで何とかする   
⇒showmodalは非推奨の為禁止   
 javascript openwindow modalとかで検索  
  引数でオブジェクトで渡す 
   
 CSSを使った擬似モーダルダイアログ   
・  単体テストJunit   
    ログーlog4j   
ライブラリーLombok   
チェックーfindbugscheckstyle   
便利サイト   
 http://qiita.com/disc99/items/727b51dbe737602a5c91"

struts.devMode
開発モード(デバックモード)とは
『主に開発者向けの機能で、デバック情報(開発時のエラーなどの詳細情報)を表示させたり、
開発効率を上げるツールがあったりと開発時に大変役に立つモード。障害の切り分けや原因の特定もしやすい。
また、多くの情報が出るためシステム的にはそれなりに負荷がかかる。』


設定ファイル関係
http://mat5ukawa.hateblo.jp/entry/2016/04/10/125813


Struts2で例外を捕捉する
http://techmedia-think.hatenablog.com/entry/20080531/1212200933


struts2 login interceptor


http://www.journaldev.com/2210/struts-2-interceptor-example

f:id:oguri0220:20161004035447p:plain

sampleプロジェクト


・web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" id="struts_blank" version="2.4">
  <display-name>Struts Blank Convention</display-name>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </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>



・libの中身(\struts-2.5.2\lib)
aopalliance-1.0.jar
asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
commons-fileupload-1.3.2.jar
commons-io-2.4.jar
commons-lang3-3.4.jar
commons-logging-1.1.3.jar
freemarker-2.3.23.jar
javassist-3.20.0-GA.jar
log4j-api-2.5.jar
ognl-3.1.10.jar
spring-aop-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
struts2-config-browser-plugin-2.5.2.jar
struts2-convention-plugin-2.5.2.jar
struts2-core-2.5.2.jar


・hello.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title><s:text name="hello.message"/></title>
</head>

<body>
    <h2><s:property value="message"/></h2>

</body>
</html>


・struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>

  <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
  <constant name="struts.devMode" value="false"/>

</struts>


・Index.java
package local.sample.actions;

import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

@Results({
        @Result(name = Action.SUCCESS, location = "${redirectName}", type = "redirectAction")
})
public class Index extends ActionSupport {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    private String redirectName;

    public String execute() {
        redirectName = "hello";
        return Action.SUCCESS;
    }

    public String getRedirectName() {
        return redirectName;
    }

}


・HelloAction.java
package local.sample.actions;

import com.opensymphony.xwork2.ActionSupport;

/**
 * <code>Set welcome message.</code>
 */
public class HelloAction extends ActionSupport {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private static int count = 0;
    public String execute() throws Exception {
        setMessage(String.valueOf(count++));
        return SUCCESS;
    }

    /**
     * Provide default valuie for Message property.
     */
    public static final String MESSAGE = "hello.message";

    /**
     * Field for Message property.
     */
    private String message;

    /**
     * Return Message property.
     *
     * @return Message property
     */
    public String getMessage() {
        return message;
    }

    /**
     * Set Message property.
     *
     * @param message Text to display on HelloWorld page.
     */
    public void setMessage(String message) {
        this.message = message;
    }
}
http://localhost:8080/sample/config-browser/showConfig.action