آشنایی با استاندارد JSR 168

مقدمه :

در این مقاله استاندارد (Java Specification Request)  JSR 168 مورد بررسی قرار می گیرد. این استاندارد توسط شرکت Sun ارائه شده است و روشی برای استاندارد کردن فناوری های مختلف و مرتبط با هم Java است. JSR 168 ویژگی هایی را مشخص می کند که به کمک آن پورتال ها و پورتلت های مختلف می توانند با هم کار کنند. این ویژگی ها یک مجموعه واسط برنامه نویسی (API) استاندارد را تعریف می کند که ارتباط بین پورتال ها و پورتلت ها از طریق این واسط انجام می شود. قبل از ارائه این استاندارد لازم بود تا هر پورتلتی متناسب با استاندارد پورتال سروری که قرار بود روی آن نصب شود، ساخته شود. در نتیجه امکان نصب یک پورتلت بر روی پورتال سرورهای متفاوت وجود نداشت. برای رفع این مشکل استاندارد JSR 168 پیشنهاد شده است.

سرولت (Servlet) چیست ؟

سرولت ها کلاس های جاوا هستند که عملکرد وب سرور (web server) را از طریق ایجاد صفحات وب پویا توسعه می دهند. یک محیط اجرا (Runtime Environment) تحت عنوان موتور سرولت (servlet engine) وظیفه بارگذاری، اجرا و برداشتن سرولت ها را برعهده دارد. این موتور بطور مستقیم با وب سرور ارتباط دارد و درخواست ها را از وب سرور گرفته و به سرولت های مناسب ارسال می کند و نتیجه را به درخواست کنندگان بر می گرداند.

موتور سرولت  وظایف زیر را بر عهده دارد :

1)    اولین باری که یک سرولت مورد درخواست قرار می گیرد، آنرا بار می کند.
2)   
متد Init() مربوط به آن سرولت را صدا می زند. در حالت پیش فرض فقط یک نمونه (instant) از سرولت ساخته می شود و موتور سرولت هر درخواست را در یک ریسمان (thread) مجزا به همین نمونه ساخته شده ارسال می کند.
3)   
تمام درخواست هایی را که مربوط به این سرولت است با فراخوانی متد service() مربوط به این سرولت پاسخ می دهد.
4)   
هنگامیکه این موتور ، خاموش (shut down) می شود ، متد destroy() همه سرولت ها را صدا می زند.

 پورتلت (Portlet) چیست ؟

پورتلت یک عنصر وبی است که توسط یک ظرف (Container) مدیریت می شود بدین صورت که ظرف پورتلت درخواست هایی را که این پورتلت مسئول پاسخگویی به آن است ، به پورتلت ارسال می کند و پورتلت این درخواست ها را دریافت کرده و محتوای پویای متناظر با آن را تولید می کند.

 JSR 168 :

JSR 168(Java Specification Request) یک ظرف پورتلت (Portlet Container) است. ظرف پورتلت یک سرویس از طرف سرور است که امکان می دهد تا پورتلت های مختلف با هم اطلاعات رد و بدل کنند یا اینکه به سرویس هایی از قبیل اعتبارسنجی کاربر دسترسی پیدا کنند.

JSR 168  یک واسط برنامه نویسی (API) استاندارد برای ایجاد پورتلت ها و قرار دادن آنها در کنار یکدیگر در قالب یک پورتال را فراهم می کند و تعیین می کند که پورتلت ها باید در چه قالبی ساخته شوند. این استاندارد موجب می شود تا برنامه ای که بصورت یک پورتلت برای یک پورتال ساخته می شود با کمترین تغییر به سادگی درون پورتال های دیگر قابل استفاده باشد. JSR 168 بوسیله بکارگیری سرویس های JCP) JCP یک سازمان باز و بین المللی است که ایجاد استانداردهای Java و پیاده سازی های مرجع را انجام می دهد. برای اطلاعات بیشتر به http://jcp.org مراجعه کنید.) ایجاد شده است.

JSR 168 پشتیبانی صنعتی بسیار قدرتمندی دارد و شرکتهای زیر از آن حمایت می کنند :

  1. The Apache Software Foundation
  2. Art Technology Group
  3. BEA Systems, Boeing
  4. Borland Software Corporation
  5. BroadVision, Inc.
  6. Citrix Systems, Inc.
  7. EDS
  8. Epicentric
  9. Fujitsu Limited
  10. Hitachi, Ltd.
  11. IBM
  12. Novell Inc.
  13. Oracle
  14. SAP AG
  15. SAS Institute
  16. Sun Microsystems, Inc.
  17. Sybase
  18. TIBCO Software Inc.

