הפעל את מנוע התבנית המהיר

מנוע תבנית המהירות מאפשר לך לעבד נתונים מתוך יישומים ושרתים. משמש בעיקר לפיתוח אתרים דינמיים מבוססי סרוולט, ההפרדה הנקייה של Velocity בין תבנית וקוד Java הופכת אותו לאידיאלי לפיתוח אתרי MVC. כמנוע תבניות כללי, Velocity מתאימה למטרות רבות אחרות, כגון יצירת קוד, יצירת XML ושינוי טרנספורמציה ועיבוד זרם טקסטואלי. מאמר זה מציג את שפת התבנית המהירות (VTL) ומספק דוגמאות לשימוש במנוע המהירות, כולל כיצד ליצור תוכן אינטרנט בסביבת Java-servlet.

Velocity הוא כלי תבנית קוד פתוח שפותח על ידי קהילת מתנדבים בינלאומית ומתארח על ידי פרויקט ג'קרטה של ​​קרן Apache Software. באתר פרוייקט Velocity של ג'קרטה, שם תוכלו להוריד את קוד המקור הזמין בחינם, קהילה משגשגת וגדלה של משתמשים מוכנה לענות על שאלות ולהציע פתרונות לבעיות תבניות נפוצות. המהירות נכתבה בהשראת פרויקט ה- WebMacro החלוצי, עבודה שאנו בקהילת המהירות אסירת תודה עליה.

במאמר זה, אני מציג פריימר קצר על מנוע התבנית המהיר ושפת התבנית שלו, שפת התבנית המהירות (VTL). אני מדגים גם כיצד להשתמש במהירות באמצעות מספר דוגמאות.

שלום עולם, כמובן

שום הסבר על נושא הקשור לתכנות לא יהיה שלם ללא דוגמה של Hello World. כל יישום המשתמש ב- Velocity דורש שני חלקים. הראשונה היא התבנית, שבדוגמה זו היא קובץ שנקרא helloworld.vm:

שלום $ name! ברוך הבא ל- Velocity!

השנייה היא תוכנית Java מתאימה הנקראת HelloWorld.java:

ייבא java.io.StringWriter; יבוא org.apache.velocity.app.VelocityEngine; ייבא org.apache.velocity.Template; ייבא org.apache.velocity.VelocityContext; class public HelloWorld {public static void main (String [] args) זורק Exception {/ * first, get and initialize a engine * / VelocityEngine ve = new VelocityEngine (); ve.init (); / * הבא, קבל את התבנית * / תבנית t = ve.getTemplate ("helloworld.vm"); / * ליצור הקשר ולהוסיף נתונים * / VelocityContext context = VelocityContext חדש (); context.put ("שם", "עולם"); / * הפוך כעת את התבנית למכתב StringWriter * / StringWriter כותב = StringWriter חדש (); t.merge (הקשר, כותב); / * הצג את העולם * / System.out.println (writer.toString ()); }}

כעת, כאשר אתה מרכיב ומפעיל תוכנית זו, תראה את הפלט:

שלום עולם! ברוך הבא ל- Velocity!

זו דוגמה טריוויאלית, אך היא מכילה את החלקים המכריעים כדי לתת לך מושג על מה מדובר בתבנית מהירות.

מדוע עלי להשתמש בו?

עוצב ככלי תבנית כללי קל לשימוש, מהירות שימושית בכל אזור יישומי Java הדורש עיצוב נתונים והצגתם. עליך להשתמש ב- Velocity מהסיבות הבאות:

  • הוא מסתגל לאזורי יישומים רבים
  • הוא מציע תחביר פשוט וברור עבור מעצב התבניות
  • הוא מציע מודל תכנות פשוט למפתח
  • מכיוון שהתבניות והקוד נפרדים, תוכלו לפתח ולתחזק אותן באופן עצמאי
  • מנוע ה- Velocity משתלב בקלות בכל סביבת יישומי Java, במיוחד servlets
  • מהירות מאפשרת לתבניות גישה לכל שיטה ציבורית של אובייקטים נתונים בהקשר

