Alcance de JSP: UseBean
-
13-09-2019 - |
Pregunta
home.jsp
<jsp:useBean id="username" class="java.lang.String" scope="application"/>
<%
username="Jitendra";
%>
<jsp:include page="include.jsp"/>
incluir.jsp
<%=username%>
Esto da un error que decir "nombre de usuario" está indefinido en incluir.jsp, a pesar de que el alcance del bean es aplicación ...
Solución
En cuanto a su problema, cualquier cosa que declare localmente utilizando los guionistas antiguos es no vinculado con un jsp:useBean
. Además, declarar una variable de scriptlet local es no Visible en las páginas incluidas, debe ponerlas explícitamente en al menos el alcance de la solicitud. Como usar scriptlets es un mala práctica. Recomiendo olvidarlo en absoluto.
En su caso específico, simplemente cree un real Java Bean para mantener los datos. Es decir, una clase con un constructor predeterminado (implícito) y propiedades privadas que están expuestas por getters/setters públicos. Aquí hay un ejemplo básico:
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Luego puede usar una clase de servlet para solicitudes de preprocesamiento. Puedes usar servlet's doGet()
Método para esto.
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
User user = new User();
user.setName("Jitendra");
request.setAttribute("user", user); // Store in request scope.
request.getRequestDispatcher("/WEB-INF/show.jsp").forward(request, response);
}
Asigna este servlet en web.xml
en una url-pattern
de por ejemplo /show
. Este servlet debe ser accesible por http://example.com/context/show
y es doGet()
sería ejecutado de inmediato.
Luego cambie/cree el archivo JSP show.jsp
que colocas en /WEB-INF
para evitar el acceso directo (para que los clientes no puedan acceder a él http://example.com/context/show.jsp
pero están "obligados" a llamar al servlet) con la siguiente línea:
<p>User name: ${user.name}</p>
los ${user}
se refiere al objeto que está asociado con cualquier tecla de atributo de solicitud/sesión/aplicación user
. Esto hace detrás de escena jspContext.findAttribute("user")
. Como el regreso User
instancia conforma la especificación de Javabean, la ${user.name}
invocará el getName()
método en el User
instancia y el EL mostrará su resultado.
Oh, debería agregar, tú lo haces no necesitar jsp:useBean
Para esto, ya que el servlet ya ha creado y coloca el frijol deseado en el alcance.
Dicho esto, recomiendo comenzar con un tutorial/libro JSP/Servlet decente. Ejemplos:
- Sun Java EE Tutorial Parte II Capítulos 1-8.
- CoreServlets.com JSP/Servlet Tutorials.
- PRIMERO SERVLETS Y LIBRO JSP.
Espero que esto ayude.
Otros consejos
Tu código es "malvado" porque un java.lang.String
No es realmente un frijol. Significativamente, no tiene un método "establecido" para cambiar su texto (que es intencional, está destinado a ser inmutable).
La forma en que accede a los frijoles es declarar uno y luego usar sus propiedades (es decir, los nombres detrás de los métodos get () y set ()) para cambiarlo. No puede cambiar directamente la instancia real de Bean, solo sus valores.
En Tomcat 6, home.jsp
se traduce al código de servlet:
java.lang.String username = null;
synchronized (application) {
username = (java.lang.String) _jspx_page_context.getAttribute("username",
PageContext.APPLICATION_SCOPE);
if (username == null){
username = new java.lang.String();
_jspx_page_context.setAttribute("username", username,
PageContext.APPLICATION_SCOPE);
}
}
username="Jitendra";
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response,
"include.jsp", out, false);
Aunque el comportamiento es el mismo, el código exacto generado depende de la implementación del servidor de aplicaciones.
El alcance del local username
La variable no se extiende al servlet que se generará desde include.jsp
. No está configurando el valor "jitendra" en el alcance de la aplicación, solo establece el valor de la variable local.
Como otros han señalado, una cuerda inmutable no es un frijol muy bueno.