Edited at

今さらstruts1.3.10を勉強したのでまとめてみた


はじめに

2019年9月の時点でstruts1でWebアプリケーションを新規開発をする事はほとんどないと思いますが、

それでもstruts1で構築され、現在でも動いているWebアプリケーションはまだまだ存在すると思います。

今後もプロジェクトで関わる可能性が大いにあるフレームワークですが、

すでに枯れた技術でもあり、ほかの技術に比べて、学習できる書籍やサイトがそこまで多くありません。

そこで今回、struts1についてこれまで学習したことをまとめてみました。

自分が新人で初めてstruts1を勉強した時に、

この資料があれば嬉しかったなというものを作ろう!という思いでこの記事を書きました。

今後、少しでも多くの方がこの記事を読んで、struts1の概要を理解してもらえたら幸いです。


本記事が向いている人


  • struts1についての知識がないが、一通り概要を理解したい方


ゴール


  • struts1の構成や特徴などの大枠を理解できる状態

  • この記事を足がかりに、struts1の学習がスムーズに進められる状態


strutsについて


どんなフレームワーク?

スクリーンショット 2019-08-27 19.13.45.png

strutsはApacheソフトウェア財団が提供している、MVCモデルを採用した、Webアプリケーションを作成するためのオープンソースのフレームワークです。

2000年にリリース後、struts1はJavaベースのWebアプリケーション開発の主流となりました。

その後、2008年12月に最終バージョンであるstruts1.3.10がリリースされ、2013年4月に正式にサポートが終了となりました。1

struts1が採用したMVCモデルに関しては、以下の記事を参考になります。

MVCモデルについて


strutsの特徴

strutsの主な特徴は以下が挙げられます。


1.遷移先などの処理を設定ファイル(struts-config.xml)で管理

ここが一番重要です!!

strutsでは遷移先などの処理に関しては設定ファイル(struts-config.xml)で管理しています。

そのため、遷移先や実行するビジネスロジックを修正する際は設定ファイルのみを修正すれば良く、Viewであるjspファイルを変更は不要です。

struts-config.xmlの内容が理解できれば、どの画面に遷移するか、どの処理が実行されるがとても簡単に理解できるようになります。

jspファイルと設定ファイル(struts-config.xml)の関連について、ざっくりとしたイメージを以下に記載します。

jspファイル

<form>タグのアクション属性にAction名を定義

設定ファイル(struts-config.xml)

リクエスト時に<action>エレメントのpath属性と一致するアクションを実行

スクリーンショット 2019-08-27 23.25.43.png


2.validationの提供

strutsでは入力データの必須チェックや文字数チェックの処理などのvalidationの機能が提供されており、入力チェック用のプログラムを実装する手間が省けます。

以下のログイン画面の入力チェックも、strutsが提供しているvalidation.xmlでパラメータの検証ルールを定義し、

メッセージ・リソースファイルを用いてエラーの際に表示するメッセージを設定する事で実装が可能となります。

9月-10-2019 01-10-25.gif


3.タグライブラリの提供

Strutsは独自のタグライブラリが用意されており、Javaコードの代わりに専用タグライブラリを使用することで、

画面(JSP)の可読性の低下を防止や記述レベルを統一が可能となります。


4.その他


  • <global-exceptions>タグを用いた例外処理

  • Commons-Loggingを用いたログ出力機能


  • 国際化対応 など


strutsの構成・処理の流れ

strutsの構成・処理の流れは下図となります。

スクリーンショット 2019-08-18 12.35.30.png「Struts逆引き大全333の極意」を元に作成


処理の流れ

処理の流れは以下となります。


  1. クライアントがアクション名を含むリクエストを送る

  2. アクションサーブレットがアクション名を含むリクエストを受け取る

  3. アクションサーブレットは受け取ったアクション名を設定ファイルと照合し、アクションフォームやアクションクラスを特定する

  4. アクションフォームのメソッドを実行し、 必要に応じて処理結果を受け取る

  5. アクションクラスのメソッドを実行し、遷移先ページについての情報を受け取る

  6. アクションサーブレットは アクションクラスの処理結果をもとにjspへ画面を遷移する

  7. jspが実行されレスポンスを返す

上記の流れをざっくり説明すると

クライアントからのリクエストをもとに、アクションサーブレットが実行するアクションフォームやアクションクラスを特定し、実行結果をもとに遷移先を決定する。