הנקודה האחרונה חשובה - המשמעות היא שתוכלו לעשות שימוש חוזר בשיעורים הקיימים שלכם. לכן, אובייקטים שבהם ברצונך להשתמש בתבניות שלך אינם צריכים להיות מובנים בצורה מסוימת, כמו JavaBeans, או ליישם מצבי קלט / פלט או מחזור חיים מיוחדים, כגון תגיות של JSP (JavaServer Pages). הדרישה היחידה היא שהשיטות יהיו ציבוריות. תוכלו לראות יותר מכך כאשר אנו מכסים את שפת התבנית בפירוט.

אחת מהעוצמות של Velocity היא בכך שהיא אוכפת מאוד הפרדה של אחריות פונקציונלית בתוך היישום. היא עושה זאת על ידי הגבלת הגישה לתבנית לאובייקטים שקוד היישום מעמיד לרשותם באופן ספציפי. משמעות הדבר היא שמעצבים יכולים להתמקד אך ורק במצגת הנתונים (התצוגה), ומתכנת היישומים יכול להתמקד בבקרת היישומים (הבקר) ובלוגיקה העסקית וניהול הנתונים (המודל) ב- Model-View-Controller (MVC). התפתחות. MVC הוא דפוס פיתוח מקובל שמפשט הן את הפיתוח והן את התחזוקה השוטפת של יישומים מתוחכמים.

היכן אני משתמש בו?

מהירות משמשת בהצלחה ב:

  • יישומי אינטרנט מבוססי Servlet
  • הפקת קוד Java ו- SQL
  • עיבוד ושינוי XML
  • עיבוד טקסט, כגון יצירת קבצי RTF

המהירות משמשת לרוב כמנוע רינדור לפיתוח אפליקציות אינטרנט מבוססות Java-servlet, במקום או בשילוב עם JSPs וטכנולוגיות טיוח אחרות. מלבד תחביר התבנית הקל והמתוחזק, נעשה שימוש ב- Velocity בפיתוח אתרים מכיוון ששפת התבנית שלה יכולה לתפעל ולהציג את הנתונים, ולא ליצור נתונים. זה מרתיע תכנות בתוך התבניות. זה דבר טוב; זה שומר על הלוגיקה העסקית והיישומית של קוד ה- Java שלך היכן שהם שייכים.

מהירות מתאימה היטב לפיתוח אתרי J2EE (Java 2 Platform, Enterprise Edition) מכיוון שהפלטפורמה מתאימה לטכנולוגיות פלט שאינן JSP. בעוד JSP כלול במפרט J2EE, J2EE אינו דורש את השימוש בו.

איך זה עובד?

אתה משתמש באותו תהליך כללי כדי ליצור יישום מבוסס מהירות כמו בכל יישום. הבה נבחן דוגמה מעניינת יותר מאשר היישום Hello World לעיל. נניח שאתה מפעיל חנות לחיות מחמד ורוצה ליצור פיצוץ בדוא"ל כדי להודיע ​​על מכירה. ראשית, עליך לעצב את הדוא"ל ואז לפתח את התבנית והקוד על סמך העיצוב הזה.

שיקולי זמן עיצוב

עליכם לקחת בחשבון שלושה אלמנטים לעיצוב שלכם:

  • אילו נתונים לכלול במייל
  • מה ליצור את מרכיבי הנתונים צריכים לקחת (למשל, כמו List, Map, או String)
  • איך קוראים לאלמנטים הנתונים האלה

לדוגמא זו, נניח שתחליט על שלושה חיות מחמד למכירה, שלכל אחת מהן מחיר מפורסם אחר. אתה מחליט להשתמש במפה כדי לשייך כל שם של חיית מחמד למחיר שלה, ואז לאחסן את כל שלוש המפות ברשימה. אתה קורא לרשימה הזו petList, לשם חיית המחמד nameוהמחיר כמו priceבמפה. כעת, לאחר שזיהיתם את הנתונים הרלוונטיים, ייצוגם וקריטריונים למתן שמות, תוכלו לכתוב את הקוד ואת עיצוב התבנית.

כתוב את הקוד ואת עיצוב התבנית

