2. یک مثال اول
اکثر مثالهای ما به لایه وب محدود خواهند بود و با استفاده از Struts 2 پیادهسازی میشوند:
![]() |
پس از پوشش مبانی، به مثالی پیچیدهتر با معماری چندلایه خواهیم پرداخت.
2.1. ایجاد مثال
ما در حال ساخت اولین برنامهمان هستیم.
![]() |
- در [1]، یک پروژه جدید ایجاد میکنیم
- در [2]، نوع Java Web / Web Application را انتخاب میکنیم
- در [3]، به پروژه نام میدهیم
- در [4]، مکان پروژه را مشخص میکنیم.
- در [5]، پروژه جدید را بهعنوان پروژه اصلی تنظیم کنید.
![]() |
- در [6]، سرور Tomcat را انتخاب کنید. وقتی NetBeans 7.01 نصب شد، دو سرور نصب شدند: Apache Tomcat و GlassFish 3.1.
- در [7]، مشخص میکنیم که با فریمورک Struts 2 کار خواهیم کرد. این امکان با نصب پلاگین Struts 2 فراهم میشود. بدون این پلاگین، فریمورک Struts 2 به ما ارائه نمیشود.
- در [8]، از ما خواسته میشود تا پروژهٔ مثالی را که قصد مطالعهٔ آن را داریم، ایجاد کنیم.
- در [9]، میتوانیم بررسی کنیم که کدام کتابخانههای Struts 2 استفاده خواهند شد.
![]() |
- در [10]، پروژهٔ تولیدشده. بعداً به این موضوع باز خواهیم گشت.
- در [11]، کتابخانههای پروژه. اینها توسط پلاگین Struts 2 یکپارچه شدهاند. اگر این پلاگین را ندارید، میتوانید این کتابخانهها را در پوشه [lib] توزیع دانلود شده Struts 2 پیدا کنید. سپس باید مراحل ۱۲ و ۱۳ را دنبال کنید.
2.2. پروژه تولیدشده در سیستم فایل
![]() |
- به [1]، زبانه [Projects] نمای «توسعهدهنده» پروژه را نمایش میدهد
- در [2]، زبانه [Files] پوشه پروژه را در سیستم فایل نمایش میدهد
- در [2A]، شاخه [Web Pages] در [2] توسط پوشه [web] [2B] نشان داده میشود
- در [3A]، شاخه [Source Packages] در [2] با پوشه [java] [3B] نشان داده میشود
2.3. فایل پیکربندی [META-INF/context.xml]
![]() |
این فایل به شرح زیر است:
<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/exemple-01"/>
خط ۲ نشان میدهد که زمینهٔ برنامهٔ وب /exemple-01 است. تمام فایلهای URL از نوع [http://machine:port/exemple-01/...] توسط این برنامه پردازش خواهند شد. این زمینه را میتوان در ویژگیهای پروژه [2] یافت: روی پروژه کلیک راست کنید / Properties / Run.
2.4. فایل پیکربندی [WEB-INF/web.xml]
![]() |
هر برنامه وب با فایل [web.xml] در پوشه [WEB-INF] برنامه پیکربندی میشود. فایلی که تولید شده به شرح زیر است:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<URL-pattern>/*</URL-pattern>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>example/HelloWorld.JSP</welcome-file>
</welcome-file-list>
</web-app>
- خطوط ۳–۶ یک فیلتر را تعریف میکنند که توسط کلاس Struts 2 با نام [org.apache.struts2.dispatcher.FilterDispatcher] پیادهسازی شده است. این کلاس است که بهعنوان کنترلکننده C برای مدل MVC عمل خواهد کرد.
- خطوط ۷–۱۰: یک پیوند بین مدلی از نوع URL و فیلتری که باید نمونههای URL منطبق با این مدل را پردازش کند، تعریف میکنند. در اینجا مشخص شده است که هر URL (الگو /*) باید توسط فیلتری به نام struts2 پردازش شود. این همان فیلتری است که در خطوط ۳ تا ۶ تعریف شده است. بنابراین، تمام درخواستهای URL از طریق کنترلکننده Struts 2 عبور خواهند کرد.
- خطوط ۱۱–۱۵: مدتزمان یک جلسه کاربری را تعریف میکنند، در این مورد ۳۰ دقیقه. در طول درخواستهای متوالی، کاربر با یک توکن جلسه که در اولین درخواست به او اختصاص داده میشود، ردیابی میشود؛ توکنی که او سپس در هر درخواست جدید بهطور سیستماتیک ارسال میکند. این امر به سرور وب امکان میدهد کاربر را شناسایی کرده و «حافظهای» برای او مدیریت کند که به آن جلسه (session) گفته میشود. اگر بیش از ۳۰ دقیقه بین دو درخواست فاصله بیفتد، یک توکن جلسه جدید برای کاربر ایجاد میشود و در نتیجه او «حافظه» خود را از دست داده و از نو شروع میکند.
- خطوط ۱۶–۱۸: فایلی را که باید هنگام دسترسی کاربر به برنامه وب بدون درخواست هیچ سندی نمایش داده شود، تعریف میکند. بنابراین، هنگامی که URL درخواستی برابر با [http://machine:port/exemple-01] باشد، URL ارائهشده برابر با [http://machine:port/exemple-01/example/HelloWord.JSP] خواهد بود.
2.5. فایل پیکربندی [struts.xml]
![]() |
فایل [struts.xml] فایل پیکربندی Struts 2 است. این فایل میتواند در هر نقطهای از دایرکتوری ClassPath پروژه قرار گیرد. در پروژه NetBeans بالا، دایرکتوری ClassPath پروژه از دو شاخه تشکیل شده است:
- بستههای منبع
- کتابخانهها
هر پوشه یا کتابخانهای که در این دو شاخه قرار داشته باشد، بخشی از ClassPath پروژه است. قرار دادن [struts.xml] در <default package> یک رویه رایج است. در اینجا، محتویات آن به شرح زیر است:
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="example.xml"/>
<!--پیکربندی برای بسته پیشفرض. -->
<package name="default" extends="struts-default">
</package>
</struts>
- خطوط ۵ و ۱۰: تگ ریشهٔ سند تگ <struts> است
- خط ۶: فایل [example.xml] در اینجا وارد میشود. بنابراین پیکربندی خاص خود را به همراه دارد. به این موضوع باز خواهیم گشت.
- خطوط ۸–۹: در اینجا یک پکیج با نام «default» تعریف میشود. یک پکیج به شما امکان میدهد گروهی از اکشنهای Struts 2 را که URL یکسان دارند پیکربندی کنید. برای مثال، [/chemin/Action1] و [/chemin/Action2]. بنابراین میتوانیم یک پکیج برای این اکشنها تعریف کنیم:
<package name="employes" namespace="/employes" extends="struts-default">
... configuration
</package>
پکیج بالا با نام «employees» نامگذاری شده و اقدامات URL و /employes/Action را پیکربندی میکند. این پکیج میتواند با استفاده از کلمه کلیدی «extends» از پکیج دیگری ارث بری کند. در مثال بالا، بسته employes از بسته struts-default ارث میبرد. این بسته در فایل [struts-default.xml] در داخل کتابخانه struts2-core.jar قرار دارد:
![]() |
پکیج «struts-default» که در فایل [struts-default.xml] تعریف شده است، عناصر مختلفی را پیکربندی میکند، از جمله فهرستی از interceptorها که هنگام فراخوانی یک action اجرا میشوند. بیایید به ساختار MVC یک برنامه Struts 2 بازگردیم:
![]() |
برای پردازش یک URL از نوع [http://machine:port/.../Action]، کنترلکننده [FilterDispatcher]، کلاسی را که اقدام درخواستی را پیادهسازی میکند، نمونهسازی کرده و یکی از متدهای آن را اجرا خواهد کرد — که به طور پیشفرض، متدی به نام execute است. فراخوانی این متد، execute، از میان مجموعهای از interceptors عبور خواهد کرد:
![]() |
اینترسپتورها و اکشن همگی یک درخواست را پردازش میکنند. فهرست اینترسپتورهای تعریفشده در پکیج struts-default در اکثر موارد کافی است. بنابراین، پکیجهای Struts ما همیشه از پکیج struts-default ارثبری خواهند کرد. برای اطلاع از عملکرد اینترسپتورهای مختلف، به فصل ۴ از [ref2] مراجعه کنید.
بیایید به فایل پیکربندی struts.xml بازگردیم:
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="example.xml"/>
<!--پیکربندی برای بسته پیشفرض. -->
<package name="default" extends="struts-default">
</package>
</struts>
- خط ۸: پکیج با نام default یک نقش خاص دارد. این پکیج اقداماتی را مدیریت میکند که در سایر پکیجها پیکربندی نشدهاند. در اینجا، در خطوط ۸–۹، هیچ پیکربندیای برای پکیج default انجام نشده است. بنابراین میتوانیم تعریف این پکیج را حذف کنیم.
اکنون بیایید به فایل [example.xml] که در خط ۶ فایل [struts.xml] گنجانده شده است، نگاهی بیندازیم:
<?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>
<package name="example" namespace="/example" extends="struts-default">
<action name="HelloWorld" class="example.HelloWorld">
<result>/example/HelloWorld.JSP</result>
</action>
</package>
</struts>
- خط ۸: یک بسته به نام example را تعریف میکند که بسته struts-default را گسترش میدهد. این بسته فایلهای URL از نوع /example/Action (فضای نام /example) را مدیریت میکند.
- سطور ۹–۱۱: یک اکشن به نام HelloWorld (ویژگی name) تعریف کنید که بنابراین با URL و /example/Helloworld مطابقت دارد. این اقدام توسط یک نمونه از کلاس example.HelloWorld (ویژگی class) پردازش میشود.
- کنترلکننده [FilterDispatcher] باعث اجرای متد execute این کلاس خواهد شد.
- این متد یک رشته را که به عنوان کلید ناوبری شناخته میشود، بازمیگرداند.
- کلیدهای ناوبری مختلف باید با استفاده از تگهای <result name="key"/> (خط ۱۰) تعریف شوند. اگر ویژگی name وجود نداشته باشد، کلید success بهصورت پیشفرض استفاده میشود. در مثال بالا نیز همینطور است. بنابراین، متد execute از کلاس example.HelloWorld باید کلید success را به کنترلر [FilterDispatcher] بازگرداند.
- سپس کنترلر [FilterDispatcher] صفحه [/example/HelloWorld.JSP] را نمایش میدهد (خط ۱۰).
اگر دو فایل [struts.xml] و [example.xml] را ادغام کنیم و بسته default را که به نظر غیرضروری است، حذف کنیم، همه چیز طوری رفتار میکند که گویی فایل [struts.xml] به صرفاً فایل [example.xml] کاهش یافته است.
2.6. اقدام HelloWorld
![]() |
طبق بررسی فایل [struts.xml]، اقدام HelloWorld زمانی فعال میشود که درخواست URL توسط کلاینت به /example/HelloWorld باشد. سپس متد execute آن اجرا میشود. این متد باید یک کلید ناوبری را بازگرداند. ما دیدیم که تنها یکی وجود دارد: success، و سپس صفحه /example/HelloWorld.JSP به عنوان پاسخ برای کاربر ارسال میشود.
کد اقدام HelloWorld به شرح زیر است:
- خط ۵: کلاس HelloWorld از کلاس ActionSupport در Struts 2 ارث میبرد. این حالت تقریباً همیشه صادق است. این به ما امکان میدهد تا از متدهای خاصی، مانند متد getText در خط ۸، استفاده کنیم.
- خطوط ۷–۱۰: متد execute که هنگام فراخوانی کنترلکننده Struts اجرا میشود. ما میدانیم که این متد باید یک رشته را بازگرداند، از این رو امضای آن در خط ۷ آمده است. در اینجا، این متد مقدار ثابت SUCCESS را بازمیگرداند که در ActionSupport نیز تعریف شده است. ثابتهای دیگر نیز به همین شکل برای نتیجه متد execute تعریف شدهاند:
SUCCESS | "success" |
ERROR | "error" |
INPUT | "input" |
LOGIN | "login" |
بنابراین در اینجا، متد execute رشته success را برمیگرداند. اگر به فایل [struts.xml] مراجعه کنیم، بنابراین صفحهای که به کاربر بازگردانده میشود /example/HelloWorld.JSP خواهد بود.
- خط ۸: متد execute فیلد message را در خط ۱۴ با مقدار getText(" HelloWorld.message ") مقداردهی اولیه میکند. متد getText متعلق به کلاس والد ActionSupport است. این متد برای بازیابی متن از یک فایل بر اساس زبان مورد استفاده به کار میرود. به طور پیشفرض، فایل package.properties که در همان بسته (package) اکشن قرار دارد، در اینجا استفاده خواهد شد. این فایل در دو نسخه عرضه میشود:
فایل [package.properties] به شرح زیر است:
این یک دنباله از خطوط متن در قالب clé=valeur است. اگر از این فایل استفاده شود، getText("HelloWorld.message") مقدار «Struts is up and running ...» را خواهد داشت.
فایل [package_es.properties] به شرح زیر است:
اگر زبان مورد استفاده توسط مرورگر کلاینت اسپانیایی باشد (ویژگی 'es' در package_es.properties)، getText("HelloWorld.message") مقدار ¡Struts está bien! را خواهد داشت. ... در سایر موارد، فایل [package.properties] استفاده خواهد شد.
2.7. نما HelloWorld.JSP
![]() |
این آخرین قطعه از پازل Struts است. این نمایی است که هنگام درخواست URL /example/HelloWorld نمایش داده میشود. ما هزارتو را که درخواست اولیه از آن عبور کرد تا در نهایت این پاسخ نمایش داده شود، دیدهایم. کد صفحه به شرح زیر است:
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title><s:text name="HelloWorld.message"/></title>
</head>
<body>
<h2><s:property value="message"/></h2>
<h3>Languages</h3>
<ul>
<li>
<s:url id="URL" action="HelloWorld">
<s:param name="request_locale">en</s:param>
</s:url>
<s:a href="%{URL}">English</s:a>
</li>
<li>
<s:url id="URL" action="HelloWorld">
<s:param name="request_locale">es</s:param>
</s:url>
<s:a href="%{URL}">Espanol</s:a>
</li>
</ul>
</body>
</html>
- این صفحه از تگهای HTML (خطوط ۵، ۶ و ...) و تگهایی از یک کتابخانه که در خط ۳ تعریف شده است، استفاده میکند. تمام تگهای <s:xx> به این کتابخانه تعلق دارند.
- خط ۷: تگ <s:text> امکان نمایش متنهای متفاوت را بسته به زبان مرورگر مشتری فراهم میکند. ویژگی 'name' کلید مورد جستجو در فایلهای پیام را مشخص میکند. در اینجا نیز از فایلهای package_xx.properties استفاده خواهد شد. به یاد داشته باشید که این فایلها تنها حاوی یک پیام با کلید HelloWorld.message هستند.
- خط ۱۱: تگ <s:property name="property"> برای نوشتن مقدار یک ویژگی از یک شی به نام ActionContext استفاده میشود. این شی شامل موارد زیر است:
- ویژگیهای اکشنی که اجرا شده است. name="message" مقدار فیلد «message» اکشن جاری را نمایش میدهد. متدهای get و set مرتبط با این فیلد برای بازیابی مقدار آن یا مقداردهی اولیه آن استفاده میشوند. بنابراین این متدها باید وجود داشته باشند.
- ویژگیهای درخواست جاری، که با <s:property name="#request['clé']"> نشان داده میشوند
- ویژگیهای جلسه (session) کاربر، که با <s:property name="#session['clé']"> نشان داده میشوند
- ویژگیهای خود برنامه، که با <s:property name="#application['clé']"> نشان داده میشوند
- پارامترهای ارسالشده توسط مرورگر مشتری، که با <s:property name="#parameters['clé']"> نشان داده میشود
- نشانهگذاری <s:property name="#attr['clé']"> مقدار یک شیء را که در صفحه، درخواست، جلسه و برنامه جستجو شده است، به ترتیب نمایش میدهد.
- خطوط 16–18: تگ <s:url> برای تعریف یک URL استفاده میشود. ویژگی id نامی را به URL که قرار است ایجاد شود اختصاص میدهد. این نام سپس در خط ۱۹ استفاده میشود. ویژگی action مشخص میکند که URL باید به کدام اکشن اشاره کند.
- خط ۱۷: تگ <s:param ..> امکان افزودن پارامترها به URL را در قالب ?param1=valeur1¶m2=valeur2&... فراهم میکند. در اینجا، پارامتر افزوده شده ؟request_locale=es خواهد بود.
در نهایت، URL تولیدشده به شکل زیر خواهد بود:
برای درک این URL، مهم است به خاطر داشته باشید که صفحه [HelloWorld.JSP] در دو حالت نمایش داده میشود:
- (ادامه)
- درخواست مستقیم URL [/exemple-01/example/HelloWorld.JSP]
- درخواست شده از سوی اقدام [/exemple-01/example/HelloWorld.action]
در هر دو مورد، مسیر برای URL، /exemple-01/example. است. تگ <s:url action= "... ">، اکشن تعریفشده توسط ویژگی action را به این مسیر اضافه میکند. این منجر به /example-01/example/HelloWorld میشود. سپس پسوند .action را به URL قبلی اضافه میکند و همچنین پارامترها را از URL، در صورت وجود، اضافه میکند. URL /example-01/example/HelloWorld.action?request_locale=en اقدام HelloWorld را که در فایل [struts.xml] تعریف شده است فراخوانی میکند، در حالی که پارامتر request_locale=en را ارسال میکند. این پارامتر توسط اکشن HelloWorld پردازش نخواهد شد، بلکه توسط یکی از interceptorهای Struts، به طور خاص همان interceptor که به بینالمللیسازی صفحات میپردازد، پردازش خواهد شد. پارامتر request_locale شناسایی و پردازش خواهد شد. زبان صفحه روی انگلیسی (en) تنظیم خواهد شد.
- خط ۱۹: یک لینک HTML را تعریف میکند. ویژگی href تگ یک رشته را انتظار دارد. در اینجا میخواهیم از مقدار URL که در خط ۱۶ تعریف شده است، با id URL استفاده کنیم. برای انجام این کار، href="%{URL}" را مینویسیم. متغیر URL ارزیابی شده و مقدار آن به ویژگی href اختصاص مییابد. در بیشتر موارد، متغیرها بهطور ضمنی ارزیابی میشوند. برای مثال، وقتی مینویسیم
، مقدار خاصیت message نمایش داده میشود، نه رشته " message ". با این حال، در موارد دیگر، باید ارزیابی متغیرها یا خواص را بهصورت اجباری انجام دهید. اگر ما href="URL" را نوشته بودیم، رشته URL به ویژگی href اختصاص مییافت.
- خطوط ۲۳–۲۷: یک لینک HTML ایجاد کنید تا زبان صفحه به اسپانیایی تغییر کند.
2.8. اجرای برنامه
ما پروژه را اجرا میکنیم:
![]() |
- در [1]، پروژه [exemple-01] را اجرا میکنیم. سپس سرور وب Tomcat بهطور خودکار راهاندازی میشود اگر قبلاً در حال اجرا نبوده باشد. URL [/exemple-01] درخواست [3] میشود. سپس از فایل [web.xml] استفاده میشود:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<URL-pattern>/*</URL-pattern>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>example/HelloWorld.JSP</welcome-file>
</welcome-file-list>
</web-app>
- زیرا در URL [/exemple-01] درخواستی، هیچ صفحهای مشخص نشده است، بنابراین Tomcat از تگ <welcome_file-list> از خطوط ۱۶ و ۱۸ استفاده خواهد کرد. بنابراین، URL /example-01/example/HelloWorld.JSP که در دسترس قرار میگیرد.
- از آنجا که Struts 2 تمام URL (خطوط 8 و 9) را پردازش میکند، این URL توسط Struts فیلتر خواهد شد. از آنجا که این به یک اکشن مربوط نمیشود بلکه به یک صفحه (JSP) مربوط است، صفحهٔ دوم نمایش داده خواهد شد.
- بنابراین آنچه در [2] مشاهده میکنیم، همان صفحه HelloWorld.JSP است که در حال مشاهده آن بودهایم.
- در [4]، میبینیم که نه تگ <title><s:text name="HelloWorld.message"/></title> و نه تگ <s:property value="message"/> تأثیر خود را اعمال نکردهاند. دلیل این امر آن است که هیچ اکشنی فراخوانی نشده است. بنابراین، لیست interceptorهایی که قبل از اقدام اجرا میشوند، اجرا نشد، بهویژه interceptor مسئول بینالمللیسازی. برچسب بینالمللیسازی <s:text ...> به درستی پردازش نشد. علاوه بر این، ویژگی message که به فیلد «message» از کلاس Action1 ارجاع میدهد، وجود ندارد. بنابراین، هیچ چیزی نمایش داده نمیشود.
اکنون، بیایید لینک [English] را دنبال کنیم. به صفحه زیر هدایت میشویم:
![]() |
- در [1]، URL درخواستی. ما توضیح دادیم که چگونه این URL تولید میشود. این بار، یک اکشن Struts درخواست میشود: اکشن HelloWorld که در [example.xml] تعریف شده است.
<struts>
<package name="example" namespace="/example" extends="struts-default">
<action name="HelloWorld" class="example.HelloWorld">
<result>/example/HelloWorld.JSP</result>
</action>
</package>
</struts>
- متد execute این اکشن اجرا شد. ما دیدیم که این متد مقدار کلید success را برمیگرداند. از خط ۴ بالا، میتوان نتیجه گرفت که صفحه /example/HelloWorld.JSP به کلاینت بازگردانده میشود. این همان چیزی است که در [3] مشاهده میکنیم.
- در [1] میبینیم که URL درخواستی توسط پارامتر request_locale=en پیکربندی شده است. زبان صفحات اکنون انگلیسی خواهد بود. این انتخاب زبان در جلسه کاربر ذخیره میشود و این تنظیم را تا زمانی که کاربر آن را تغییر دهد، حفظ خواهد کرد.
- در [2] و [3] میتوانیم بینالمللیسازی را در عمل ببینیم. برچسبهای <title><s:text name="HelloWorld.message"/></title> و <s:property value="message"/> در این مورد تأثیر مطلوب را داشتهاند.
اگر اکنون لینک [Espanol] را انتخاب کنیم، به صفحهٔ اسپانیایی هدایت میشویم:
![]() |
2.9. Conclusion
ما یک مثال تولیدشده بهطور خودکار توسط افزونه Struts 2 برای NetBeans را بررسی کردیم. متوجه شدیم که ردیابی پردازش یک درخواست بسیار دشوار است. عناصر زیر در این فرایند دخیل هستند:
- پیکربندی [web.xml]، [struts.xml]
- اقدامی که اجرا میشود: interceptors و متد execute.
در ابتدا، سازوکار داخلی Struts 2 ممکن است پیچیده به نظر برسد. کمی زمان میبرد تا به آن عادت کنید. اکنون مجموعهای از مثالها را ارائه میدهیم که هر کدام جنبه خاصی از Struts را نشان میدهند.