といったところでしょうか


構成

構成に関しては図に記載した


  • アクションサーブレット

  • アクションフォーム

  • アクションクラス

  • JSP

  • struts設定ファイル(struts-config.xml)

の5つと


  • Web.xml

で主に構成されています。


1.アクションサーブレット

全てのリクエストを受け付け、リクエストに対応したアクションフォーム、アクションクラス、jspページを起動します。アクションサーブレットはMVC構成のコントローラの役割を持つサーブレットです。


2.アクションフォーム

フォームから入力されたリクエストデータを保持するBeanです。

実装する際は以下を定義する必要があります。


  • org.apache.struts.action.ActionFormを継承

  • プロパティおよび各プロパティのgetter/setterメソッド


ActionForm.java

import org.apache.struts.action.ActionForm;

public class SampleActionForm extends ActionForm {
private String hoge; //プロパティ

public SampleActionForm(String hoge) {this.hoge = hoge;}

public void setHoge(String hoge) {this.hoge = hoge;} //setter
public String getHoge() {return hoge;} //getter

}


※validationの設定に関して、後日追記


3.アクションクラス

アクションフォームにリクエストが設定された後に起動されます。

アプリケーションで行うビジネスロジックはこのアクションクラスに記述します。

アクションクラスの構成の特徴は以下となります。


  • org.apache.struts.action.Actionを継承

  • executeメソッドをオーバーライドして、ビジネスロジックを記述

  • executeメソッドの戻り値にActionMappingオブジェクトのfindForwardメソッドを用いて、どのjspに遷移するか指定

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

public final class SampleAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {

       //ビジネスロジックの記述

//設定ファイル(struts-config.xml)のforwardタグのname属性に記載されているjspのパスに遷移
return mapping.findForward("success");
}
}


4.JSP

MVC構成のビューの役割を持っている機能であり、アクションクラスの処理後に起動され、ブラウザの表示内容を返却します。

また、JSPはstrutsが提供しているタグライブラリが存在し、Javaコードの代わりに専用のタグライブラリを使用することによって、可読性を高める事が可能です。


タグライブラリの使用例 - htmlタグライブラリ

参考として、以下のログイン画面を、strutsのタグライブラリを使用する場合しない場合でどう記述が変わるのか確認します。

スクリーンショット 2019-08-27 11.44.41.png


タブライブラリ未利用

strutsのタグライブラリを利用しない場合は以下のような記述になります。(一部抜粋)


jsp

<h1>ログイン</h1>

<form action="/アプリケーション名/WebContentからのパス" method="post" >
<input type="text" name="id" class="id" placeholder="ID" autofocus>
<br>
<input type="password" name="password" class="pass" placeholder="PASSWORD">
<br>
<input type="submit" class="login" value="ログイン">
</form>

<input>タグを用いてID、パスワード、送信ボタンを作成しています。


HTMLタグライブラリ利用

次にstrutsのHTMLタグライブラリを利用した場合は以下のような記述になります。(一部抜粋)


struts

<h1>ログイン</h1>

<html:form action="/xxx" focus="id">
<html:text styleClass="id" property="id" value = ""/>
<br>
<html:password styleClass="pass" property="pass" redisplay="false"/>
<br>
<html:submit styleClass="login" property="submit" value="ログイン"/>
</html:form>

このように、<input>タグではなく、strutsで提供されているHTMLタグライブラリを用いても、ほぼ同様の記載が可能となります。

今回の場合は、<input>タグで生成された部品が、<html:text><html:password><html:submit>で記載されている事がわかります。

ただし、strutsのHTMLタグライブラリはHTML5の新規タグには対応していません。

一例ですが、上記に挙げたように、HTML5にあるplaceholder属性をstrutsのHTMLタグライブラリで利用する事ができません。

strutsのHTMLタグライブラリを利用して、HTML5と同様の属性を出力したい場合は、jQueryで以下のコードを追加する必要があります。


jQuery

$(function(){

$(".id").attr('placeholder', 'ID');
$(".pass").attr('placeholder', 'PASSWORD');
});