ویژگی های پورتلت ها (Portlet Specifications) :

1)    مدیریت چرخه زمانی زندگی یک پورتلت
2)   
تعریف پنجره  (window state) و حالت های مختلف یک پورتلت
3)   
مدیریت ترجیحات یک پورتلت
4)   
اطلاعات کاربر
5)   
بسته بندی و استقرار (Packaging and deployment)
6)   
امنیت
7)   
برچسب های JSP برای کمک به ایجاد پورتلت

 مدیریت چرخه زمانی زندگی یک پورتلت

ویژگی پورتلت (Portlet Specification) یک ظرف پورتلت تعریف می کند که برای مدیریت پورتلت بکار می رود. قراردادی برای این ظرف تعریف می شود بدین صورت که تمامی متدهای مربوط به پورتلت در زمان حیات آن فراخوانی می شوند. کسی که پورتلت را پیاده سازی می کند می تواند این متدها را طوری پیاده سازی کند که عملکرد دلخواه پورتلت توسط آنها تامین شود. متدهای مربوط به چرخه حیات یک پورتلت که مستقیما توسط ظرف آن فراخوانی می شوند عبارتند از :

هنگامی که یک نمونه از روی یک پورتلت توسط ظرف پورتلت گرفته می شود، فراخوانی می شود و شامل دستوراتی است که پورتلت را برای پاسخ دادن به درخواست ها آماده می کند.

init()

هنگامی که ظرف پورتلت،  یک پورتلت را از بین می برد فراخوانی می شود و شامل دستوراتی است که یک پورتلت را حذف می کند.

destroy()

هنگامی فراخوانی می شود که کاربر تغییراتی را به یک پورتلت ارسال می کند و ورودی کاربر را مورد پردازش قرار می دهد.

processAction()

هنگامی که پورتلت مجددا روی صفحه ترسیم می شود این متد فراخوانی می شود.

render()

این متد توسط render فراخوانی می شود و شامل دستوراتی است که یک پورتلت را هنگامیکه در حالت view قرار دارد ترسیم می کند.

doView()

این متد توسط render فراخوانی می شود و زمانی که یک پورتلت در حالت Edit قرار دارد فراخوانی می شود.

doEdit()

این متد توسط render فراخوانی می شود و زمانی که یک پورتلت در حالت Help قرار دارد فراخوانی می شود.

doHelp()

متدهای processAction()، render() و سایر متدهای ویژه ای که توسط render() صدا زده می شوند، درخواست های یک پورتلت را می پذیرند و اشیایی شبیه به آنچه که به متد Servlet service() ارسال می شود، به عنوان پاسخ بر می گردانند. با استفاده از این اشیا یک کلاس پورتلت می تواند موارد زیر را انجام دهد :

-        وضعیت پورتلت را حفظ کند و با سایر پورتلت ها و سرولت ها و JSP هایی که نیاز به portlet session دارند ارتباط برقرار کنند.
-        ورودی کاربر را از طریق فرمی که در پورتلت نمایش داده می شود، دریافت کنند.
-        محتوایی را که قرار است در پاسخ به درخواست کاربر نمایش داده شود، بسازند.
-        از وضعیت پورتال و پورتلت اطلاعات لازم را پرس و جو نماید.

تعریف  وضعیت پنجره (window state) و حالت های مختلف یک پورتلت

دو وضعیت اصلی وجود دارند که توسط ظرف برای هر پورتلت نگهداری می شوند. حالت پورتلت و وضعیت پنجره. این یکی از تفاوت های موجود بین پورتلت و سرولت می باشد. هر پورتلتی یک حالت فعلی دارد که عملی را که پورتلت در حال انجام آن است، نشان می دهد. حالت هایی که در ویژگیهای پورتلت تعریف شده اند عبارتند از View، Edit و Help. این حالت ها توسط متد render() فراخوانی می شوند تا تعیین شود که چه متدی برای نمایش پورتلت باید فراخوانی شود. وضعیت این حالت می تواند هرجایی درون کد پورتلت فراخوانی شود.

