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
نعم. باختصار:
بالنسبة لمعظمكم ، فإن الرجال الرائعين JSP هو أمر فظيع ، لكني أحب استخدامه للنماذج الأولية و tagfiles. للأسف والمثير للدهشة ، لا يعرف الكثير من الناس عن tagfiles على الرغم من كونهم تقنية مدعومة وناضجة بشكل جيد لإنشاء مكونات واجهة المستخدم القابلة لإعادة الاستخدام.
يكون بدء تطبيق JSP-Heavy بطيئًا لأن تطبيقات JSP الأخرى ستعمل أولاً على تجميع JSP و TagFiles إلى رمز مصدر Java ، ثم إلى رمز البايت ثم إلى رمز الجهاز. أيضًا ، عند إجراء تغييرات على ملفات JSP ، يجب تكرار العملية بأكملها مما يبطئ التطوير. في مرحلة ما ، ستحصل على أخطاء ترجمة غير قابلة للتفسير ، وأخطاء تحميل الفصل ، ونفاد الذاكرة وما بين الإعجاب ، ستعرف أن لديك ما يكفي وستقوم بإعادة تشغيل حاوية Servlet.
يقوم FauxJSP بتنفيذ مترجم JSP و Servlet JSP الذي يقرأ ملفات JSP ويفسرها على الطيران ، وتخطي التجميع تمامًا. هذا يجلب الاستفادة من إعادة تحميل الصفحة الفورية ، وأوقات بدء التطبيق السريعة والمتانة (لا يوجد عبء على مرملة الفصل!) ولكن من الواضح أن صفحات JSP التي تم إنشاؤها أبطأ تحت الحمل من التنفيذ القياسي الذي قد يكون مشكلة في الإنتاج.
الميزات التي تم تنفيذها حاليًا:
القيود والميزات المفقودة:
c:out ستعمل ولكن الطرفات الطرف الثالث مثل DisplayTag لن تعمل ، إلا إذا قمت بإعادة تنفيذها من أجل fauxjsp.classpath: بادئة لحل 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 s.TagLibDefinitionCache والتي تتأكد من قراءة taglibs مرة واحدة فقط أثناء كل طلب.JspParserFactory لمحلل جديد يوسع تاغفيل بشكل متكرر. لسوء الحظ ، لا يمكن حاليًا تحميل Taglibs بخلاف TagFiles. ومع ذلك ، من الممكن استخدام 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 القياسية المستخدمة من قبل خادم التطبيق ، لذلك يجب أن يعمل كل شيء خارج المربع.
إذا كنت بحاجة إلى المزيد من الوظائف ، فلا تنس إعلانها في 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 مسارًا للموارد أو ClassPath.
كما هو مكتوب من قبل ، لا يمكن 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 : تمديد defaultjspparserfactoryimpl وتجاوز طريقة 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 والناصات التي يتم استخدامها في مكان آخر كحمد مثل <،> ، {،} وما إلى ذلك في هذه الحالة ، حاول استخدام الهروب مثل u007b لـ {.
حالة الاستخدام هي أن TagFiles أو JSPs تشير إلى tagfiles أو JSPs الأخرى التي تتواجد في ClassPath (على سبيل المثال ، ملف جرة). لا تستخدم tagdir ولكن استخدم uri بدلاً من ذلك عند تضمين المورد ، على سبيل المثال:
<%@ taglib prefix = " cp " uri = " classpath:/tagfiles " %> ربما لاحظت أن JstlView و InternalViewResolver لا يعملون ولا يجد الربيع JSPs. تحت الغطاء ، يجب أن يملأ الربيع النموذج (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 > trimDirectiveWhiteSpaces مساحات servlet init init
< 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 لا يؤثر على تطبيقك.