دومین تمرین آشنایی با فناوریهای Java Enterprise Edition
جاواکاپ سیر مطالعاتی پیشنهادی شرکتهای مختلف را با هدف آگاهی متقاضیان شغلی از فضای صنعت جاوا و آموزش جاوا منتشر می نماید.
این تمرین آموزشی، دومین تمرین آموزشی از مجموعه تمرینهایی است که در شرکت مشاوران نرمافزاری اعوان طراحی شده است. این تمرین، به مهارتهای برنامهنویسی server-side محدود شده است و برای انجام آن، نیازی به مهارتهای client-side (مانند HTML و JavaScript و AngularJS) نیست.
برای انجام این تمرین، باید ابتدا تمرین اول پیشنهادی شرکت اعوان را مرور کرده باشید. به خصوص بخشهای «معرفی سیستم»، «پیش نیازها»، «آماده سازی محیط»، «دریافت پروژه از Git» ، «اتصال تامکت به پایگاه داده» ، «اجرای برنامه» و «تست سرویس آزمایشی» را باید با موفقیت گذرانده باشید.
مقدمه
در این تمرین چند وبسرویس ساده ذخیره و بازیابی اطلاعات فروشگاهی تولید میشود. در این تمرین از فناوری های زیر استفاده می شود:
- Spring Framework
- JPA برای کار با پایگاه داده (با کمک فناوری Hibernate)
- JAX-RS برای تولید سرویسهای REST
برای مرور این مفاهیم، میتوانید مسیر مطالعاتی پیشنهادی شرکت اعوان را ملاحظه فرمایید.
در ابتدا به معرفی کلی سیستم فروشگاهی خواهیم پرداخت. سپس در چند گام، برخی وبسرویسهای موردنیاز این سیستم را پیاده سازی خواهیم کرد.
- روش انجام تمرین
- ابتدا بخش معرفی سیستم را کامل و دقیق مطالعه نمایید.
- سپس هر گام را مطالعه کنید و انجام دهید. بهتر است قبل از انجام یک مرحله، مرحله بعدی را مطالعه نکنید.
- بهتر است از تکتک نامهایی که در تمرین ذکر شده، تبعیت کنید. مثلاً نام کلاسی که برای موجودیت «محصول» پیادهسازی میکنید دقیقاً ProductEntity بگذارید و در این کلاس، فیلدی با عنوان code قرار دهید.
- پس از انجام هر مرحله آن را به مربی تحویل بدهید و ایرادات آن را بپرسید.
معرفی سیستم
سیستم فروشگاهی دارای موجودیتهای اصلی زیر است:
- موجودیت محصول (ProductEntity). هر محصول در فروشگاه به فروش میرسد. هر محصول تعدادی دسته دارد. ویژگیهای این کلاس عبارتند از:
- شناسه (id) از نوع Long
- کد (code) از نوع String
- دستهها (categories) از نوع فهرستی از دستهها (دسته=CategoryEntity)
- موجودیت دسته (CategoryEntity). هر دسته، نوع محصول را مشخص میکند. ویژگیهای این کلاس عبارتند از:
- شناسه (id) از نوع Long
- موضوع (subject) از نوع String
- محصولها (products) از نوع فهرستی از محصولها (محصول = ProductEntity)
- موجودیت سفارش (OrderEntity). یک سفارش، خرید یک مشتری را نشان میدهد. ویژگیهای این کلاس عبارتند از:
- شناسه (id) از نوع Long
- آیتم ها (items) از نوع فهرستی از آیتم ها (آیتم = ItemEntity)
- زمان خرید (purchaseTime) از نوع زمان (java.util.Date)
- موجودیت آیتم (ItemEntity). یکی از آیتمهای یک سفارش را نشان میدهد. ویژگیهای این کلاس عبارتند از:
- شناسه (id) از نوع Long
- محصول (product) از نوع ProductEntity
- تعداد (quantity) از نوع int
بنابراین روابط بین موجودیتها این گونه است:
- رابطهی بین محصول و دسته: ManyToMany
- رابطهی بین محصول و آیتم: OneToMany
- رابطهی بین آیتم و سفارش: ManyToOne
مثالی برای توصیف موجودیتهای این سیستم:
دو محصول با کدهای AL20 و TA30 داریم. AL20 دارای دستههای Game و Electronics است ولی TA30 فقط دارای دسته Entertainment است. همچنین دسته Sport ثبت شده که هیچ محصولی در این دسته ثبت نشده است. یک سفارش در تاریخ 1/1/2017 ثبت شده که شامل دو آیتم است: آیتم اول شامل محصول AL20 به تعداد 5 عدد و آیتم دوم شامل محصول TA30 به تعداد 3 عدد.
پیشنیازها
پیشنیاز انجام این تمرین، انجام تمرین اول است. اگر تمرین اول را انجام ندادهاید، حداقل باید بخشهای «معرفی سیستم»، «پیش نیازها»، «آماده سازی محیط»، «دریافت پروژه از Git» ، «اتصال تامکت به پایگاه داده» ، «اجرای برنامه» و «تست سرویس آزمایشی» از این تمرین را با موفقیت گذرانده باشید.
پیاده سازی چند وبسرویس REST
در این مرحله می خواهیم چند سرویس REST پیادهسازی کنیم. صرفاً برای سادگی، همه این سرویسها از نوع GET در نظر گرفته شدهاند. برای با توجه به توضیحات فوق، نمونه آدرسهای زیر گویای سرویسهایی هستند که باید پیادهسازی شوند:
.../save-product/AL20
.../save-category/Game
.../set-product-categories/AL20?category=Game&category=Electronics
.../save-order/2017-01-02/AL20:5,TA30:3
.../get-product-categories/AL20
نمونه خروجی این سرویس:
[ { "id": 3, "subject": "Game" }, { "id": 4, "subject": "Electronics" }, { "id": 33, "subject": "Fun" } ]
.../find-items-in-range/2015-01-12/2017-11-06
نمونه خروجی این سرویس:
[ { "id": 6, "product": { "id": 1, "code": "AL20" }, "quantity": 5 }, { "id": 7, "product": { "id": 2, "code": "TA30" }, "quantity": 3 }, { "id": 35, "product": { "id": 1, "code": "AL20" }, "quantity": 2 }, { "id": 36, "product": { "id": 2, "code": "TA30" }, "quantity": 2 } ]
.../total-sales/Electronics
نمونه خروجی این سرویس:
[ [ "AL20", 150 ], [ "TA30", 10 ] ]
چالشهای حل این مسأله
برخی از چالشهایی که در پیادهسازی این تمرین با آن روبرو میشوید، عبارتند از:
- تنظیم صحیح روابط بین موجودیتها و جزئیاتی مانند ستونهای کلید خارجی و …
- ارسال (برگرداندن) یک موجودیت به همراه روابط آن از طریق وبسرویس و JSON
- برخی راه حلها: استفاده از امکان Mapper در WISE ، استفاده از اشیاء DTO به جای Entity در برگرداندن اطلاعات از طریق سرویس، استفاده از JsonIgnore@ و …
- پیادهسازی صحیح جستجو (با کمک JPQL یا Criteria API) برای سرویسهایی که کار جستجو انجام میدهند