وضعیت پنجره تعیین می کند که چه مقدار از فضای صفحه پورتال به پورتلت اختصاص می یابد. پورتلت از این اطلاعات برای تعیین اینکه چه مقدار اطلاعات باید render شود استفاده می کند. سه وضعیت پنجره ای که برای هر پورتلت تعریف شده اند عبارتند از حداقل، حداکثر و عادی.

 ترجیحات پورتلت(Portlet Preferences):

پورتلت ها اغلب طوری پیکره بندی می شوند که یک نمای قابل تنظیم یا یک رفتار قابل تنظیم برای کاربران مختلف فراهم کنند. این تنظیمات بعنوان یک مجموعه ماندگار از زوج های نام-مقدار (Key-Value) نمایش داده می شوند و بعنوان ترجیحات پورتلت شناخته می شوند. در ویژگی های  پورتلت ها، ظرف پورتلت وظیفه ذخیره و بازیابی این ترجیحات را بر عهده دارد و این عملیات را از طریق واسط PortletPreferences و متدهای getValues() و setValues() انجام می دهد.

پورتلتها هنگامی که درخواستها را پردازش می کنند به شی PortletPreference دسترسی دارند ولی فقط هنگام فراخوانی processAction امکان تغییر صفات آن را دارند. قبل از اتمام processAction متد store() باید فراخوانی شود تا تغییرات ذخیره شوند. برای تعیین صحت اطلاعات مربوط به ترجیحات پورتلت، کلاس PerferencesValidator پیاده سازی می شود. در حالت اجرا متد store() متد validate() از این کلاس را فراخوانی می کند، قبل از اینکه تغییری روی داده ها انجام دهد.

اطلاعات کاربر (User Information):

ویژگی های  پورتلت، ساز و کاری برای دسترسی به اطلاعات کاربران (نظیر نام، پست الکترونیکی، تلفن، آدرس و ...) را فراهم می کند. این اطلاعات درون یک Map Object که غیر قابل تغییر است قرار می گیرد و از طریق ثابتی به نام USER_INFO که در واسط درخواست، تعریف شده است قابل بازیابی می باشد.

بسته بندی و استقرار (Packaging and deployment)

ویژگی های یک پورتلت امکان بسته بندی و ارائه یک پورتلت را بعنوان بخشی از یک برنامه بایگانی تحت وب (WAR : Web Application Archive) می دهد که می تواند شامل عناصر دیگری مانند JSP ها و نیز سرولت ها باشد.علاوه بر Web.xml که هم اکنون در میان فایلهای WAR یافت می شود، یک فایل توصیفی دیگر به نام portlet.xml وجود دارد که تمامی پیکره بندی های مربوط به پورتلت ها درون آن انجام   می شود. ابزاری که فایل توصیف کننده هر پورتلت را تجزیه و تحلیل (Parse) می کند توسط هر پورتال بطور جداگانه ارائه می شود.

امنیت :

ویژگی های پورتلت شامل امکاناتی (features) می باشد که اجازه می دهد برنامه نویسان پورتلت های امن ایجاد کنند. در فایل توصیفی ارائه پورتلت پرچمی وجود دارد که تعیین می کند پورتلت فقط از طریق HTTPS اجرا شود. این ویژگی برای پورتلت هایی مهم است که اطلاعات حیاتی دارند و این اطلاعات باید بصورت رمز شده روی شبکه منتقل شود. علاوه بر این واسط برنامه نویسی (API) مربوط به پورتلت ها دارای امکاناتی برای اعتبارسنجی کاربر می باشد که از طریق آن می توان کاربر و اطلاعات مربوط به نقش او را جویا شد.

کتابخانه برچسب های JSP :

کتابخانه برچسب های JSP کمک می کند تا صفحات مربوط به پورتلت به درستی با فناوری JSP نمایش داده شوند. به عنوان مثال یک برچسب عادی JSP بطور خودکار یک درخواست پورتلت و اشیای پاسخ را تعریف می کند بطوریکه آنها می توانند درون JSP بکار گرفته شوند.

مثالی از یک پورتلت مطابق با استاندارد JSR 168 :

پورتلت وضعیت آب و هوا :

در اینجا نحوه ایجاد پورتلت وضعیت آب و هوا را درون پورتال Sun-One که مطابق با JSR 168 است توضیح می دهیم :