参考(https://log4jk.hatenadiary.org/entry/20130112/p1


タグライブラリの使用例 - logicタグライブラリ

strutsではjspでif文やfor文などに該当する処理をlogicタグライブラリを用いて記述する事ができます。

※後日追記


タグライブラリの種類

strutsで提供されている主なタグライブラリは以下となります。

タグライブラリ名
概要

Beanタグライブラリ
Beanに関連する機能を提供

HTMLタグライブラリ
HTMLのフォーム要素などを表示する機能を提供

Logicタグライブラリ
条件分岐や繰り返し処理などの論理的な機能を提供

Nestedタグライブラリ
ネストしたプロパティにアクセスする機能を提供し、
複数のプロパティにアクセスする際により簡潔に記載が可能となる


代表的なBeanタグライブラリ

タグ名
概要

<bean:define>
変数を定義する

<bean:write>
Beanのプロパティを取得する

<bean:cookie>
クッキーを取得する


代表的なHTMLタグライブラリ

タグ名
概要

<html:button>
<input type="button">タグを生成する

<html:checkbox>
<input type="checkbox">タグを生成する

<html:form>
<form>タグを生成する

<html:hidden>
<input type="hidden">タグを生成する

<html:image>
<input type="image">タグを生成する

<html:link>
<a>タグを生成する

<html:text>
<input type="text">タグを生成する

<html:password>
<input type="password">タグを生成する

<html:submit>
<input type="submit">タグを生成する


代表的なLogicタグライブラリ

タグ名
概要

<logic:iterate>
繰り返し処理を行う

<logic:empty>
指定された値が、空をどうかを判定する

<logic:notEmpty>
指定された値が、空でないかを判定する

<logic:equal>
指定された値と、等しいかを判定する

<logic:notEquals>
指定された値と、等しくないかを判定する

カスタムタグの詳細な説明に関しては、以下のサイトが参考になります。

参考(http://struts.wasureppoi.com/taglib/00_taglib.html


5.struts設定ファイル(struts-config.xml)

リクエストと各コンポーネントの関連付けを行う定義ファイルです。

アクションサーブレットはこの設定ファイルを参照し、リクエストのアクションに一致するアクションパスから、実行するビジネスロジックや、アクションフォーム、バリデーションの有無や遷移先を指定します。


使用例

一例として、以下のjspファイルからリクエストを送った際に、

ビジネスロジックや遷移先がどう決定するかを確認します。


jspファイル

<!-- <form>タグのアクション属性に実行するアクションを指定 -->

<form action="/sample" method="post"></form>

上記jspのaction="/sample"はリクエストの際に

struts-config.xmlの<action>エレメントに記載された/sampleを参照して

という意味になります。

そしたら次は、struts-config.xmlのpath="/sample"と記述されている<action>エレメントに定義されている処理を実行します。


struts-config.xml(一部抜粋)

<form-beans>

<form-bean
name="sampleForm"
type="package.SampleActionForm"/>
</form-beans>
<action-mappings>
<action
path="/sample"
type="package.SampleAction"
name="sampleForm"
scope="session"
validate="true"
input="/index.jsp">
<forward name="success" path="/WEB-INF/jsp/sample.jsp"/>
</action>
</action-mappings>

アクションが"/sample"だった場合に実施される処理が以下となります。

①:SampleActionというアクションクラスを実行

②:SampleActionFormというアクションフォームを利用

③:②のアクションフォームを保持するスコープがsessionであることを定義

④:入力チェックを実施することを定義

⑤:④の入力チェックでエラーだった場合にindex.jspに遷移することを定義

⑥:①のアクションクラスの戻り値が"success"の場合に"/WEB-INF/jsp/sample.jsp"に遷移することを定義


エレメントの概要

設定ファイルに記述されている、各エレメントの概要は以下となります。


<action>エレメントの主な属性

属性
説明

path
jspのアクションとStrutsの設定ファイルを結びつける名称

type
アクションに対応するアクションクラスのクラス名(完全修飾名)

name
アクションに対応するアクションフォーム名(アクションフォーム名は<form-beans>エレメントに記載)

scope
アクションフォームを格納するスコープを指定(requsetかsession)

validate
バリデーションを行う場合はtrueを指定。行わない場合はfalseを指定

input
入力エラー次の戻り値を指定


<form-beans>エレメントの主な属性

属性
説明

name
アクションフォームの名前を指定
<action>エレメントのname属性のアクションフォーム名と一致

type
アクションフォーム名のクラス名(完全修飾名)


<forward>エレメントの主な属性

属性
説明

name
アクションクラスのexecuteメソッドの戻り値と結びつける名称

forward
遷移先のjspファイル名

<action><form-beans><forward>以外のエレメントの概要は以下となります。

エレメント
概要

<data-sources>
データソースの定義

<global-exceptions>
共通の例外処理設定

<global-forwards>
共通のアクションフォワード設定

<controller>
コントローラの定義

<message-resources>
メッセージリソースの定義

<plug-in>
プラグインの定義


6.web.xml

ざっくりとした説明は以下


  • ServletコンテナがWebアプリケーションの動作を 制御するための設定ファイル

  • ActionServletに関する定義を記述する

  • /WEB-INF直下に配置する


リクエストとアクションサーブレットの関係

リクエストから、実行するアクションを指定するまでの流れを追って、web.xmlの役割をみていきたいと思います。


jspファイル(再掲)

<!-- <form>タグのアクション属性に実行するアクションを指定 -->

<form action="/sample" method="post"></form>

上記のように、jspファイルにアクションを記述し、クライアントがブラウザからリクエストを要求すると、URLに拡張子「.do」がつきます。

↓ リクエスト時のURL

スクリーンショット 2019-08-17 18.57.33.png

そして、web.xmlで定義されている設定ファイルに基づいて、実行するアクションが決定します。

strutsのweb.xmlは通常、以下のように定義されています。


web.xml

<servlet>

<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value> <!-- (2) -->
</init-param>
<!-- 中略 -->
</servlet>
<!-- 中略 -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern> <!-- (1) -->
</servlet-mapping>

(1)web.xmlに記載されているURLパターンから、拡張子「.do」のリクエストがActionServlet

(org.apache.struts.action.ActionServlet)
に渡されるということがわかります。

(2)<param-value>にActionServletの制御を記述した設定ファイルのパスが記載されています。

今回の場合、struts-config.xmlがリクエストとアクションの関連付けを行なっており、

リクエストに指定されたパスhttp://ホスト名/コンテキスト名/xxx.doxxxstruts-config.xml<action>エレメントのpath属性が一致したアクションを実行しています。

(2)の説明から分かるように、設定ファイルの宣言は<param-value>で行なっているので、

設定ファイルを追加したい場合は、<param-value>内に、ファイル名を追加で記述すれば良いです。


web.xml(設定ファイルを追加する場合)

  <init-param>

<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml,
/WEB-INF/struts-config-xxx.xml,
/WEB-INF/struts-config-xxx.xml,
/WEB-INF/struts-config-xxx.xml,
.
.
.
</param-value>


Struts1の環境構築

※後日追記(以下のサイトが参考になります)

Struts 1.3インストールガイド

http://struts.nomaki.jp/struts1.3/install/document.html

Struts1.3.10でWebアプリケーション作成

https://liliel.hateblo.jp/entry/2018/09/05/145011


ログイン画面作成して動作を確認

※ソースコードの解説については後日追記


実装する機能


ログイン画面

・ユーザIDとパスワードを入力して、ログインを実施

・パスワードは全ユーザ共通で「1111」

・入力チェックを行い、問題があればログイン画面にエラーメッセージを表示

スクリーンショット 2019-09-12 18.58.08.png


実行結果画面

・「ログインに成功しました」というメッセージと、ログインしたユーザIDを表示

スクリーンショット 2019-09-12 18.58.42.png


ログアウト画面

・セッションを破棄して、ログアウトしましたのメッセージを表示

スクリーンショット 2019-09-12 18.59.02.png


実装したログイン画面

実装したログイン画面は以下となります。分かりづらいですが、2つ目がstrutsを用いて作成したログイン画面です。(リクエスト時のURLの拡張子に「.do」がついています。)


ディレクトリ構成

struts

├── WebContent
│   ├── META-INF
│   ├── WEB-INF
│   │   ├── classes
│   │   │   └── MessageResources.properties
│   │   ├── jsp
│   │   │   ├── loginResult.jsp
│   │   │   └── logout.jsp
│   │   ├── src
│   │   │   └── java
│   │   │   └── MessageResources.properties
│   │   ├── struts-config.xml
│   │   ├── validation.xml
│   │   └── web.xml
│   ├── css
│   │   └── style.css
│   └── index.jsp 
└── src
└── model
├── LoginAction.java
├── LogoutAction.java
└── UserActionForm.java


アクションクラス


LoginAction.java

package model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.*;

public final class LoginAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {

HttpSession session = request.getSession();
ActionMessages errors = new ActionMessages();

UserActionForm UserActionForm= (UserActionForm)form;
String id = UserActionForm.getId();
String pass = UserActionForm.getPass();

if(!(pass.equals("1111"))) {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("errors.login"));
saveErrors(request, errors);
return (mapping.findForward("fail"));
} else {
session.setAttribute("id", id);
return mapping.findForward("success");
}
}
}