ברגע שאתה מסכים לגבי פרטים ספציפיים, Velocity מאפשרת לך לכתוב את הקוד ולעצב את התבנית במקביל. המעצב משלב את הנתונים בתוכן של מצגת nondata (כמו תמונות, טקסט וכדומה) בתבנית. במקרה זה, אנו פשוט כותבים בגוף הדוא"ל:

$ petList.size () חיות מחמד במבצע! אנו גאים להציע חיות מחמד משובחות אלה במחירים מדהימים אלה. החודש בלבד, בחר מבין: #foreach ($ pet in $ petList) $ pet.name רק עבור $ pet.price # שלח התקשר היום!

בתור המתכנת, עליכם:

  • אחזר את כל הנתונים ממקורות הנתונים - מסד נתונים באמצעות JDBC (Java Database Connectivity), קובץ או סתם משהו מחושב
  • שים את הנתונים האלה בהקשר באמצעות השמות המוסכמים
  • הפוך את התבנית עם ההקשר להפקת פלט

אולי אתה זוכר מהדוגמה העולם שלום כי התייחסתי בכיתה VelocityContextכמו ההקשר . על פי המודל a java.util.Map, ההקשר הוא אובייקט שמאחסן נתונים המסופקים על ידי היישום או ה- servlet אליו הגישה התבנית.

לדוגמא זו, אנו מקבלים את כל הנתונים ממקורות הנתונים שלנו (במקרה זה אנו מחברים אותם בקוד), מארגנים אותם ומוסיפים אותם להקשר:

/ * צור את רשימת המפות שלנו * / ArrayList list = ArrayList new (); מפת מפה = HashMap חדש (); map.put ("שם", "סוס"); map.put ("מחיר", "00.00"); list.add (מפה); מפה = HashMap חדש (); map.put ("שם", "כלב"); map.put ("מחיר", "9.99"); list.add (מפה); מפה = HashMap חדש (); map.put ("שם", "דוב"); map.put ("מחיר", ".99"); list.add (מפה); / * הוסף את הרשימה ל- VelocityContext * / VelocityContext context = VelocityContext חדש (); context.put ("petList", list);

נראה שאנחנו באמת רוצים להיפטר מהדובים האלה!

כעת, כשהנתונים מסודרים וממוקמים בהקשר והתבנית מוכנה, אנו יכולים לעבד את התבנית מול ההקשר. הנה הקוד:

