FAUXJSP est une implémentation Java Server Pages (JSP) pour une utilisation pendant le développement: les JSP sont interprétés paresseusement (au lieu de compilés) qui réduisent les temps de démarrage de l'application et de la page, accélère la recharge de la page lorsque JSPS change et ne nécessite pas de redémarrages de serveur. Mieux utilisé lors du développement, peut être utilisé dans la production également si la conformité des spécifications n'est pas critique.
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 >Les versions ci-dessous (et y compris) 1.2.3 sont dans Maven Central:
pom.xml:
< dependency >
< groupId >com.github.ggeorgovassilis</ groupId >
< artifactId >fauxjsp</ artifactId >
< version >1.2.3</ version >
</ dependency >Les versions après 1.2.3 nécessitent un référentiel:
< 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 (non libéré sur Maven Central)
1.2.3
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
trimDirectiveWhiteSpaces , c:set le contenu corporel implémenté0.0.9
0,0,5 snapshot
0,0,4 snapshot
Oui. En bref:
Pour la plupart d'entre vous, les mecs cool JSP sont horriblement hors de mode, mais j'aime l'utiliser pour le prototypage et les tagfiles. Malheureusement et étonnamment, peu de gens connaissent les tagfiles bien qu'ils soient une technique bien soutenue et mature pour créer des composants d'interface utilisateur Web réutilisables.
Le démarrage d'une application JSP-lourde est lent car d'autres implémentations JSP compileront d'abord JSP et TagFiles en code source Java, puis vers le code d'octets puis vers le code machine. De plus, lors des modifications des fichiers JSP, l'ensemble du processus doit être répété, ce qui ralentit le développement. À un moment donné, vous obtiendrez même des erreurs de compilation inexplicables, des erreurs de chargement de classe, vous manquer de mémoire et les goûts, vous saurez que vous en avez assez et vous redémarrez le conteneur servlet.
FAUXJSP implémente un interprète JSP et un servlet JSP qui lit les fichiers JSP et les interprète à la volée, en sautant complètement la compilation. Cela apporte le bénéfice des rechargements de pages instantanés, des heures de début rapide et de la robustesse (pas de chargement de classe de classe!) Mais, évidemment, les pages JSP générées sont plus lentes que l'implémentation standard qui peut être un problème de production.
Caractéristiques actuellement implémentées:
Contraintes et fonctionnalités manquantes:
c:out fonctionneront, mais des tags tiers tels que DisplayTag ne le feront pas, à moins que vous ne les réimplémentez pour FAUXJSP.classpath: Prefix pour résoudre Tagfiles et JSPS dans le ClassPath. Ne prend pas en charge le moyen standard de résoudre les ressources de chemin de classe.Parce que:
Prime:
< dependency >
< groupId >com.github.ggeorgovassilis</ groupId >
< artifactId >fauxjsp</ artifactId >
< version >1.1.0</ version >
</ dependency >OU
Télécharger des sources et compiler
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 sont étendus comme provided car le conteneur servlet ou l'application Web contribuent ces dépendances
log4j, les haricots sont étendus comme provided car ils sont facultatifs
Commons-Lang est portée comme compile car il est obligatoire
Pour les détails à jour, veuillez consulter le POM.
Veuillez soumettre un rapport de bogue lorsque vous trouvez un bogue ou demandez une fonctionnalité implémentée. Maintenant, dans une vraie vie (projet), vous êtes probablement sur un horaire serré et ne voulez pas attendre une solution officielle. FAUXJSP est modulaire et facilement extensible. Jetez donc un œil au prochain chapitre sur l'architecture de FAUXJSP qui vous aidera à comprendre les différents composants plutôt simples, comment les modifier et implémenter de nouvelles fonctionnalités.
JspServlet accepte une demande HTTP et rend le JSP demandé. La séquence entière ressemble à ceci:
ServletRequestjspbase (voir Javadocs pour JspServlet ) pour le fichier JSPJspParserFactory pour un nouveau JspParserJspParser qui l'analyse, résout récursivement des dépendances et renvoie un JspPageRenderSessionJspRendererFactory pour un nouveau JspRendererJspPage et RenderSession au JspRenderer qui le rend JspServlet a un tas de méthodes protégées qui construisent les différentes usines mentionnées précédemment. Si vous avez besoin de configurations spéciales, la remplacement de ces méthodes de constructeur vous permet de spécifier vos propres usines qui peuvent renvoyer des implémentations modifiées ou complètement nouvelles de Analyrs et Rendeurs.
Le JspParser et plus précisément sa seule implémentation JspParserImpl reçoit un emplacement de fichier JSP, le rend et renvoie les résultats analysés. En détails:
JspParser.parse(path) reçoit le chemin du fichier jsp à rendreResourceResolver (le JspParserFactory définit celui-ci) qui renvoie le fichier JSP en tant que chaîne.JspNode s.TagLibDefinitionCache ce qui garantit que les taglibs ne sont lus qu'une seule fois pendant chaque demande.JspParserFactory pour un nouvel analyseur qui analyse récursivement le tagfile. Malheureusement, il n'est actuellement pas possible de charger des taglibs autres que TagFiles. Cependant, il est possible d'utiliser des tagobs manquants en fournissant une implémentation spéciale pour FAUXJSP vous-même. Selon le Taglib, vous essayez de simuler cela peut ou non être une tâche à forte intensité de main-d'œuvre. Pour quelques exemples, jetez un œil aux classes JstlCoreTaglib* . L'usine DefaultJspParserFactoryImpl les définit dans un espace de noms spécial, un pour chaque méthode 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 délégue à l'implémentation standard de la fonction JSTL utilisée par le serveur d'applications, donc tout devrait fonctionner hors de la boîte.
Si vous avez besoin de plus de fonctions de fonction, n'oubliez pas de les déclarer dans 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 peut être un chemin de ressource de serveur ou de classe de classe.
Comme écrit précédemment, FAUXJSP ne peut pas utiliser Taglibs et doit les imiter à la place, ce qui signifie que quelqu'un doit programmer cette émulation.
Étape 1 : Créez l'implémentation Taglib. Il suffit de trouver l'un des Taglibs déjà simulés comme JStlCoretaglibout et de le copier et de le coller
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 ));
}
}
Étape 2 : Extendez defaultjspparserfactoryIMP et remplacez la méthode setup . Ici, vous pouvez enregistrer le nouveau Taglib que vous avez écrit
public class MyJspParserFactory extends DefaultJspParserFactoryImpl {
protected void setup ( JspParserImpl parser ) {
super . setup ( parser );
parser . registerTaglibDefinition (
"http://mytaglibs/add" ,
new TaglibAdd ());
}
} Étape 3 : étendez JSPServlet et remplacez getJspParserFactory afin qu'il renvoie votre nouvelle usine
public class MyJspServlet extends JspServlet {
protected JspParserFactory getJspParserFactory ( ServletConfig config ){
ResourceResolver location = new ServletResourceResolver ( jspBase , getServletContext ());
DefaultJspParserFactoryImpl factory = new MyJspParserFactory ( location );
return factory ;
}
}Étape 4 : Utilisez votre nouvelle implémentation JSPServlet dans web.xml au lieu de l'ancien 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 se connecte via LOG4J, s'il est trouvé sur le chemin de classe, sinon via le mécanisme de journalisation JDK standard. Une configuration de journalisation possible dans log4j.properties pourrait ressembler à ceci:
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
Les scripts sont implémentés avec l'utilisation de beanshell, donc certains écarts par rapport au comportement standard des scripts sont à prévoir. Les scripts ne seront pas activés à moins que l'interpréteur de haricots ne soit trouvé sur le chemin de classe. Les limitations actuelles sont:
Idéalement, vous trouverez un moyen qui fonctionne à la fois dans l'environnement JSP de production ainsi qu'avec FAUXJSP. Un exemple serait le cas de Varargs utilisé dans les scripts dont nous avons parlé plus tôt. L'analyseur FAUXJSP est susceptible d'être confus par des chaînes qui apparaissent dans les expressions EL et les scripts qui sont utilisées ailleurs comme des délimiteurs comme <,>, {,} etc. Dans ce cas, essayez d'utiliser des évasions comme u007b pour {.
Le cas d'utilisation est que vos tagfiles ou JSPS font référence à d'autres tagfiles ou JSP qui résident dans le CLASSPATH (par exemple un fichier JAR). N'utilisez pas tagdir mais utilisez uri à la place lorsque vous incluez la ressource, par exemple:
<%@ taglib prefix = " cp " uri = " classpath:/tagfiles " %> Vous avez probablement remarqué que le JstlView et InternalViewResolver ne fonctionnent pas et que Spring ne trouve pas votre JSPS. Sous le capot, le ressort doit remplir le modèle (le M en MVC) dans les attributs HttpServletRequest et transmettre la demande à FAUXJSP, mais ce n'est pas le cas. Nous pouvons implémenter un simple mécanisme de transfert comme tel:
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 );
}
}La présence simple de ces deux composants dans le contexte de l'application Web devrait être suffisante pour qu'ils soient ramassés et activés.
JspServlet peut être configuré pour mettre en cache JSPS analysé. Il s'agit d'une amélioration mineure des performances car le rendu normalement est plus lent que l'analyse.
< 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 un paramètre de servlet 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 > Caractéristiques à venir à proximité Dans le futur:
Science-fiction (choses que j'ai une idée difficile de mettre en œuvre mais que j'ai besoin de s'entraîner et ne viennent peut-être jamais):
Ross Studtman pour les tutoriels JSP qui a inspiré de nombreux grands tests unitaires.
FAUXJSP est disponible sous le GPL. Étant donné que FAUXJSP est un outil de développement, vous ne le déployez normalement pas avec vos binaires d'application en production, donc l'aspect "non commercial" du GPL n'affecte pas votre application.