این پورتلت وضعیت آب و هوا را برای یک منطقه پستی (Zip Code) خاص نمایش می دهد. این پورتلت اطلاعات آب و هوا را از یک وب سرویس به نام JAX-RPC می گیرد.

متد init():

اولین متدی که درون پورتلت فراخوانی می شود متد init() نام دارد که برای مقداردهی اولیه به پورتلت آب و هوا بکار می رود، قبل از اینکه پورتال هیچگونه درخواستی را به آن ارسال نماید.

File: WeatherPortlet.java

public class WeatherPortlet extends GenericPortlet {
      private WeatherForecasterService _weatherService;
      public void init(PortletConfig config)
               throws PortletException, UnavailableException
               {
                        super.init(config);
                        String weatherWSURL = config.getInitParameter("weather.url");
                        if (weatherWSURL==null) {
                            throw new UnavailableException("Weather Web Service URL not found",-1);
               }
            try
      {
            Context ctx = new InitialContext();
            _weatherService = (WeatherForecasterService)ctx.lookup("java:/comp/env/WeatherForecaster");
      }
      catch (Exception ex) {
          throw new UnavailableException("Weather Service can not be initialized");
      }
}
...
}

متد init() ، آدرس الکترونیکی سرویس را از پارامتر ورودی می گیرد و سرویس JAX-RPC را توسط آن مقداردهی اولیه می کند. اگر پارامتر اولیه ذکر نشود یا سرویس JAX-RPC نتواند مقدار دهی شود، این متد استثنای UnavailableException را ایجاد می کند و پورتلت در دسترس نخواهد بود.

متد doView() :

با فرض اینکه پورتلت با موفقیت مقداردهی اولیه شود، هنگامی که کاربران وارد پورتال می شوند و وارد صفحه ای می شوند که در آن پورتلت آب و هوا وجود دارد، متد doView() فراخوانی می شود تا محتویات پورتلت را نمایش دهد. این متد زمانی فراخوانی می شود که پورتلت در حالت  View قرار دارد :

File: WeatherPortlet.java

public class WeatherPortlet extends GenericPortlet {
...

