FauxJSP เป็นการใช้งานหน้าเซิร์ฟเวอร์ Java (JSP) สำหรับการใช้งานในระหว่างการพัฒนา: JSPs ถูกตีความอย่างเกียจคร้าน (แทนที่จะรวบรวม) ซึ่งจะลดเวลาแอปพลิเคชันและเวลาเริ่มต้นหน้าเพิ่มความเร็วในการโหลดหน้าใหม่เมื่อ JSPS เปลี่ยนและไม่จำเป็นต้องรีสตาร์ทเซิร์ฟเวอร์ ใช้งานได้ดีที่สุดเมื่อพัฒนาสามารถใช้ในการผลิตได้หากการปฏิบัติตามข้อกำหนดไม่สำคัญ
web.xml:
< servlet >
< servlet-name >FauxJsp</ servlet-name >
< servlet-class >fauxjsp.servlet.JspServlet</ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name >FauxJsp</ servlet-name >
< url-pattern >*.jsp</ url-pattern >
</ servlet-mapping >เวอร์ชันด้านล่าง (และรวม) 1.2.3 อยู่ใน Maven Central:
pom.xml:
< dependency >
< groupId >com.github.ggeorgovassilis</ groupId >
< artifactId >fauxjsp</ artifactId >
< version >1.2.3</ version >
</ dependency >รุ่นหลังจาก 1.2.3 ต้องใช้ที่เก็บ:
< repositories >
< repository >
< id >fauxjsp-repo</ id >
< url >https://github.com/ggeorgovassilis/fauxjsp/raw/gh-pages/</ url >
< snapshots >
< enabled >true</ enabled >
< updatePolicy >always</ updatePolicy >
</ snapshots >
</ repository >
</ repositories >1.2.7-SNAPSHOT (ไม่ได้เปิดตัวใน Maven Central)
1.2.3
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
trimDirectiveWhiteSpaces , c:set เนื้อหาของร่างกายที่ใช้งาน0.0.9
0.0.5-snapshot
0.0.4-snapshot
ใช่. ในระยะสั้น:
สำหรับพวกคุณส่วนใหญ่ Dudes JSP นั้นเป็นแฟชั่นอย่างน่ากลัว แต่ฉันชอบใช้มันสำหรับการสร้างต้นแบบและ tagfiles น่าเศร้าและน่าประหลาดใจที่มีคนไม่มากนักเกี่ยวกับ tagfiles แม้ว่าพวกเขาจะเป็นเทคนิคที่ได้รับการสนับสนุนและเป็นผู้ใหญ่สำหรับการสร้างส่วนประกอบ UI เว็บที่นำกลับมาใช้ใหม่ได้
การเริ่มต้นแอปพลิเคชัน JSP-Heavy นั้นช้าเนื่องจากการใช้งาน JSP อื่น ๆ จะรวบรวม JSP และ TagFiles ไปยังซอร์สโค้ด Java ก่อนจากนั้นไปยังรหัส BYTE แล้วไปที่รหัสเครื่อง นอกจากนี้เมื่อทำการเปลี่ยนแปลงไฟล์ JSP กระบวนการทั้งหมดจะต้องทำซ้ำซึ่งทำให้การพัฒนาช้าลง ในบางจุดคุณจะได้รับข้อผิดพลาดในการรวบรวมที่ไม่สามารถอธิบายได้ข้อผิดพลาดในการโหลดคลาสไม่มีหน่วยความจำและไลค์คุณจะรู้ว่าคุณมีเพียงพอและคุณจะรีสตาร์ทคอนเทนเนอร์เซิร์ฟเล็ต
FauxJSP ใช้ล่าม JSP และ JSP Servlet ซึ่งอ่านไฟล์ JSP และตีความได้ทันที สิ่งนี้นำมาซึ่งประโยชน์ของการโหลดหน้าใหม่ทันทีเวลาเริ่มต้นแอปพลิเคชันที่รวดเร็วและความทนทาน (ไม่มีการเล่นซอกับคลาสโหลด!) แต่เห็นได้ชัดว่าหน้า JSP ที่สร้างขึ้นนั้นช้ากว่าการโหลดมากกว่าการใช้งานมาตรฐานซึ่งอาจเป็นปัญหาในการผลิต
คุณสมบัติที่นำไปใช้ในปัจจุบัน:
ข้อ จำกัด และคุณสมบัติที่ขาดหายไป:
c:out จะทำงานได้ แต่ Taglibs บุคคลที่สามเช่น DisplayTag จะไม่เป็นเช่นนั้นเว้นแต่ว่าคุณจะนำพวกเขามาใช้ใหม่สำหรับ fauxjspclasspath: คำนำหน้าสำหรับการแก้ไข tagfiles และ jsps ใน classpath ไม่สนับสนุนวิธีมาตรฐานในการแก้ไขทรัพยากร ClassPathเพราะ:
โบนัส:
< dependency >
< groupId >com.github.ggeorgovassilis</ groupId >
< artifactId >fauxjsp</ artifactId >
< version >1.1.0</ version >
</ dependency >หรือ
ดาวน์โหลดแหล่งที่มาและรวบรวม
git clone https://github.com/ggeorgovassilis/fauxjsp.git
cd fauxjsp
mvn install< servlet >
< servlet-name >FauxJsp</ servlet-name >
< servlet-class >fauxjsp.servlet.JspServlet</ servlet-class >
<!-- optionally specify a root for resource lookup, defaults to "/"
<init-param>
<param-name>base-path</param-name>
<param-value>/WEB-INF/jsp/</param-value>
</init-param>
-->
</ servlet >
< servlet-mapping >
< servlet-name >FauxJsp</ servlet-name >
< url-pattern >*.jsp</ url-pattern >
</ servlet-mapping > Servlet API, JSTL, EL ถูกกำหนดขอบเขตตาม provided เนื่องจากคอนเทนเนอร์ servlet หรือเว็บแอปพลิเคชันมีส่วนร่วมในการพึ่งพาเหล่านี้
log4j, beanshell ถูกกำหนดขอบเขตตามที่ provided เพราะเป็นทางเลือก
Commons-lang ถูกกำหนดให้เป็นแบบ compile เพราะเป็นข้อบังคับ
สำหรับรายละเอียดที่ทันสมัยโปรดดู POM
โปรดส่งรายงานข้อผิดพลาดเมื่อคุณพบข้อผิดพลาดหรือต้องการคุณสมบัติที่นำไปใช้ ตอนนี้ในชีวิตจริง (โครงการ) คุณอาจอยู่ในตารางที่แน่นและไม่ต้องการรอการแก้ไขอย่างเป็นทางการ fauxjsp เป็นแบบแยกส่วนและขยายได้ง่าย ดังนั้นลองดูที่บทต่อไปเกี่ยวกับสถาปัตยกรรมของ Fauxjsp ซึ่งจะช่วยให้คุณเข้าใจส่วนประกอบที่ค่อนข้างง่าย ๆ วิธีการแก้ไขและใช้งานฟังก์ชั่นใหม่
JspServlet ยอมรับคำขอ HTTP และแสดงผล JSP ที่ร้องขอ ลำดับทั้งหมดมีลักษณะเช่นนี้:
ServletRequestjspbase (ดู javadocs สำหรับ JspServlet ) สำหรับไฟล์ jspJspParserFactory สำหรับ JspParser ใหม่JspParser ที่แยกวิเคราะห์มันแก้ไขการพึ่งพาซ้ำและส่งคืน JspPageRenderSession ใหม่JspRendererFactory สำหรับ JspRenderer ใหม่JspPage และ RenderSession ต่อ JspRenderer ที่แสดงผล JspServlet มีวิธีการป้องกันจำนวนมากซึ่งสร้างโรงงานต่าง ๆ ที่กล่าวถึงก่อนหน้านี้ หากคุณต้องการการตั้งค่าพิเศษจากนั้นการเอาชนะวิธีการสร้างเหล่านี้ช่วยให้คุณสามารถระบุโรงงานของคุณเองซึ่งสามารถส่งคืนการปรับเปลี่ยนหรือการใช้งานใหม่ของตัวแยกวิเคราะห์และผู้แสดงผล
JspParser และโดยเฉพาะอย่างยิ่งการใช้งาน JspParserImpl เพียงอย่างเดียวนั้นได้รับตำแหน่งไฟล์ JSP แสดงผลและส่งคืนผลลัพธ์ที่แยกวิเคราะห์ โดยละเอียด:
JspParser.parse(path) ได้รับเส้นทางของไฟล์ JSP เพื่อแสดงผลResourceResolver ( JspParserFactory ตั้งค่าไว้ที่หนึ่ง) ซึ่งส่งคืนไฟล์ JSP เป็นสตริงJspNode sTagLibDefinitionCache ซึ่งทำให้แน่ใจว่า taglibs ถูกอ่านเพียงครั้งเดียวในระหว่างการร้องขอแต่ละครั้งJspParserFactory สำหรับตัวแยกวิเคราะห์ใหม่ที่แยกวิเคราะห์แท็กไฟล์ซ้ำ น่าเสียดายที่ปัจจุบันไม่สามารถโหลดแท็กอื่น ๆ นอกเหนือจากแท็กฟิลส์ได้ อย่างไรก็ตามมันเป็นไปได้ที่จะใช้ taglibs ที่หายไปโดยให้การใช้งานพิเศษสำหรับ fauxjsp ด้วยตัวคุณเอง ขึ้นอยู่กับ Taglib คุณกำลังพยายามจำลองสิ่งนี้อาจหรือไม่ใช่งานที่ต้องใช้แรงงานมาก สำหรับตัวอย่างบางส่วนให้ดูคลาส JstlCoreTaglib* โรงงาน DefaultJspParserFactoryImpl ตั้งค่าเหล่านั้นภายใต้เนมสเปซพิเศษหนึ่งรายการสำหรับแต่ละวิธี taglib
<%@ taglib prefix uri tagdir %>
<@ include file %>
<%@ attribute name required rtexprvalue type %>
< jsp : attribute name = " ... " >...</ jsp : attribute >
< jsp : body >...</ jsp : body >
< jsp : doBody />< c : out value = " ... " />
< c : choose test = " ... " >...</ c : choose >
< c : when test = " ... " >...</ c : when >
< c : otherwise >...</ c : otherwise >
< c : forEach var = " ... " items = " ... " varStatus = " ... " begin = " ... " end = " ... " >...</ c : forEach >
< c : if test = " ... " >...</ c : if >
< c : set var = " ... " value = " ... " />
< fmt : message key = " ... " />
< fmt : setBundle basename = " ... " />
< fmt : formatNumber value = " ... " .../>
< fmt : formatDate value = " ... " .../>
< fmt : setLocale value = " ... " />
FauxJSP มอบหมายให้ใช้งานฟังก์ชั่น JSTL มาตรฐานที่ใช้โดยแอปพลิเคชันเซิร์ฟเวอร์ดังนั้นทุกอย่างควรทำงานนอกกรอบ
หากคุณต้องการฟังก์ชั่น taglibs เพิ่มเติมอย่าลืมประกาศใน web.xml:
< jsp-config >
< taglib >
< taglib-uri >http://java.sun.com/jstl/core-rt</ taglib-uri >
< taglib-location >META-INF/c-1_0-rt.tld</ taglib-location >
</ taglib >
</ jsp-config >Taglib-Location สามารถเป็นเส้นทางทรัพยากรเซิร์ฟเวอร์หรือคลาส
ตามที่เขียนไว้ก่อนหน้านี้ fauxjsp ไม่สามารถใช้ taglibs และต้องเลียนแบบพวกเขาแทนซึ่งหมายความว่ามีคนต้องโปรแกรมการจำลองนั้น
ขั้นตอนที่ 1 : สร้างการใช้งาน Taglib เพียงแค่ค้นหาหนึ่งใน taglibs ที่จำลองแล้วเช่น jstlcoretaglibout และคัดลอกและวางมัน
public class TaglibAdd extends TaglibDefinition {
protected void runAdd ( RenderSession session , JspTaglibInvocation invocation ) {
String xExpression = invocation . getArguments (). get ( "x" );
if ( xExpression == null )
throw new RuntimeException ( "Missing x argument" );
Object x = session . elEvaluation . evaluate ( xExpression , session );
String yExpression = invocation . getArguments (). get ( "y" );
if ( yExpression == null )
throw new RuntimeException ( "Missing y argument" );
Object y = session . elEvaluation . evaluate ( yExpression , session );
try {
int ix = ( Number ) x ;
int iy = ( Number ) y ;
String s = "" +( ix + iy );
session . response . getOutputStream (). write (( s ). getBytes ( session . response . getCharacterEncoding ()));
} catch ( Exception e ) {
throw new JspRenderException ( invocation , e );
}
}
@ Override
public void render ( RenderSession session , JspTaglibInvocation invocation ) {
runAdd ( session , invocation );
}
public TaglibAdd () {
this . name = "add" ;
this . attributes . put ( "x" , new AttributeDefinition ( "x" , Integer . class . getName (), true , true ));
this . attributes . put ( "y" , new AttributeDefinition ( "y" , Integer . class . getName (), true , true ));
}
}
ขั้นตอนที่ 2 : ขยาย defaultJSPPARFACTORYIMPL และแทนที่วิธี setup ที่นี่คุณสามารถลงทะเบียน taglib ใหม่ที่คุณเขียน
public class MyJspParserFactory extends DefaultJspParserFactoryImpl {
protected void setup ( JspParserImpl parser ) {
super . setup ( parser );
parser . registerTaglibDefinition (
"http://mytaglibs/add" ,
new TaglibAdd ());
}
} ขั้นตอนที่ 3 : ขยาย JSPServlet และแทนที่ getJspParserFactory เพื่อให้ส่งคืนโรงงานใหม่ของคุณ
public class MyJspServlet extends JspServlet {
protected JspParserFactory getJspParserFactory ( ServletConfig config ){
ResourceResolver location = new ServletResourceResolver ( jspBase , getServletContext ());
DefaultJspParserFactoryImpl factory = new MyJspParserFactory ( location );
return factory ;
}
}ขั้นตอนที่ 4 : ใช้การใช้งาน JSpservlet ใหม่ของคุณใน web.xml แทน jspservlet เก่า
< servlet >
< servlet-name >FauxJsp</ servlet-name >
< servlet-class >MyJspServlet</ servlet-class >
</ servlet >
< servlet-mapping >
< servlet-name >FauxJsp</ servlet-name >
< url-pattern >*.jsp</ url-pattern >
</ servlet-mapping > JspServlet บันทึกผ่าน log4j หากพบใน classpath มิฉะนั้นผ่านกลไกการบันทึก JDK มาตรฐาน การตั้งค่าการบันทึกที่เป็นไปได้ใน log4j.properties อาจมีลักษณะเช่นนี้:
log4j.rootLogger=INFO, stdout
log4j.logger.fauxjsp=INFO, stdout
log4j.additivity.fauxjsp.impl.parser.JspParserImpl=false
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
สคริปต์ถูกนำไปใช้กับการใช้ beanshell ดังนั้นจึงคาดว่าจะมีการเบี่ยงเบนบางอย่างจากพฤติกรรมสคริปต์มาตรฐาน สคริปต์จะไม่ถูกเปิดใช้งานเว้นแต่จะพบล่าม Beanshell บน ClassPath ข้อ จำกัด ปัจจุบันคือ:
เป็นการดีที่คุณจะพบวิธีที่ใช้งานได้ทั้งในสภาพแวดล้อมการผลิต JSP เช่นเดียวกับ fauxjsp ตัวอย่างจะเป็นกรณีของ varargs ที่ใช้ในสคริปต์ที่เราพูดถึงก่อนหน้านี้ ตัวแยกวิเคราะห์ fauxjsp มีแนวโน้มที่จะสับสนโดยสตริงที่ปรากฏใน EL Expressions และ Scriptlets ซึ่งใช้ที่อื่นเป็นตัวคั่นเช่น <,>, {,} ฯลฯ ในกรณีนั้นพยายามใช้ Escapes เช่น U007b สำหรับ {
กรณีการใช้งานคือ Tagfiles หรือ JSPS ของคุณอ้างอิงแท็กไฟล์อื่น ๆ หรือ JSPs ซึ่งอยู่ใน classPath (เช่นไฟล์ JAR) อย่าใช้ tagdir แต่ใช้ uri แทนเมื่อรวมทรัพยากรเช่น:
<%@ taglib prefix = " cp " uri = " classpath:/tagfiles " %> คุณอาจสังเกตเห็นว่า JstlView และ InternalViewResolver ไม่ทำงานและฤดูใบไม้ผลิไม่พบ JSP ของคุณ ภายใต้ประทุนสปริงควรเติมโมเดล (M ใน MVC) ลงในแอตทริบิวต์ HttpServletRequest และส่งต่อการร้องขอไปยัง faUxJSP แต่มันไม่ได้ เราสามารถใช้กลไกการส่งต่ออย่างง่าย ๆ เช่นนี้:
import java . util . Locale ;
import org . springframework . stereotype . Component ;
import org . springframework . web . servlet . View ;
import org . springframework . web . servlet . ViewResolver ;
@ Component
public class ForwardingViewResolver implements ViewResolver {
@ Override
public View resolveViewName ( String viewName , Locale locale ) throws Exception {
ForwardingView view = new ForwardingView ();
view . setUrl ( "classpath:/jsp/" + viewName + ".jsp" );
return view ;
}
} import java . util . Map ;
import javax . servlet . RequestDispatcher ;
import javax . servlet . http . HttpServletRequest ;
import javax . servlet . http . HttpServletRequestWrapper ;
import javax . servlet . http . HttpServletResponse ;
import org . springframework . web . servlet . view . InternalResourceView ;
public class ForwardingView extends InternalResourceView {
@ SuppressWarnings ( "unchecked" )
@ Override
public void render ( Map < String , ?> model , HttpServletRequest request , HttpServletResponse response )
throws Exception {
HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper ( request ) {
@ Override
public String getServletPath () {
return getUrl ();
}
};
exposeModelAsRequestAttributes (( Map < String , Object >) model , wrapper );
exposeHelpers ( wrapper );
RequestDispatcher rd = request . getServletContext (). getNamedDispatcher ( "FauxJsp" );
rd . forward ( wrapper , response );
}
}การมีอยู่อย่างง่าย ๆ ขององค์ประกอบทั้งสองในบริบทของแอปพลิเคชันเว็บควรจะเพียงพอสำหรับพวกเขาที่จะได้รับและเปิดใช้งาน
JspServlet สามารถกำหนดค่าให้แคชแยกวิเคราะห์ JSPs นี่คือการปรับปรุงประสิทธิภาพเล็กน้อยเนื่องจากการแสดงผลปกติช้ากว่าการแยกวิเคราะห์
< servlet >
< servlet-name >FauxJsp</ servlet-name >
< servlet-class >fauxjsp.servlet.JspServlet</ servlet-class >
< init-param >
< param-name >cachePages</ param-name >
< param-value >true</ param-value >
</ init-param >
</ servlet > ระบุพารามิเตอร์ servlet init trimDirectiveWhiteSpaces
< servlet >
< servlet-name >FauxJsp</ servlet-name >
< servlet-class >fauxjsp.servlet.JspServlet</ servlet-class >
< init-param >
< param-name >trimDirectiveWhiteSpaces</ param-name >
< param-value >true</ param-value >
</ init-param >
</ servlet > คุณสมบัติที่จะมาถึง ใกล้ บางครั้งในอนาคต:
นิยายวิทยาศาสตร์ (สิ่งที่ฉันมีความคิดคร่าวๆว่าจะใช้อย่างไร แต่ต้องออกกำลังกายและอาจไม่เคยมา):
Ross Studtman สำหรับบทเรียน JSP ซึ่งเป็นแรงบันดาลใจให้การทดสอบหน่วยที่ยอดเยี่ยมมากมาย
FauxJSP มีให้ภายใต้ GPL เนื่องจาก FauxJSP เป็นเครื่องมือการพัฒนาคุณจะไม่ปรับใช้กับแอปพลิเคชันไบนารีของคุณในการผลิตดังนั้นแง่มุม "ไม่ใช่เชิงพาณิชย์" ของ GPL จึงไม่ส่งผลกระทบต่อแอปพลิเคชันของคุณ