ייבא java.io.StringWriter; ייבא java.util.List; ייבא java.util.ArrayList; ייבא java.util.Map; ייבא java.util.HashMap; ייבא org.apache.velocity.Template; ייבא org.apache.velocity.VelocityContext; יבוא org.apache.velocity.app.VelocityEngine; מחלקה ציבורית PetStoreEmail {public static void main (String [] args) זורק Exception {/ * first, get and initialize a engine * / VelocityEngine ve = new VelocityEngine (); ve.init (); / * לארגן את הנתונים שלנו * / ArrayList list = ArrayList new (); מפת מפה = HashMap חדש (); map.put ("שם", "סוס"); map.put ("מחיר", "00.00"); list.add (מפה); מפה = HashMap חדש (); map.put ("שם", "כלב"); map.put ("מחיר", "9.99"); list.add (מפה); מפה = HashMap חדש (); map.put ("שם", "דוב"); map.put ("מחיר", ".99 "); list.add (map); / * הוסף את הרשימה ל- VelocityContext * / VelocityContext context = חדש VelocityContext (); context.put (" petList ", רשימה); / * קבל את התבנית * / תבנית t = ve.getTemplate ("petstoreemail.vm"); / * עכשיו הפוך את התבנית לסופר * / StringWriter כותב = StringWriter חדש (); t.merge (הקשר, כותב); / * השתמש בפלט בגוף הדוא"ל שלך * / sendEmail (writer.toString ());}}toString ()); }}toString ()); }}

תוכנית שלמה זו מייצרת את גוף הדוא"ל שלך. מכיוון ש- Velocity מעבד תבניות ל- a Writer, אתה יכול לנהל את הפלט בקלות. במקרה זה, הפלט המועבר נכנס ל- a Stringדרך ה- StringWriter, אך הוא יכול היה לעבור בקלות לקובץ, לדפדפן או ל- BLOB (אובייקט גדול בינארי) במסד נתונים. זו אחת הסיבות שמהירות משתלבת כל כך בקלות ביישומי Java.

פלט התוכנית (גוף הדוא"ל שלך) נראה כך:

3 חיות מחמד במבצע! אנו גאים להציע חיות מחמד משובחות אלה במחירים מדהימים אלה. החודש בלבד בחרו מבין: סוס לכלב 00.00 בלבד עבור 9.99 דוב בלבד עבור .99 התקשרו היום!

שפת תבנית מהירות

הראיתי תבניות Velocity לשתי דוגמאות שונות, אך בשני המקרים לא הסברתי מה הסימון המיוחד עשה (אם כי אתה בטח יכול לנחש).

שפת התבנית המהירות (VTL) היא תחביר פשוט המספק שני חלקים: הפניות, פורמליזם לגישה לאובייקטים בהקשר; ו הנחיות, סט של דוחות המשמשים לבקרת פעולה. מתואר כ"הגדרת שפה עם ערכת תכונות המתאימה בנוחות בכרטיס ביקור רגיל "(ראה" להתגבר במהירות עם ג'ים ג'יג'לסקי ") VTL נשמר בכוונה על ידי הקהילה בפשטות ובקטנה.

הפניות

הפניות בנתוני הגישה לתבנית. הם מתערבבים באופן חופשי עם תוכן התבנית שאינו VTL. רשמית מוגדר, הפניה היא דבר תבנית מתחיל בתו "$" ו מתייחס משהו בהקשר. אם לא קיים אובייקט נתונים תואם בהקשר, התבנית פשוט מתייחסת אל ההפניה כאל טקסט ומעבירה אותה כמות שהיא לזרם הפלט.

להלן תבנית קצרה המכילה התייחסות פשוטה המעורבת בתוכן שאינו VTL:

שלום $ name! ברוך הבא ל- Velocity!

הנה, ההתייחסות היא $name. כמו בדוגמת Hello World, Velocity מחליפה $nameבתבנית את toString()ערך ההחזרה של מה שממוקם בהקשר מתחת למפתח name:

שלום עולם! ברוך הבא ל- Velocity!

ההפניה למהירות מאפשרת גישה לשיטה הציבורית של כל אובייקט ותחביר התבנית זהה לזה שהיה בקוד Java. להלן מספר דוגמאות:

יש $ myBean.getSize () אלמנטים. $ myObject.anotherMethod (1, "נתונים נוספים") $ foo.getBar (). barMethod ("שלום", $ moredata) $ foo.myMethod ($ bar.callThis ())

אולי אתה זוכר מהדוגמה הדוא"ל Pet Store שאנחנו מאוחסן המידע שם ומחיר java.util.Map, והגישה לנתונים באמצעות שני אסימונים nameו price, אשר אינם קיימים שיטות של java.util.Mapהכיתה:

 $ pet.name עבור $ pet.price בלבד 

זה עובד מכיוון ש- Velocity משלבת מנגנון אינטרוספקציה דמוי JavaBean המאפשר לך להביע גישות לשיטה בהפניות באמצעות סימון מאפיין. בתבנית הדוגמא לחנות חיות מחמד, מתקן ההתבוננות של Velocity מוצא ומפעיל את השיטה Mapשל public Object get(String)בעזרת המקשים nameו- price. נוכל לגשת לאותם נתונים בדרך אחרת על ידי הפעלת get(String)השיטה ישירות בתבנית:

 $ pet.get ('שם') תמורת $ pet.get בלבד ('מחיר') 

זה יפיק את אותה תפוקה, ומייצג טוב יותר את מה שקורה בפועל. עם זאת, הדרך השנייה המשתמשת בסימון המאפיינים קלה יותר לקריאה ואינה קושרת את התבנית שלך ליישום הספציפי של מחלקת הנתונים. לדוגמא, אתה יכול להחליף את Mapב Listעם קורס שיש שיטות ציבור getName()ו getPrice(), ואת התבנית לדוגמא המקורית המכילה את האפשרויות הבאות ימשיך בעבודה:

 $ pet.name עבור $ pet.price בלבד