Funzionalità nascoste di JSP / Servlet

Sono interessato ai tuoi trucchi ecc. Usati quando scrivi JSP / Servlet. Inizierò:

In qualche modo ho scoperto di recente come è ansible includere l’output di un tag JSP in un attributo di un altro tag:

        

Nota: trovo difficile pensare a “funzioni nascoste” per JSP / Servlet. Secondo me, le “migliori pratiche” sono una formulazione migliore e posso pensare a qualcuno di loro. Dipende anche molto dalla tua esperienza con JSP / Servlet. Dopo anni di sviluppo non vedi più quelle “caratteristiche nascoste”. In ogni caso, elencherò alcune di quelle piccole “migliori pratiche” di cui ho scoperto negli anni che molti principianti non ne sono pienamente consapevoli. Questi sarebbero classificati come “elementi nascosti” negli occhi di molti principianti. Comunque, ecco la lista 🙂


Nascondi le pagine JSP dall’accesso diretto

Collocando i file JSP nella cartella /WEB-INF si nascondono effettivamente dall’accesso diretto, ad esempio http://example.com/contextname/WEB-INF/page.jsp . Ciò comporterà un 404 . Puoi quindi accedervi solo da un RequestDispatcher in Servlet o usando jsp:include .


Richiesta di preelaborazione per JSP

Molti sono a conoscenza del doPost() di Servlet per post- elaborare una richiesta (un modulo di invio), ma la maggior parte non sa che è ansible utilizzare il metodo doGet() di Servlet per pre- elaborare una richiesta per un JSP. Per esempio:

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List items = itemDAO.list(); request.setAttribute("items", items); request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response); } 

che viene utilizzato per precaricare alcuni dati tabulari che devono essere visualizzati con l’aiuto di JSTL’s c:forEach :

  
${item.id}${item.name}

Mappare tale servlet su un url-pattern di url-pattern di /page (o /page/* ) e invocare http://example.com/contextname/page tramite la barra degli indirizzi del browser o un semplice collegamento di vanilla per eseguirlo. Vedi anche doGet e doPost in Servlet .


Dynamic include

Puoi usare EL in jsp:include :

  

bean.getPage() può solo restituire un nome di pagina valido.


EL può accedere a qualsiasi getter

EL non per sé richiede che l’object a cui si accede sia un Javabean degno di fiducia. La presenza di un metodo no-arg con prefisso get o is è più che sufficiente per accedervi in ​​EL. Per esempio:

 ${bean['class'].name} 

Questo restituisce il valore di bean.getClass().getName() cui il metodo getClass() è effettivamente ereditato da Object#getClass() . Si noti che la class viene specificata usando “brace notation” [] per i motivi menzionati qui instanceof check in linguaggio di espressione EL .

 ${pageContext.session.id} 

Questo restituisce il valore di pageContext.getSession().getId() che è utile in ao Può un’applet comunicare con un’istanza di un servlet .

 ${pageContext.request.contextPath} 

Questo restituisce il valore di pageContext.getRequest().getContextPath() che è utile in ao Come utilizzare i percorsi relativi senza includere il nome della root di contesto?


EL può accedere anche a Maps

La seguente notazione EL

 ${bean.map.foo} 

risolve in bean.getMap().get("foo") . Se la chiave Map contiene un punto, puoi usare la “notazione brace” [] con una chiave quotata:

 ${bean.map['foo.bar']} 

che risolve in bean.getMap().get("foo.bar") . Se si desidera una chiave dynamic, utilizzare anche la notazione delle controventi, ma non quotata:

 ${bean.map[otherbean.key]} 

che risolve in bean.getMap().get(otherbean.getKey()) .


Iterare su Mappa con JSTL

Puoi anche usare c:forEach per iterare su una Map . Ogni iterazione dà un Map.Entry che a sua volta ha metodi getKey() e getValue() (in modo da poterlo accedere in EL solo da ${entry.key} e ${entry.value} ). Esempio:

  Key: ${entry.key}, Value: ${entry.value} 

Vedi anche es. Debugging con jstl – come esattamente?


Ottieni la data corrente in JSP

Puoi ottenere la data corrente con jsp:useBean e formattarlo con l’aiuto di JSTL fmt:formatDate

  ... 

Copyright ©

Questa stampa (come ora) come segue: “Copyright © 2010”.


URL facili e amichevoli

Un modo semplice per avere URL amichevoli è quello di utilizzare HttpServletRequest#getPathInfo() e JSP nascosti in /WEB-INF :

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF" + request.getPathInfo() + ".jsp").forward(request, response); } 

Se mappate questo servlet su per esempio /pages/* , quindi una richiesta su http://example.com/contextname/pages/foo/bar visualizzerà in modo efficace /WEB-INF/foo/bar.jsp . Puoi ottenere un ulteriore passo dividendo il pathinfo su / e prendi solo la prima parte come URL della pagina JSP e il resto come “business actions” (lascia che il servlet agisca come un controller di pagina ). Vedi anche es. Modelli di progettazione applicazioni basate sul web .


Mostra di nuovo l’input dell’utente usando ${param}

L’object EL implicito ${param} che fa riferimento a HttpServletRequest#getParameterMap() può essere utilizzato per visualizzare nuovamente l’input dell’utente dopo l’invio di un modulo in JSP:

  

Questo in pratica fa lo stesso di request.getParameterMap().get("foo") . Vedi anche ad esempio Come posso mantenere i valori del campo modulo HTML in JSP dopo aver inviato il modulo a Servlet?
Non dimenticare di impedire da XSS! Vedi il capitolo seguente.


JSTL per prevenire XSS

Per impedire il tuo sito da XSS , tutto ciò che devi fare è (ri) visualizzare i dati controllati dall’utente usando JSTL fn:escapeXml o c:out .

 


Alternando

righe con LoopTagStatus

L’attributo varStatus di JSTL c:forEach fornisce un LoopTagStatus che a sua volta ha diversi metodi getter (che possono essere utilizzati in EL!). Quindi, per verificare la presenza di righe pari, controlla se loop.getIndex() % 2 == 0 :

  ... 

che effettivamente finirà dentro

 ............ ... 

Usa i CSS per dare loro un diverso colore di sfondo.

 tr.even { background: #eee; } tr.odd { background: #ddd; } 

Compilare una stringa commseparata da List / Array con LoopTagStatus :

Un altro utile metodo LoopTagStatus è isLast() :

  ${item}${!loop.last ? ', ' : ''}  

Il che si traduce in qualcosa come item1, item2, item3 .


Funzioni EL

È ansible dichiarare metodi public static utilità public static come funzioni EL (come le funzioni JSTL ) in modo che sia ansible utilizzarli in EL. Per esempio

 package com.example; public final class Functions { private Functions() {} public static boolean matches(String string, String pattern) { return string.matches(pattern); } } 

con /WEB-INF/functions.tld che sembrano i seguenti:

 < ?xml version="1.0" encoding="UTF-8" ?>  1.0 Custom_Functions http://example.com/functions  matches com.example.Functions boolean matches(java.lang.String, java.lang.String)   

che può essere usato come

 < %@taglib uri="http://example.com/functions" prefix="f" %>  ...  

Ottieni l’URL della richiesta originale e la stringa di query

Se il JSP è stato inoltrato, puoi ottenere l’URL di richiesta originale di,

 ${requestScope['javax.servlet.forward.request_uri']} 

e la stringa di richiesta della richiesta originale di,

 ${requestScope['javax.servlet.forward.query_string']} 

Era così lontano. Forse aggiungerò qualche altro prima o poi.