LogoutAction.java

package model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.*;

public final class LogoutAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {

HttpSession session = request.getSession();
session.invalidate();

return mapping.findForward("success");

}
}



アクションフォーム


UserActionForm

package model;

import org.apache.struts.action.*;
import org.apache.struts.validator.*;

public class UserActionForm extends ValidatorForm {

private String id; // ユーザー名
private String pass; // パスワード

public UserActionForm() {}

public UserActionForm(String id, String pass) {
this.id = id;
this.pass = pass;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}



jsp


index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding=
"UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE html>
<html>
<head>
<title>ログイン</title>
<link rel="stylesheet" type="text/css" href="<html:rewrite page="/css/style.css"/>" >
</head>
<body>
<html:errors />
<div class="main-div">
<h1>ログイン</h1>
<html:form action="/loginResult" focus="id">
<html:text styleClass="id" property="id" value = ""/>
<br>
<html:password styleClass="pass" property="pass" redisplay="false"/>
<br>
<html:submit styleClass="login" property="submit" value="ログイン"/>
</html:form>
</div>
</body>
</html>


loginResult.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding=
"UTF-8" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<logic:notPresent name="id" scope="session">
<logic:redirect forward="fail"/>
</logic:notPresent>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>メイン</title>
<link rel="stylesheet" type="text/css" href="<html:rewrite page="/css/style.css"/>" >
</head>
<body>
<div class="main-div">
<h1>ログイン結果</h1>
<p>ログインに成功しました</p>
<p>ユーザID:<bean:write name="id" scope="session"/></p>
<html:link action="/logout">ログアウト</html:link>
</div>
</body>
</html>



logout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding=
"UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ログアウト</title>
<link rel="stylesheet" type="text/css" href="<html:rewrite page="/css/style.css"/>" >
</head>
<body>
<div class="main-div">
<h1>ログアウト</h1>
<p>ログアウトしました</p>
<a href="/struts/">トップへ</a>
</div>
</body>
</html>


設定ファイル(strtus-config.xml)


struts-config.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">

<struts-config>
<form-beans>
<form-bean
name="UserActionForm"
type="model.UserActionForm"/>
</form-beans>
<global-forwards>
<forward name="fail" path="/index.jsp"/>
</global-forwards>
<action-mappings>
<action
path="/Welcome"
forward="/pages/Welcome.jsp"/>
<action
path="/loginResult"
type="model.LoginAction"
name="UserActionForm"
scope="session"
validate="true"
input="/index.jsp">
<forward name="success" path="/WEB-INF/jsp/loginResult.jsp"/>
<forward name="fail" path="/index.jsp"/>
</action>
<action
path="/logout"
type="model.LogoutAction">
<forward name="success" path="/WEB-INF/jsp/logout.jsp"/>
</action>
</action-mappings>
<message-resources parameter="resources.application"/>
<message-resources parameter="MessageResources"/>
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/org/apache/struts/validator/validator-rules.xml,
/WEB-INF/validation.xml"
/>
</plug-in>
</struts-config>


Validation.xml


validation.xml

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!-- 中略 -->
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd">

<form-validation>
<!-- 中略 -->
<formset>
<form name="UserActionForm">
<field
property="id"
depends="required">
<arg key="field.id" />
</field>
<field
property="pass"
depends="required">
<arg key="field.pass" />
</field>
</form>
</formset>
<formset language="fr">
<constant>
<constant-name>postalCode</constant-name>
<constant-value>^[0-9a-zA-Z]*$</constant-value>
</constant>
<form name="logonForm">
<field
property="username"
depends="required">
<arg key="logonForm.username"/>
</field>
<field
property="password"
depends="required,mask">
<arg key="logonForm.password"/>
<var>
<var-name>mask</var-name>
<var-value>^[0-9a-zA-Z]*$</var-value>
</var>
</field>
</form>
</formset>
</form-validation>


メッセージ・リソースファイル


MessageResources_jp.properties

# -- standard errors --

errors.header=<div class="err-font" >
errors.prefix=
errors.suffix=<br />
errors.footer=</div >
# -- validator --
# --中略 --
errors.range={0} is not in the range {1} through {2}.
errors.required={0} を入力してください。
# --中略 --
field.id=ログインID
field.pass=パスワード
errors.login=パスワードに誤りがあります


特に勉強になった書籍、サイト

参考文献と重複しますが、特に勉強になった書籍とサイトを記載します。

この記事を見た後にもっと詳しく勉強したい方は、以下の書籍とWebサイトを参考にしてください。


書籍

Struts逆引き大全333の極意

https://www.amazon.co.jp/Struts%E9%80%86%E5%BC%95%E3%81%8D%E5%A4%A7%E5%85%A8333%E3%81%AE%E6%A5%B5%E6%84%8F-%E5%9D%82%E7%94%B0-%E5%81%A5%E4%BA%8C/dp/4798007358


Webサイト

忘れっぽいエンジニアのJakarta Struts リファレンス

http://struts.wasureppoi.com

Webアプリ開発エンジニアのための技術情報サイト[テックスコア]

https://www.techscore.com/tech/Java/ApacheJakarta/Struts/index/

Struts1日入門

http://www.knowledge-ex.jp/opendoc/Struts_1day_seminar.pdf


参考文献


書籍 

Struts逆引き大全333の極意

https://www.amazon.co.jp/Struts%E9%80%86%E5%BC%95%E3%81%8D%E5%A4%A7%E5%85%A8333%E3%81%AE%E6%A5%B5%E6%84%8F-%E5%9D%82%E7%94%B0-%E5%81%A5%E4%BA%8C/dp/4798007358

スッキリわかるサーブレット&JSP入門

https://book.impress.co.jp/books/1112101008


Webサイト

忘れっぽいエンジニアのJakarta Struts リファレンス

http://struts.wasureppoi.com

Webアプリ開発エンジニアのための技術情報サイト[テックスコア]

https://www.techscore.com/tech/Java/ApacheJakarta/Struts/index/

Struts1日入門

http://www.knowledge-ex.jp/opendoc/Struts_1day_seminar.pdf

株式会社アークシステム Strutsをはじめとするオープンソースプロダクト情報

https://www.arksystems.co.jp/closeupit/struts/

@IT Strutsを使うWebアプリケーション構築術

https://www.atmarkit.co.jp/ait/series/2515/

struts - 機能リファレンス

http://pgbox.grush.jp/ref/java/struts/refs/

ぷ~ろぐ サーブレット・JSPメモ016:Struts:validator-rules.xml

http://into.cocolog-nifty.com/pulog/2012/03/jsp016strutsval.html

SEさんの外部記憶装置 まだまだ苦戦

https://ameblo.jp/system-eng1neer/entry-10385236995.html

でぃべろっぱーず・さいど struts のタグのstyleClass

http://dev.chrisryu.com/2007/07/styleclass_attribute_of_struts_imgtag.html

世界」旅と子育てとガジェットを愛するエンジニアリングマネージャーのブログ Struts1.3.5でValidatorを使う

https://daipresents.com/2008/struts135validator/

雑廉堂の雑記帳 いまさらながらStruts – ActionMessages

https://www.rough-and-cheap.jp/java/struts_meno_actionmessages/

ウィリアムのいたずらの開発?日記 TomcatからStrutsの流れを確認する 

https://blog.goo.ne.jp/xmldtp/e/8da26250101a830f58e0896d0c767333

IT技術三昧 java+struts開発でメッセージ・リソースファイルで日本語を利用(native2asciiコマンド)

https://www.zanmai.net/blog/data/83.html

log4jk Strutsのカスタムタグで任意の属性を出力したい

https://log4jk.hatenadiary.org/entry/20130112/p1

Struts 1.3インストールガイド

http://struts.nomaki.jp/struts1.3/install/document.html

liliel_OvO’s blog Struts1.3.10でWebアプリケーション作成

https://liliel.hateblo.jp/entry/2018/09/05/145011