1. ภาพรวม
Freemarker เป็นเครื่องมือเทมเพลตซึ่งเป็นเครื่องมือทั่วไปสำหรับการสร้างเอาต์พุตข้อความตามเทมเพลต มันเขียนด้วยชวาบริสุทธิ์ Freemarker ได้รับการออกแบบมาเพื่อสร้างหน้าเว็บ HTML โดยเฉพาะแอปพลิเคชันตามรูปแบบ MVC แม้ว่า FreeMarker จะมีความสามารถในการเขียนโปรแกรม แต่ก็มักจะเตรียมข้อมูลที่จะแสดงโดยโปรแกรม Java และสร้างหน้าโดย Freemarker และแสดงข้อมูลที่เตรียมผ่านเทมเพลต (ดังแสดงด้านล่าง)
Freemarker ไม่ใช่เฟรมเวิร์กแอปพลิเคชันเว็บ แต่เหมาะสำหรับเป็นส่วนประกอบของเฟรมเวิร์กแอปพลิเคชันเว็บ Freemarker ไม่เกี่ยวข้องกับคอนเทนเนอร์เพราะไม่ทราบเกี่ยวกับ HTTP หรือ Servlets; FreeMarker ยังสามารถนำไปใช้กับสภาพแวดล้อมแอปพลิเคชันที่ไม่ใช่ WEB, Freemarker นั้นเหมาะสมกว่าเป็นส่วนประกอบมุมมองของเฟรมเวิร์ก Model2 (เช่น struts) และคุณยังสามารถใช้ไลบรารีแท็ก JSP ในเทมเพลต นอกจากนี้ Freemarker ก็ฟรี
2. เงื่อนไขการเตรียม Freemarker
freemarker.2.3.16.jar ที่อยู่ดาวน์โหลดจะไม่ถูกโพสต์ที่นี่ ... (แพ็คเกจ Jar นี้อยู่ใน struts2)
3. หลักการของ freemarker สร้างหน้าคงที่
Freemarker สร้างหน้าคงที่ ก่อนอื่นคุณต้องใช้หน้าเทมเพลตที่คุณกำหนดเอง หน้าเทมเพลตนี้อาจเป็น HTML ธรรมดาที่สุดหรืออาจเป็นนิพจน์ค่าซ้อนกันฉลากหรือแท็กที่กำหนดเอง ฯลฯ ใน freemarker จากนั้นหน้าเทมเพลตจะถูกอ่านในพื้นหลังแยกวิเคราะห์แท็กไว้เพื่อให้การดำเนินการที่สอดคล้องกันเสร็จสมบูรณ์จากนั้นส่งพารามิเตอร์ในคู่คีย์-ค่าเพื่อแทนที่นิพจน์ค่าในเทมเพลต หลังจากนั้นสามารถสร้างหน้า HTML ใหม่ได้ตามเส้นทางที่กำหนดค่าเพื่อให้บรรลุวัตถุประสงค์ของการเข้าถึงแบบคงที่
4. ป้ายกำกับที่จัดทำโดย freemarker
Freemarker มีแท็กที่มีประโยชน์และใช้กันทั่วไปมากมาย แท็ก Freemarker มีชื่อ <## ชื่อแท็ก> เช่นนี้ $ {value} แสดงเนื้อหาของชื่อตัวแปรเอาต์พุตดังนี้:
1. รายการ: แท็กนี้ส่วนใหญ่เป็นรายการรวบรวมรายการที่ส่งผ่านจากฝั่งเซิร์ฟเวอร์ผ่านซ้ำ ๆ เช่น:
<#list namelist เป็นชื่อ> $ {ชื่อ} </#list>ชื่อเป็นตัวแปรลูปที่ถ่ายเมื่อวนรอบรายการ เมื่อ Freemarker แยกวิเคราะห์แท็กรายการมันจะเทียบเท่ากับ:
สำหรับ (ชื่อสตริง: namelist) {system.out.println (ชื่อ); -2. ถ้า: แท็กนี้ส่วนใหญ่ใช้สำหรับการตัดสินเช่น:
<#if (ชื่อ == "Chen Jingchou")> อาวุธของเขาคือ: สิบห้า ~~ </#ถ้า>
นี่คือฉลากการตัดสินตามเงื่อนไข ควรสังเกตว่าสมการเงื่อนไขจะต้องอยู่ในวงเล็บซึ่งเทียบเท่ากับ:
if (names.equals ("Chen jingchou")) {system.out.println ("อาวุธของเขาคือ: สิบห้า ~~"); -
3. รวม: แท็กนี้ใช้ในการนำเข้าไฟล์
<#include "รวม. html"/>
แท็กนำเข้านี้มีประโยชน์มากโดยเฉพาะอย่างยิ่งสำหรับการใช้ใหม่
นอกจากนี้คุณสามารถใช้ $ {} เพื่อรับค่าในไฟล์คงที่ วิธีการค่าเหมือนกับนิพจน์ EL ซึ่งสะดวกมาก
นี่คือตัวอย่าง (static.html):
<! doctype html public "-// w3c // dtd html 4.01 transitional // en" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <title> แทรกชื่อเรื่องที่นี่ </title> </head> <body> คำอธิบาย: $ {คำอธิบาย} <br/> ขนาดการรวบรวม: $ {namelist? ขนาด} <br/> รายการรวบรวมรายการซ้ำ: <br/> <#list namelist เป็นชื่อ> นี่คือ $ {names_index+1} บุคคลที่เรียกว่า (ชื่อ == "Chen jingchou")> อาวุธของเขาคือ: สิบห้า ~~ <#elseif (ชื่อ == "yuwentuo")> <#-โปรดทราบว่าไม่มีการกลับมาที่นี่ แต่ในตอนท้าย-> อาวุธของเขาคือ: Xuanyuan Sword ~# WeaponMap? keys เป็นคีย์> คีย์ ---> $ {key} <br/> ค่า -----> $ {weaponmap [key]! ("null")} <#-fremarker ไม่รองรับ Null สามารถใช้งานได้! แทนที่จะเป็นค่าที่ว่างเปล่า ในความเป็นจริงคุณยังสามารถให้ค่าเริ่มต้น ----- $ {weaponmap [key]? default ("null")} คุณสามารถตรวจสอบได้ว่ามันเป็นโมฆะก่อนเอาต์พุต <#ถ้าอาวุธ [key] ??> </#ถ้า>-> <br/> </#list>รหัสจริง:
แพ็คเกจ com.chenghui.test; นำเข้า Java.io.File; นำเข้า Java.io.FileOutputStream; นำเข้า java.io.ioException; นำเข้า Java.io.OutputStreamWriter; นำเข้า java.io.writer; นำเข้า java.util.arraylist; นำเข้า java.util.hashmap; นำเข้า java.util.list; นำเข้า java.util.map; นำเข้า freemarker.template.configuration; นำเข้า freemarker.template.defaultobjectwrapper; นำเข้า freemarker.template.template; นำเข้า freemarker.template.templateException; คลาสสาธารณะ createhtml {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {ลอง {// สร้างการกำหนดค่าการกำหนดค่าวัตถุที่เหมาะสม = การกำหนดค่าใหม่ (); configuration.setDirectoryFortemPlateLoading (ไฟล์ใหม่ ("D: // Project // WebProject // webContent // web-inf // แม่แบบ")); configuration.setObjectWrapper (ใหม่ defaultObjectWrapper ()); configuration.setDefaultEncoding ("UTF-8"); // สิ่งนี้จะต้องตั้งค่ามิฉะนั้นจะถูกอ่านไม่ออกในหน้าสร้าง // รับหรือสร้างเทมเพลต เทมเพลตเทมเพลต = configuration.getTemplate ("static.html"); แผนที่ <สตริงวัตถุ> parammap = ใหม่ hashmap <string, object> (); parammap.put ("คำอธิบาย", "ฉันกำลังเรียนรู้ที่จะใช้ freemarker เพื่อสร้างไฟล์คงที่!"); รายการ <String> namelist = new ArrayList <String> (); namelist.add ("Chen Jingchou"); namelist.add ("yuer"); namelist.add ("yuwentuo"); parammap.put ("namelist", namelist); แผนที่ <string, Object> weaponmap = new hashmap <string, object> (); Weaponmap.put ("First", "Xuanyuan Sword"); Weaponmap.put ("Second", "Kongtong Seal"); Weaponmap.put ("Third", "Nuwa Stone"); Weaponmap.put ("Fourth", "Shennong Ding"); Weaponmap.put ("Fifth", "Fuxi Qin"); Weaponmap.put ("Sixth", "Kunlun Mirror"); Weaponmap.put ("เจ็ด", Null); parammap.put ("WeaponMap", WeaponMap); Writer Writer = New OutputStreamWriter (ใหม่ fileOutputStream ("success.html"), "UTF-8"); เทมเพลต PROCESS (PARAMMAP, นักเขียน); System.out.println ("ขอแสดงความยินดีรุ่นนี้ประสบความสำเร็จ ~~"); } catch (ioexception e) {e.printstacktrace (); } catch (templateException e) {e.printStackTrace (); -
สิ่งนี้อาจถือได้ว่าเป็นรุ่นที่เรียบง่ายและเรียบง่าย แต่ก็ยังห่างไกลจากการใช้งานในทางปฏิบัติเนื่องจากแท็กที่ได้รับจาก Freemarker ไม่สามารถตอบสนองความต้องการของเราได้เลย ในเวลานี้จำเป็นต้องใช้แท็กที่กำหนดเองเพื่อให้ความต้องการของเราสมบูรณ์ -
5. แท็กที่กำหนดเอง freemarker
แท็กที่กำหนดเอง Freemarker คือการเขียนแท็กด้วยตัวเองแล้วแยกวิเคราะห์ด้วยตัวเอง พวกเขาควบคุมอินพุตและเอาต์พุตของแท็กด้วยตัวเองอย่างสมบูรณ์ซึ่งจะช่วยให้โปรแกรมเมอร์มีพื้นที่เล่นได้อย่างมาก
ขึ้นอยู่กับขั้นตอน:
ในอดีตเมื่อเขียนแท็กคุณต้องเพิ่ม # หลังจาก <แต่เพื่อรับรู้แท็กที่กำหนดเองคุณต้องเพิ่ม @ หลังจากนั้นจากนั้นคุณสามารถกำหนดพารามิเตอร์บางอย่างในภายหลัง เมื่อโปรแกรมดำเนินการ template.process (parammap, out);, มันจะแยกวิเคราะห์แท็ก freemarker ทั้งหมดในหน้าทั้งหมด
การปรับแต่งแท็กจำเป็นต้องปรับแต่งคลาสจากนั้นใช้ TemplatedirectiveModel, การเขียนวิธีการดำเนินการใหม่เสร็จสิ้นการได้มาของพารามิเตอร์ทำบางสิ่งบางอย่างตามพารามิเตอร์ ฯลฯ
ในการผูกแท็กที่กำหนดเองเพื่อแยกวิเคราะห์คลาสคุณต้องใส่อินสแตนซ์ของคลาส Parse ใน Parammap และคีย์ที่เก็บไว้นั้นเหมือนกับแท็กที่กำหนดเอง -
หมายเหตุ: ในแท็กที่กำหนดเองหากไม่มีอะไรในแท็กแท็กเริ่มต้นและแท็กปลายจะต้องไม่เป็นบรรทัดเดียวกันมิฉะนั้นจะมีการรายงานข้อผิดพลาด
freemarker.log.jdk14loggerfactory $ jdk14logger ข้อผิดพลาด
ฉันถูกหลอกและนี่คือข้อผิดพลาดใน Freemarker
นี่คือตัวอย่างของ Static.html:
<! doctype html public "-// w3c // dtd html 4.01 transitional // en" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <title> แทรกชื่อเรื่องที่นี่ </title> </head> <body> <##-ตัวแปรที่กำหนดเอง-> <#assign num = 'hehe' /// $ {num} <br/> แท็กที่กำหนดเอง <@content name = "chenghui" age = "120"> $} $} $}
นี่คือคลาสการแยกวิเคราะห์ของเทมเพลต HTML แบบคงที่ด้านบน:
แพ็คเกจ com.chenghui.test; นำเข้า freemarker.template.objectwrapper.default_wrapper; นำเข้า java.io.ioException; นำเข้า java.io.writer; นำเข้า java.util.map; นำเข้า freemarker.core.environment; นำเข้า freemarker.template.templatedirectivebody; นำเข้า freemarker.template.templatedirectivemodel; นำเข้า freemarker.template.templateException; นำเข้า freemarker.template.templateModel; นำเข้า freemarker.template.templateModelexception; นำเข้า freemarker.template.templatenumbermodel; นำเข้า freemarker.template.templatescalarmodel; / ** * คลาสความละเอียดแท็กที่กำหนดเอง * @Author Administrator * */ คลาสสาธารณะ contentDirective onplateMelection templatedirectiveModel {สตริงสุดท้ายคงที่ param_name = "name"; สตริงสุดท้ายคงที่ส่วนตัว param_age = "อายุ"; @Override โมฆะสาธารณะดำเนินการ (สภาพแวดล้อม env, แผนที่พารามิเตอร์, templateModel [] loopvars, templatedirectivebody body) พ่น templateException, ioexception {ถ้า (body == null) {โยน templateModelexception ใหม่ ("ร่างกาย null"); } else {string name = getString (param_name, params); อายุจำนวนเต็ม = getint (param_age, params); // หลังจากได้รับพารามิเตอร์คุณสามารถดำเนินการเฉพาะตามการดำเนินการเฉพาะจากนั้นแสดงข้อมูลบนหน้า if (name! = null) {env.setVariable ("เอาต์พุต", default_wrapper.wrap ("พารามิเตอร์ที่ได้จากคลาสการแยกวิเคราะห์ contentDirective คือ:"+ชื่อ+",")); } if (อายุ! = null) {env.setVariable ("ผนวก", default_wrapper.wrap ("อายุ:"+อายุ)); } นักเขียน out = env.getOut (); out.write ("จากที่นี่คุณสามารถดูเนื้อหาเฉพาะในหน้าเช่นเดียวกับ document.writer การดำเนินการเขียน <br/>"); Body.render (ออก); /* หากคุณระมัดระวังคุณจะพบว่าหน้าแสดงคำสั่ง out.write () เอาต์พุตแล้วเอาต์พุตเนื้อหาของเอาต์พุต จะเห็นได้ว่าเมื่อร่างกายกำลังแยกวิเคราะห์มันจะใส่พารามิเตอร์ลงใน env ก่อนและเฉพาะเมื่อหน้าพบรูปแบบที่สอดคล้องกันมันจะได้รับค่า อย่างไรก็ตามหากไม่มีแบบฟอร์มจะมีการรายงานข้อผิดพลาด ฉันคิดว่า freemarker ทำได้ไม่ดีที่นี่และข้อผิดพลาดจะถูกสัมผัสกับหน้าเว็บเมื่อแยกวิเคราะห์ คุณสามารถแต่งหน้าได้สำหรับ $ {เอาท์พุท! "null"} ด้วยวิธีนี้และคุณมักจะรู้สึกว่ามันไม่ดีเท่าการแสดงออกของ EL */}}/ ** * รับค่าของพารามิเตอร์ของประเภทสตริง * @param paramname * @param parammap * @return * @throws templatemodelexception */ สตริงคงที่สาธารณะ getString if (model == null) {return null; } if (แบบจำลองอินสแตนซ์ของ templateScalarmodel) {return ((templateScalarmodel) รุ่น) .getAstString (); } อื่นถ้า (แบบจำลองอินสแตนซ์ของ TemplatenumberModel) {return ((templatenumberModel) รุ่น) .getAsNumber (). TOSTRING (); } else {โยน templateModelexception ใหม่ (paramname); }} / ** * * รับพารามิเตอร์ประเภท int * @param paramname * @param parammap * @return * @throws templatemodelexception * / integer คงที่สาธารณะ getint (สตริง paramname, แผนที่ <String, templatemodel> parammap) if (model == null) {return null; } if (แบบจำลองอินสแตนซ์ของ templateScalarmodel) {string str = ((templateScalarmodel) รุ่น) .getAstString (); ลอง {return integer.valueof (str); } catch (numberFormatexception e) {โยน templateModelexception ใหม่ (paramname); }} else if (model instanceof templatenumberModel) {return ((templatenumberModel) รุ่น) .getAsNumber (). intValue (); } else {โยน templateModelexception ใหม่ (paramname); -จากนั้นเพิ่ม:
// การแยกแท็กที่กำหนดเอง parammap.put ("เนื้อหา", contentDirective ใหม่ ());ด้วยวิธีนี้มันสามารถใช้โดยทั่วไป Freemarker ทำแท็กที่กำหนดเองให้แก้ไขปัญหาการเขียนตรรกะทางธุรกิจอย่างง่าย อย่างไรก็ตามมันเป็นไปไม่ได้ที่จะทำสิ่งนี้ในโครงการจริงเพราะมันยังไม่ได้รวมเข้ากับฤดูใบไม้ผลิและคุณต้องใส่อินสแตนซ์การแยกวิเคราะห์ของคลาสการแยกวิเคราะห์ในเวลาการแยกวิเคราะห์ -