    public
void doView(RenderRequest rReq, RenderResponse rRes)
      throws PortletException, IOException {
          rRes.setContentType("text/html");
          PortletPreferences prefs = rReq.getPreferences();
          String zip = rReq.getParameter("zip");
          if (zip==null) {
              zip = prefs.getValue("zip","10000"); }
          String unit = prefs.getValue("unit","F");
          try {
            WeatherForecaster weatherForecaster = _weatherService.getWeatherForecasterPort();
            Weather weather = weatherForecaster.getWeather(zip,unit.charAt(0));
            weatherForecaster = null;
            rReq.setAttribute("weather",weather);
            PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/weather/weatherView.jsp");
            rd.include(rReq,rRes);
      }
      catch (Exception ex) {
          rRes.setProperty("expiration-cache","0");
          PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/weather/weatherServiceUnavailable.html");
          rd.include(rReq,rRes);
}
      ...
}

متد doView در ابتدا، نوع محتویات پاسخ را تنظیم می کند. سپس پارامترهای render را که همراه با منطقه پستی مورد استفاده قرار می گیرند، چک می کند. اگر zip بعنوان یک پارامتر ارائه نشده باشد، در اینصورت مقداری که در ترجیحات پورتلت قرار داده شده است مورد استفاده قرار می گیرد. واحد اندازه گیری نیز از اینجا خوانده می شود. بعد از اینکه منطقه پستی و واحد اندازه گیری تعیین شدند، وب سرویس weather فراخوانی می شود. شی weather درون صفات درخواست،  بصورت کلیدی با عنوان weather ذخیره می شود. سپس ارسال کننده درخواست به /weather/weatherView.jsp فراخوانی می شود و درخواست به آن ارسال می شود. اگر درخواست وب سرویس آب و هوا موفقیت آمیز نباشد، در اینصورت پورتلت یک صفحه خطا ایجاد می کند. قبل از فراخوانی ارسال، حافظه نهان به مقدار 0 تنظیم می شود تا این صفحه در حافظه نهان قرار نگیرد و اطمینان حاصل شود که بعد از درخواست render بعدی، پورتلت سرویس آب و هوا دوباره فراخوانی خواهد شد.

File: weatherView.jsp

<h3>Weather Information</h3>
<
p>City: <jsp:getproperty name="weather" property="city"/>
<
p>Zip Code: <jsp:getproperty name="weather" property="zip"/>
<
p>Time: <jsp:getproperty name="weather" property="time"/>
<
p>Temperature unit: <jsp:getproperty name="weather" property="unit"/>
<
p>Current Temperature: <jsp:getproperty name="weather" property="currentTemp"/>
<
p>Low: <jsp:getproperty name="weather" property="minTemp"/>
<
p>High: <jsp:getproperty name="weather" property="maxTemp"/>
<
form method="post" action="<portlet:actionURL/>" id="Form1">
    Enter Zip Code:
    <input type="text" name="zip" value="" id="Text1">
    <input type="submit" name="submit" value="Search" id="Submit1">

</
form>

weatherView.jsp در ابتدا یک کتابخانه برچسب پورتلت تعریف می کند. سپس با استفاده از کتابخانه برچسب درونی JSP، از طریق پرس و جو از شی آب و هوا که در صفات درخواست ذخیره می شود، محتوایی را که قرار است نمایش داده شود، می سازد. در پایان فرمی را می سازد که به کاربران اجازه می دهد تا منطقه پستی را وارد کنند. این فرم برچسب actionURL را مورد استفاده قرار می دهد. پورتلت ها باید برچسب پورتلت actionURL مربوط به PortletURL یا renderURL را مورد استفاده قرار دهند تا بتوان لینکی که به آنها اشاره می کند را ایجاد کرد، زیرا پورتلت ها به یک URL خاص نمی چسبند بلکه از طریق یک پورتال احضار می شوند.

متد doEdit():

هنگامیکه کاربر روی دکمه edit بر روی عنوان پورتلت کلیک می کند، حالت پورتلت را به حالت Edit تغییر می دهد و متد doEdit() را فراخونی می کند.

File: WeatherPortlet.java

public class WeatherPortlet extends GenericPortlet {
    ...
    public void doEdit(RenderRequest rReq,RenderResponse rRes)
    throws PortletException, IOException {
        rRes.setContentType("text/html");
        PortletPreferences prefs = rReq.getPreferences();
        String zip = prefs.getValue("zip","1000");
        String unit = prefs.getValue("unit","F");
        rReq.setAttribute("zip",zip);
        rReq.setAttribute("unit",unit);
        String error = rReq.getParameter("error");
        if (error!=null) {
            error = "<font color=\"red\"><b>ERROR: </b>" +error+"</error>";
        }
        else {
            error = "";
        }
    rReq.setAttribute("error",error);
    PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/weather/weatherEdit.jsp");
    rd.include(rReq,rRes);
}
...
}

doEdit() ابتدا، نوع محتوای پاسخ را تعیین می کند. سپس zip codee فعلی و واحد اندازه گیری را که در ترجیحات پورتلت قرار دارند و بعنوان صفات درخواست ذخیره شده اند، بازیابی می کند. همچنین بررسی می کند که آیا از درخواست قبلی خطایی رخ داده است یا خیر و آنرا درون صفات درخواست ذخیره می کند. یک ارسال کننده درخواست (Request Dispatcher) به /weather/weatherEdit.jsp بدست می آید و درخواست به آن ارسال می شود :

File: weatherEdit.jsp

<%@ page import="javax.portlet.RenderRequest" %>
<%@ page import="javax.portlet.RenderResponse" %>
<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

<
portlet:defineobjects/>
<
h3>Edit Weather Preferences</h3>
<
p><%=renderRequest.getAttribute("error")%></p>
<
form method="post" action="<portlet:actionURL/>" id="Form1">
    ZIP: <input type="text" name="zip" value="<%=renderRequest.getAttribute("zip")%>" id="Text1">
    <p>UNIT: <input type="text" name="unit" value="<%=renderRequest.getAttribute("unit")%>" id="Text2">
    <
p><input type="submit" id="Submit1" name="Submit1"> <input type="reset" id="Reset1" name="Reset1">

</
form>

weatherEdit.jsp فرمی را می سازد که امکان می دهد منطقه پستی و واحد اندازه گیری ویرایش شوند. همچنین هر پیغام خطایی را که رخ داده است، نشان می دهد. همانند weatherView.jsp آدرسی که actionn فرم به آن اشاره می کند از روی برچسب actionURL از کتابخانه برچسب های پورتلت ساخته می شود.

متد doHelp():

هنگامیکه کاربر روی دکمه help، که بر روی عنوان پورتلت قرار گرفته است، کلیک می کند، حالت پورتلت به حالت Help تغییر می کند و متد doHelp() فراخوانی می شود :

File: WeatherPortlet.java

public class WeatherPortlet extends GenericPortlet {
    ...
    public void doHelp(RenderRequest rReq, RenderResponse rRes)
    throws PortletException, IOException {
        rRes.setContentType("text/html");
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/weather/weatherHelp.html");
        rd.include(rReq,rRes);
}
...

این متد نوع محتویات را تنظیم می کند و یک ارسال کننده درخواست را بکار می برد تا صفحه راهنمای مربوط به پورتلت به نمایش درآید.

متد processAction():

هنگامیکه کاربر بر روی دکمه ارسال روی فرم پورتلت کلیک می کند، این متد فراخوانی می شود.

File: WeatherPortlet.java

public class WeatherPortlet extends GenericPortlet {
    ...
    public void processAction(ActionRequest aReq, ActionResponse aRes)
                throws PortletException, IOException {
                PortletPreferences prefs = aReq.getPreferences();
                String zip = aReq.getParameter("zip");
            if (aReq.getPortletMode().equals(PortletMode.VIEW)) {
                if (zip==null) {
                    zip = prefs.getValue("zip","10000");

               
}
                aRes.setRenderParameter("zip",zip);
            }

            else

            if
(aReq.getPortletMode().equals(PortletMode.EDIT)) {
                boolean editOK;
                String errorMsg = null;
                String unit = aReq.getParameter("unit");
                prefs.setValue("zip",zip);
                prefs.setValue("unit",unit);

            try
{
                prefs.store();
                editOK = true;
            }

            catch
(ValidatorException ex) {
                editOK = false;
                errorMsg = ex.getMessage();
            }

            if
(editOK) {
                aRes.setPortletMode(PortletMode.VIEW);
            }

            else
{
               
aRes.setRenderParameter("error", URLEncoder.encode(errorMsg));
            }
        }
    ...
}

ابتدا شی PortletPreferences را فراخوانی می کند. اگر پورتلت در حالت Vieww باشد، بررسی می کند که آیا منطقه پستی و واحد اندازه گیری وجود دارند یا خیر. در صورتیکه وجود ندارند متغیرهای محلی مقادیر پیش فرض را می گیرند. در نهایت منطقه پستی را بعنوان پارامتر render قرار می دهد که توسط فراخوانی های بعدی توسط متد doView() مورد استفاده قرار می گیرد.

اگر پورتلت در وضعیت Edit باشد، مقادیر جدید درون ترجیحات پورتلت ذخیره می شوند. متد store() مربوط به شی ترجیحات، مقادیر جدید را ذخیره می کند. اگر منطقه پستی و واحد اندازه گیری معتبر نباشند، متد store() با خطا مواجه می شود. اگر ذخیره کردن با خطا مواجه شود یک پرچم خطا برافراشته می شود و یک پیغام خطا در متغیر محلی errorMsg قرار می گیرد. اگر عمل Edit موفقیت آمیز باشد، حالت پورتلت در ActionResponse از حالت Edit به حالت View تغییر پیدا می کند، در غیر اینصورت یک پیغام خطا در صفات درخواست (Request Attributes) تنظیم می شود و پورتلت در وضعیت Edit باقی می ماند.

کلاس WeatherPreferencesValidator :

یک پورتلت ممکن است کلاس validator را در deployment descriptor تعریف کند. این شی هنگامی که متد store() از ترجیحات پورتلت فراخوانی می شود، صدا زده می شود. اگر validator استثنائی ایجاد کند، متد store() ، لغو می شود در غیر اینصورت ترجیحات جدید پورتلت بطور ماندگار ثبت می شوند :

File: WeatherPreferencesValidator.java

public class WeatherPreferencesValidator implements PreferencesValidator {
    public void validate(PortletPreferences preferences)throws ValidatorException {
        String zip = preferences.getValue("zip",null);
        String unit = preferences.getValue("unit",null);
        if (zip==null || unit==null) {
            Set set = new HashSet();
            set.add("zip");
            set.add("unit");
            throw new ValidatorException("preferences must contain zip and unit keys",set);
        }
        try {
          int i = Integer.parseInt(zip);
          if (i<0 || i>99999) {
              throw new Exception();
          }
        }
        catch (Exception ex) {
          Set set = new HashSet();
          set.add("zip");
          throw new ValidatorException("zip must be a valid Zip code",set);
        }
       if (!unit.equals("F") && !unit.equals("C")) {
          Set set = new HashSet();
          set.add("unit");
          throw new ValidatorException("unit must be 'F' (Fahrenheit) or 'C' (Celsius)",set);
       }
    }
}

در اینجا Validator تعریف شده اطمینان حاصل می کند که منطقه پستی وارد شده یک zip codee معتبر برای امریکا است و درجه نیز فارنهایت یا سلسیوس می باشد.

The portlet.xml Deployment Descriptor :

Portlet.xml داده نماهایی (Meta Information) را که ظرف پورتلت برای اجرا شدن به آنها نیاز دارد، تعریف می کند. برای هر تعریف پورتلت در portlet.xml ، ظرف پورتلت یک شی را ایجاد می کند که تمام درخواست های مربوط به این پورتلت از آن استفاده خواهند کرد. این ویژگی دقیقا با رفتار ظرف پورتلت یکی است :

File: portlet.xml

<portlet-app>
      <portlet>
            <portlet-name>WeatherPortlet</portlet-name>
            <portlet-class>sample.portlet.WeatherPortlet</portlet-class>
            <init-param>
                  <name>weather.url</name>
                  <value>java:/comp/env/WeatherProvider</value>
            </init-param>
            <expiration-cache>3600</expiration-cache>
            <supports>
                  <mime-type>text/html</mime-type>
                  <portlet-mode>EDIT</portlet-mode>
                  <portlet-mode>HELP</portlet-mode>
            </supports>
            <portlet-info>
                  <title>WeatherPortlet</title>
            </portlet-info>
            <portlet-preferences>
                  <preference>
                        <name>zip</name>
                        <value>95054</value>
                  </preference>
                  <preference>
                        <name>unit</name>
                        <value>F</value>
                  </preference>
                  <preferences-validator>sample.portlet.WeatherPreferencesValidator</preferences-validator>
            </portlet-preferences>
      </portlet>

</
portlet-app>

Portlet-name، portlet-class و init-param عناصری هستند که نام، کلاس و پارامترهای اولیه را برای پورتلت تعریف می کنند. عنصر expiration-cache تعیین  می کند که ظرف پورتلت تا چه زمانی باید محتوای پورتلت را در حافظه نهان ذخیره کند. اگر پورتلت ویژگی expiration-cache را هنگام render کردن درخواست تنظیم نکند، در اینصورت مقداری که در deployment descriptor تعریف شده است، مورد استفاده قرار خواهد گرفت.

عنصر supports تعریف می کند که پورتلت چه نو ع  محتویاتی و چه حالت هایی راپشتیبانی می کند. ظرف پورتلت ، پورتلت را در حالت هایی که پشتیبیانی نمی کند، فراخوانی نمی کند.
عنصر
portlet-info اطلاعاتی نظیر عنوان پیش فرض پورتلت را تعریف می کند.
عنصر
portlet-preferences مقادیر پیش فرض را برای ترجیحات پورتال تعریف   می کند. (منطقه پستی و واحد اندازه گیری در مثال آب و هوا)

The web.xml Deployment Descriptor :

برنامه های پورتلت در حقیقت برنامه های توسعه یافته مبتنی بر وب (Extended Web Application) می باشند و باید دارای فایل Web.xml باشند.

File: web.xml

<web-app>
    <display-name>PortletApp Sample</display-name>

</
web-app>

Web.xml در این مثال فقط نام برنامه تحت وب را تعریف می کند.

ویژگیهای پورتلت چه مواردی را اداره نمی کند ؟

ویژگیهای پورتلت برای اداره کردن نیازهای یک پورتلت به تنهایی کافی است. با این حال باید در نظر داشت که پورتال سرورها اغلب عملکردهای اضافه ای را ارائه می دهند که توسط این خصوصیات اداره نمی شود.

برای اطلاعات بیشتر به آدرسهای زیر مراجعه کنید :


آخرین بروزرسانی
۲۳ بهمن ۱۴۰۲ 
تعداد کلیک
۶,۰۹۰

فهرست نظرها و ارسال نظر جدید

نام را وارد کنید
ایمیل را وارد کنید
تعداد کاراکتر باقیمانده: 1000
نظر خود را وارد کنید