JavaServer Pages (JSP) és una tecnologia que permet als desenvolupadors de pàgines web, generar respostes dinàmicament a peticions HTTP. La tecnologia permet que codi Java i certes accions predefinides siguin incrustades en un context estàtic.

Infotaula de format de fitxerJavaServer Pages
Tipusformat de fitxer, template processor (en) Tradueix i especificació tècnica Modifica el valor a Wikidata
Extensiójsp Modifica el valor a Wikidata
MIMEapplication/jsp Modifica el valor a Wikidata
DesenvolupadorFundació Eclipse Modifica el valor a Wikidata
Més informació
Stack ExchangeEtiqueta Modifica el valor a Wikidata
PRONOMx-fmt/160 Modifica el valor a Wikidata
Lloc webprojects.eclipse.org… Modifica el valor a Wikidata

La sintaxi de JSP incorpora tags XML addicionals, anomenats accions de JSP, per ser usats per invocar altres funcions. Addicionalment, la tecnologia permet la creació de llibreries d'etiquetes que actuen com extensions de l'estàndard d'etiquetes HTML o XML. Les llibreries d'etiquetes aporten una forma multiplataforma d'ampliar les capacitats d'un servidor web.

Els JSPs són compilats en Servlets per un compilador JSP. Aquest pot generar un servlet o generar bytecode directament.

JSP i Servlets modifica

Des del punt de vista de l'arquitectura, els JSP poden ser vistos com una abstracció, d'alt nivell, de servlets implementada com una extensió de l'API Servlet 2.1. Ambdues tecnologies van ser inicialment desenvolupades per Sun Microsystems. Començant per la versió 1.2 de l'especificació de JSP, JavaServer Pages van ser desenvolupats sota la Java Community Process. La JSR 53 defineix tant les especificacions 1.2 com la 2.3 i JSR 152 defineix la JSP 2.0. El maig de 2006 l'especificació 2.1 va ser llençada sota la JSR 245 com a part de Java EE 5.

Sintaxi JSP modifica

Una pàgina JSP està dividida en les parts següents:

  • Dades estàtiques, com ara HTML o XML (no es recomana que els JSP generin respostes binàries)
  • Directives JSP, per exemple, els includes
  • Elements de scripting i variables
  • Accions JSP
  • Tags personalitzats

Directives JSP modifica

Les directives JSP controlen la manera com el compilador JSP genera el servlet. Existeixen les directives següents:

include
la directiva include informa el compilador JSP de com incloure un fitxer sencer dintre del fitxer actual. És com si els continguts del fitxer inclòs foren enganxats directament al fitxer incloent. Els fitxers inclosos acostumen a tenir l'extensió jspf (fragment de jsp).
<%@ include file="algunfitxer.jspf" %> 
page
hi ha diverses opcions per aquesta directiva
import
Els resultats d'una crida a import són inserits al fitxer resultant.
contentType
indica el tipus de contingut en la resposta
errorPage
indica la pàgina que serà mostrada si hi ha una excepció durant el processament de la petició HTTP.
isErrorPage
si és cert, vol dir que l'actual plana és una plana d'error
isThreadSafe
indica si el servlet resultant és un fil segur.
<%@ page import="java.util.*" %> //import d'exemple
<%@ page contentType="text/html" %> //exemple de contentType
<%@ page isErrorPage=false %> //exemple de pàgina que no és d'error
<%@ page isThreadSafe=true %> //exemple de JSP que és un fil segur
Nota: només la directiva "import" pot ser usada múltiples vegades al mateix jsp.
taglib
la directiva taglib indica que serà usada una llibreria de tags JSP. La directiva requereix que s'especifiqui un prefix (concepte proper al d'un espai de noms en C++) i la URI per la descripció de la llibreria de tags.
<%@ taglib prefix="unprefix" uri="taglib/mytag.tld" %>

Objectes i elements de scripting de JSP modifica

Objectes implícits JSP modifica

Les següents instàncies, declarades i inicialitzades pel contenidor JSP, poden ser referenciades pel programador:

out De la classe JSPWriter i usada per enviar l'stream (fitxer no acabat de generar) de resposta a través del socket

page Objecte que referencia la pròpia pàgina

pageContext Conté dades associades a tota la pàgina. Una pàgina HTML pot haver passat per diversos JSPs. Instància de PageContext

request Proveeix informació sobre la invocació. Instància d'HttpServletRequest

response L'objecte HttpServletResponse

session L'objecte HttpServletSession, que gestiona dades sobre la sessió d'usuari

config Conté dades sobre la configuració del servlet

application Dades compartides per tots els JSPs i servlets del contenidor

exception Excepcions no capturades

Elements de scripting modifica

Hi ha diversos tipus d'elements de scripting que permeten al codi java inserir-los directament a dintre del Serlvet

  • Un tag de declaració col·loca una definició d'una variable dintre del cos de la classe del Servlet. Les dades estàtiques també hi poden ser definides.
<%! int variableDeclarada = 1; %>
  • Un tag scriptlet col·loca el codi que conté dintre del métode _jspService() de la classe del Servlet.
<% int variableLocal = 1;
out.println(variableLocal); %>
  • Un tag expression col·loca una expressió a ser avaluada dintre la classe del Servlet. Les expressions no haurien d'acabar amb punt i coma.
<%= "dada " + 1%>
  • També existeix el tag següent per afegir-hi comentaris:
<%-- afegeix els comentaris aquí --%>

Actions de JSP modifica

Les actions de JSP són tags XML que invoquen funcionalitats preincorporades del servidor web i que són executades en temps d'execució. Algunes són estàndards i d'altres personalitzades. Les estàndards són:

jsp:include
Similar al concepte de subrutina, el servlet de Java delega temporalment la petició i respon cap al JSP específic. Un cop finalitzada l'execució, el control retorna a l'actual JSP. Amb això, el codi JSP serà compartit entre d'altres JSPs, evitant així duplicacions.
jsp:param
Pot ser usat a dintre d'un bloc jsp:include, jsp:forward o jsp:params. Especifica un paràmetre que serà afegit al paràmetres de l'actual crida.
jsp:forward
Usat per delegar la petició i la resposta cap a un altre JSP, servlet o altre tipus de pàgina web. El control mai no retornarà al JSP cridant.
jsp:plugin
versions antigues de Netscape Navigator i Internet Explorer usaven diferents tags per incrustar un applet. Aquesta action genera els tags necessaris en funció de cada navegador per incloure-hi un applet.
jsp:fallback
Contingut mostrat si el navegador no suporta applets.
jsp:getProperty
Obté una propietat del JavaBean específic.
jsp:setProperty
Modifica una propietat del JavaBean específic.
jsp:useBean
Crea o reusa un JavaBean disponible pel JSP.

Exemples d'etiquetes modifica

jsp:include modifica

<html>
<head></head>
<body>
<jsp:include page="comu.jsp" >
<jsp:param name="extraparam" value="unvalor"/>
</jsp:include>
nom:<%=request.getParameter("extraparam")%>
</body></html>

jsp:forward modifica

<jsp:forward page="subplana.jsp" >
<jsp:param name="redirigitDe" value="aquest.jsp"/>
</jsp:forward>

En aquest exemple de redirecció, la petició és enviada a "subplana.jsp". El control de la petició no retorna a aquesta plana.

jsp:plugin modifica

<jsp:plugin type=applet height="100%" width="100%"
archive="unjar.jar,unaltrejar.jar"
codebase="/applets"
code="com.foo.UnApplet" >
<jsp:params>
<jsp:param name="enableDebug" value="true"/>
</jsp:params>
<jsp:fallback>
El teu navegador no suporta applets.
</jsp:fallback>
</jsp:plugin>

El plugin d'exemple il·lustra una manera uniforme d'incrustar applets en <html> dintre d'una plana web. Abans de l'arribada de l'etiqueta <OBJECT>, no hi havia una manera comuna d'incrustar applets. Actualment, l'etiqueta jsp:plugin no permet cridar applets dinàmicament. per exemple, jsp:params no pot ser usada per un applet de gràfiques que requereix els punts que haurien de ser passats com a paràmetres llevat que el nombre de punts sigui sempre el mateix. No es pot, per exemple, fer un bucle al voltant d'un ResultSet per crear les etiquetes jsp:param. Cada etiqueta jsp:param ha de ser codificada manualment. Tanmateix, cadascuna d'aquestes etiquetes jsp:param poden tenir noms i/o valors dinàmics.

jsp:useBean modifica

<jsp:useBean id="unBean" class="com.foo.UnBean" scope="request"/>
<jsp:getProperty name="unBean" property="darrerCanviat"/>
<jsp:setProperty name="unBean" property="darrerCanviat" value="<%= new Date()%>"/>

L'àmbit (scope) pot ser request, page, session o application. Té els significats següents:

request (petició)
l'atribut és disponible durant el cicle de vida de la petició. Un cop la petició ha estat processada per tots by all els JSPs, l'atribut serà desreferenciat.
page (plana)
l'atribut és disponible només per la plana actual.
session (sessió)
l'atribut és accessible al llarg del cicle de vida de la sessió d'usuari.
application (aplicació)
l'atribut és accessible per cada instància i mai no és desreferenciat. Igual com una variable global.

L'exemple de dalt usa un Bean Manager per crear una instància de la classe com.foo.UnBean i guarda la instància a l'atribut anomenat "unBean". L'atribut serà accessible durant el cicle de vida de la petició. Pot ser compratit per tots els JSPs que hagin estat inclosos o reenviats del JSP principal que primer ha rebut la petició.

Etiquetes estàndards de llibreries JSP (JSTL) modifica

En addició a les actions predefinides de JSP, els desenvolupadors poden afegir les seves actions personalitzades usant l'API d'extensió d'etiquetes de JSP. Els desenvolupadors escriuen una classe Java que implementa una de les interfícies d'etiquetes i proveeix un fitxer XML de descripció de llibreria d'etiquetes que especifica les etiquetes i les classes java que implementen les etiquetes.

Partint del JSP següent:

<%@ taglib uri="unallibreriadetiquetes.tld" prefix="unprefix" %>
...
<unprefix:unaaction> <%-- etiqueta inicial %>
...
</unprefix:unaaction> <%-- etiqueta final %>
...

El compilador JSP carregarà el fitxer XML unallibreriadetiquetes.tld i veurà que el tag 'unaaction' és implementat per la classe java 'UnaEtiquetaAction'. El primer cop que el tag és usat al fitxer, crearà una instància d''UnaEtiqueaAction'. Llavors, cada cop que l'etiqueta torna a ser usada, invocarà el métode doStartTag() al moment que troba l'etiqueta inicial. Mira el resultat de l'etiqueta de partida i determina com processar el cos de l'etiqueta. El cos és el text entre l'etiqueta inicial i l'etiqueta final. El métode doStartTag() hauria de tornar un dels següents resultats:

SKIP_BODY
El cos de dintre del tag no és processat.
EVAL_BODY_INCLUDE
Avalua el cos de l'etiqueta.
EVAL_BODY_TAG
Avalua el cos de l'etiqueta i posa el resultat en un flux (emmagatzemat al cos de l'actual propietat de l'etiqueta).

Nota: Si l'etiqueta hereta de la classe BodyTagSupport, el métode doAfterBody() serà crida quan el cos hagi estat processat just abans de cridar el doEndTag(). Aquest métode és usat per implementar constructors repetitius.

Quan troba l'etiqueta de final, invoca el métode doEndTag(). El métode hauria de retornar un dels valors següents:

EVAL_PAGE
Això indica si la resta del fitxer hauria de ser processada.
SKIP_PAGE
Indica que no hi ha procés addicional a realitzar. El control desapareix de la plana JSP. Això és el que és usat per les actions redireccionants.

L'etiqueta unaaction de dalt hauria de tenir una classe implementadora que hauria de ser com ara:

public class UnaEtiquetaAction extends TagSupport {
//Llença totes les variables d'instància.
public void release() {...}
public UnaEtiquetaAction() { ... }
//cridat pel métode inicial
public int doStartTag() { ... }
//cridat pel métode final
public int doEndTag(){ ... }
}

Afegeix la descripció de l'etiqueta del cos del codi.

Internacionalització modifica

La Internacionalització en JSP és portada a terme de la mateixa manera que en aplicacions Java normals, és a dir, usant Resource Bundles.

JSP 2.0 modifica

La nova versió de l'especificació de JSP inclou noves funcionalitats que impliquen millores per la productivitat del programador:

Hola, ${param.visitant} <%-- el mateix que: Hola, <%=request.getParameter("visitant")%> --%>

Paradigma Model-vista-controlador modifica

Sun recomana que el patró de disseny Model-vista-controlador sigui usat als fitxers JSP per separar la presentació del processament de la petició i l'emmagatzemamanet de dades. Ni els servlets normals ni els JSP són usats per processar la petició. Després que hagi finalitzat el procés, el control torna al JSP, que és usat només per crear la sortida. Hi ha múltiples plataformes basades en el patró MVC per capes web (com ara Barracuda, Apache Struts o Spring framework).

Exemple modifica

Independentment de si el compilador JSP genera codi Java per un servlet o emet el bytecode directament, és de gran ajuda entendre com el compilador JSP transforma la pàgina en un servlet de Java. per exemple, considerant JSP següent i el seu Servlet generat.

JSP d'entrada

 <%@ page errorPage="derror.jsp" %>
 <%@ page import="com.foo.bar" %>

 <html>
 <head>
 <%! int variableServidor = 1;%>
 ...
 <% int variableApiladaLocal = 1; %>
 <table>
 <tr><td><%= "dades expandides en línia " + 1%></td></tr>
 ...

Servlet resultant

 package jsp_servlet;
 import java.util.*;
 import java.io.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
 import javax.servlet.jsp.*;
 import javax.servlet.jsp.tagext.*;

 import com.foo.bar; // importat com un resultat de <%@ page import="com.foo.bar" %>
 import ...

 class _unservlet implements javax.servlet.Servlet, javax.servlet.jsp.HttpJspPage {
 //inserit com un
 //resultat de <%! int variableSevidor = 1;%>
 int variableSevidor = 1;
 ...

 public void _jspService(javax.servlet.http.HttpServletRequest request,
 javax.servlet.http.HttpServletResponse response)
 throws javax.servlet.ServletException,
 java.io.IOException
 {
 javax.servlet.ServletConfig config = ...;//carrega la configuració del servlet
 Object plana = this;
 PageContext contextPlana = ...;// carrega el context de la plana per aquesta petició
 javax.servlet.jsp.JspWriter out = pageContext.getOut();
 HttpSession session = request.getSession(true);
 try {
 out.print("<html>\r\n");
 out.print("<head>\r\n");
 ...
 //from <% int variableApiladaLocal = 1; %>
 int variableApiladaLocal = 1;
 ...
 out.print("<table>\r\n");
 out.print(" <tr><td>");
 //nota, aStringOBlank() converteix l'expressió en un string o si l'expressió 
 // resulta un null, usa un string buit.
 //de <%= "dades expandides en línia " + 1%>
 out.print(aStringOBlank("dades expandides en línia " + 1));
 out.print(" </td></tr>\r\n");
 ...
 } catch (Exception _excepcio) {
 //fa net i redirigeix cap a la plana d'error <%@ page errorPage="derror.jsp" %>
 }
 }
 }

Vegeu també modifica

Bibliografia complementària modifica

Enllaços externs modifica