Skip to content

17. مثال ۱۵ – یکپارچه‌سازی Struts 2 / Spring

در مثال قبلی، ما هیچ داده‌ای با دامنه Application که در تمام درخواست‌های همه کاربران مشترک باشد، نداشتیم. در اینجا مثالی از این مورد را نشان می‌دهیم. برای پیاده‌سازی آن، از فریم‌ورک اسپرینگ [http://www.springsource.org/] استفاده می‌کنیم. اسپرینگ یک ابزار فوق‌العاده ارزشمند است. ما در این مثال تنها بخش کوچکی از قابلیت‌های آن را نشان می‌دهیم. مثال بعدی از آن استفاده گسترده‌تری خواهد کرد.

هدف این برنامه نمایش داده‌ها از دامنه Application است.

17.1. پروژه NetBeans

پروژه NetBeans برای این برنامه به شرح زیر است:

  • در [1]:
    • [web.xml]، که وب‌اپلیکیشن را پیکربندی می‌کند، با نسخه‌های قبلی خود متفاوت خواهد بود
    • [applicationContext.xml] فایل پیکربندی Spring است
  • به [2]: نمای [Context.JSP] که داده‌ها را از محدودهٔ Application نمایش خواهد داد
  • در [3]:
    • فایل پیام [messages.properties]
    • فایل اصلی پیکربندی Struts [struts.xml]. این با برنامه‌های قبلی متفاوت خواهد بود.
  • در [4]:
    • اقدام Struts [Action1.java]
    • کلاس [Config.java]، که داده‌های در مقیاس برنامه را ذخیره خواهد کرد
    • فایل پیکربندی ثانویه Struts [example.xml]
  • در [5]: کتابخانه Struts 2
  • در [6]:
    • آرشیوهای مورد نیاز برای Spring: [spring-core, spring-context, spring-beans, spring-web, commons-logging]
    • آرشیو افزونه Spring برای Struts 2. امکان یکپارچه‌سازی Spring با Struts 2 را فراهم می‌کند [struts2-spring-plugin]

در مقایسه با نسخه‌های قبلی:

  • شما باید آرشیوها را به پروژه اضافه کنید
  • فایل‌های [web.xml] و [struts.xml] را ویرایش کنید

17.2. Configuration

17.2.1. فایل [web.xml]

فایل [web.xml] به شرح زیر به‌روزرسانی شده است:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" 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">
  <display-name>Exemple 14</display-name>
  <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>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

تغییر در خطوط ۱۲–۱۴ رخ می‌دهد. یک listener به برنامه وب اضافه می‌شود. وقتی برنامه وب راه‌اندازی می‌شود، کلاسی که این listener را پیاده‌سازی می‌کند، نمونه خواهد شد. این یک کلاس Spring است. این کلاس از فایل [WEB-INF/applicationContext.xml] استفاده خواهد کرد. این به شرح زیر است:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  
  <!--پیکربندی bean در محدودهٔ برنامه -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

</beans>
  • فایل پیکربندی Spring دارای تگ ریشه <beans> است (خطوط ۲ و ۱۱). beans می‌تواند به عنوان «ابجکت‌ها» تفسیر شود. Spring تمام ابجکت‌های (bean) یافت‌شده در این فایل پیکربندی را instantiate (ایجاد) می‌کند. این کار تنها یک بار، در زمان راه‌اندازی Spring در شروع اپلیکیشن وب انجام می‌شود.
  • خطوط ۷–۹: یک بین به نام config (id) را تعریف می‌کنند. بین پیکربندی (config bean) با کلاس [example.Config] مرتبط است. اسپرینگ این کلاس را نمونه سازی خواهد کرد.
  • خط ۸: یک ویژگی از کلاس [example.Config] را تعریف می‌کند. Spring متد [example.Config].setNbMaxUsers(10) را فراخوانی خواهد کرد. بنابراین متد setNbMaxUsers باید در داخل کلاس وجود داشته باشد. این متد به شرح زیر است:

package example;

public class Config {

  private int nbMaxUsers;

  public int getNbMaxUsers() {
    return nbMaxUsers;
  }

  public void setNbMaxUsers(int nbMaxUsers) {
    this.nbMaxUsers = nbMaxUsers;
  }
  
}

این کلاس تنها یک فیلد، nbMaxUsers، را به همراه فیلدهای get و set تعریف می‌کند. اگر توضیحات را به درستی دنبال کرده باشید، هنگامی که برنامه وب اجرا می‌شود، یک نمونه از کلاس [Config] با مقدار 10 برای فیلد nbMaxUsers آن ایجاد می‌شود. ما تنها یک فیلد تعریف کرده‌ایم، اما این برای نمایش ما کافی است. می‌خواهیم نشان دهیم که این فیلد، که می‌تواند نماینده حداکثر تعداد کاربران باشد، یک متغیر در محدوده Application است که برای همه اکشن‌ها قابل دسترسی است. این چیزی است که با استفاده از اکشن [Action1] نشان خواهیم داد.

17.2.2. فایل [struts.xml]

فایل اصلی پیکربندی Struts به شرح زیر است:


<?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.custom.i18n.resources" value="messages" />
  <!-- یکپارچه‌سازی اسپرینگ -->
  <constant name="struts.objectFactory.spring.autoWire" value="name" />

  <include file="example/example.xml"/>

  <package name="default" namespace="/" extends="struts-default">
    <default-action-ref name="index" />
    <action name="index">
      <result type="redirectAction">
        <param name="actionName">Action1</param>
        <param name="namespace">/example</param>
      </result>
    </action>
  </package>

</struts>

تنها خط ۱۰ با نسخه‌های قبلی این فایل متفاوت است. این خط یک ثابت Struts را تعریف می‌کند. ابجکت‌هایی که توسط Spring ایجاد شده‌اند می‌توانند در سایر ابجکت‌ها تزریق شوند. این اساس و پایه Spring است. در اینجا، یک مرجع به ابجکتی از نوع [Config] که توسط Spring ایجاد شده است، می‌تواند در ابجکت‌های Struts تزریق شود. اینجاست که پلاگین Spring برای Struts 2 وارد عمل می‌شود و یکپارچگی Spring با Struts را تضمین می‌کند.

خط ۱۰ مشخص می‌کند که تزریق اشیاء Spring به یک شیء Struts (autowire) به‌طور خودکار بر اساس نام (value) انجام خواهد شد. بیایید به فایل پیکربندی [applicationContext.xml] بازگردیم:


<!--پیکربندی Beans با دامنهٔ برنامه -->
  <bean id="config" class="example.Config" >
    <property name="nbMaxUsers" value="10"/>
  </bean>

آنچه Struts 2 آن را نام bean می‌نامد، در واقع id در اینجا است. بنابراین در اینجا، bean نمونه‌سازی‌شده از نوع [Config] با نام config نامگذاری شده است.

اقدام [Action1.java] به شرح زیر است:


package example;

import com.opensymphony.xwork2.ActionSupport;
...
public class Action1 extends ActionSupport implements SessionAware, RequestAware, ParameterAware {

  // سازنده بدون پارامتر
  public Action1() {
  }
  
  // سشن، درخواست، پارامترها
  private Map<String, Object> session;
  private Map<String, Object> request;
  private Map<String, String[]> parameters;
  private Config config;

  @Override
  public String execute() {
  ....
    // درخواست
    request.put("nbMaxUsers", config.getNbMaxUsers());

    // نمایش صفحه JSP
    return SUCCESS;
  }
...
  public Config getConfig() {
    return config;
  }

  public void setConfig(Config config) {
    this.config = config;
  }
}

عمل [Action1] به جز جزئیات زیر، با مورد موجود در برنامه قبلی یکسان است:

  • خط 15: یک فیلد با نام config اضافه شده است. از آنجا که این فیلد نام یک بیانی را که توسط Spring ایجاد شده است را یدک می‌کشد، به طور خودکار مرجعی به آن شیء دریافت خواهد کرد. بنابراین اکشن به پیکربندی برنامه یا به طور کلی‌تر، به داده‌های موجود در دامنه Application دسترسی دارد.
  • خط ۳۱: Spring فیلد config را از طریق متد set آن ایجاد خواهد کرد. بنابراین این متد باید موجود باشد.
  • خط ۲۱: اکشن به اطلاعات دامنه Application دسترسی پیدا می‌کند. ما حداکثر تعداد کاربران nbMaxUsers را در پرس‌وجو قرار می‌دهیم تا نما [Context.JSP] بتواند آن را نمایش دهد.

17.2.3. فایل [example.xml]

فایل پیکربندی ثانویه Struts با نسخه قبلی یکسان است:


<?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="Action1" class="example.Action1">
      <result name="success">/example/Context.JSP</result>
    </action>
  </package>
</struts>

17.3. ویوی [Context.JSP]

نما [Context.JSP] به شرح زیر است:


<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <title><s:text name="Context.titre"/></title>
    <s:head/>
  </head>

  <body background="<s:url value="/ressources/standard.jpg"/>">
    <h2><s:text name="Context.message"/></h2>
    <h3><s:text name="Context.parameters"/></h3>
    nom : <s:property value="#parameters['nom']"/><br/>
    age : <s:property value="#parameters['age']"/>
    <h3><s:text name="Context.session"/></h3>
    compteur : <s:property value="#session['compteur']"/>
    <h3><s:text name="Context.request"/></h3>
    nbMaxUsers : <s:property value="#request['nbMaxUsers']"/>
  </body>
</html>

17.4. تست‌ها

یک مثال از اجرا به شرح زیر است: