2009-11-13 11 views
11

He estado entremezclando JSPs y Servlets en la aplicación web que estoy construyendo y estoy empezando a encontrar que mis JSPs más complejos terminan conteniendo una gran cantidad de código, lo que va en contra de todas las lecciones de MVC que tienen me han golpeado Sé que puedo hacer esto solo reenviándome al JSP, pero esto parece un truco estúpido.¿Es posible usar un JSP como plantilla para un servlet?

Lo que me gustaría hacer es usar un servlet para hacer el procesamiento y luego enviar un conjunto de valores al JSP para representar el HTML y devolver la respuesta. Algo a lo largo de las líneas de:

public class MyServlet extends HttpServlet { 
public void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws IOException { 

     // ... Do some processing 

     resp.getWriter.print(renderJSP("mypage.jsp", values)); 

    } 

} 

He estado hurgando la documentación de Sun y encontró esto: http://java.sun.com/developer/technicalArticles/javaserverpages/servlets_jsp/ Parece que el 2 Arquitectura JSP modelo es exactamente lo que quiero poner en práctica, pero no puedo encontrar un ejemplo de cómo uno puede configurar eso. Por razones técnicas, no puedo usar uno de los frameworks de plantillas más avanzados como Struts.

¿Es posible o es una causa perdida?

+2

"Por razones técnicas, no puedo usar uno de los frameworks de plantillas más avanzados como Struts". - Entonces, básicamente vas a volver a implementarlo solo para tu aplicación ... – Nate

+0

Sé que es una afirmación ingenua, pero realmente no parece que esté reinventando un marco completo. Solo busco la manera de unir dos tecnologías existentes en lo que, en mi opinión, es un caso de uso muy obvio. –

Respuesta

9

Coloque los objetos en la solicitud, reenvíe la solicitud a la página jsp y luego use los objetos en jsp para representar la respuesta.

En el servlet,

MyObject obj = ... //build somehow 
request.setAttribute("myObject", obj); 
RequestDispatcher rd = request.getRequestDispatcher("WEB-INF/jsp/my.jsp"); 
rd.forward(request, response); 

Si el resultado de JSP no debe acceder directamente desde una URL que debe ocultarlo dentro del directorio WEB-INF en el que sólo se puede acceder a través de la directiva hacia adelante.

continuación en su JSP que puede tener,

<% MyObject obj = (MyObject) request.getAttribute("myObject"); %> 

para recuperar el objeto y lo utilizó como sea necesario.

Como otros sugirieron, eventualmente sería una buena idea aprender a usar JSTL y tal vez un framework MVC como Spring MVC. El tutorial se puede encontrar here.

+0

¿Devuelve rd.forward un 302 al cliente o lo gestiona todo por el lado del servidor? Tal vez estoy confundiendo mi terminología. –

+0

@Sean Lynch: el directorio de reenvío es del lado del servidor. Es por eso que puede acceder a páginas JSP dentro del directorio WEB-INF utilizándolo. –

4

Describes el reenvío al JSP como un hack, pero realmente, eso es exactamente lo que hacen los frameworks MVC (Spring MVC y Struts, al menos).

El "modelo" son los atributos de solicitud, que el servlet rellena; entonces el JSP simplemente los recupera para mostrar. Puede envolverlo en un "ModelAndView" como lo hace Spring MVC, pero realmente se trata de eso.

Puede obtener más sofisticado en el JSP, por supuesto, analizar parámetros de solicitud, atributos de sesión o atributos de contexto de servlet ("global"). He descubierto, en general, que es más limpio permitir que el controlador frontal/servlet distribuya todos esos atributos de solicitud y que la página simplemente los extraiga. Si usa JSTL, la diferencia entre solicitud y sesión puede ser aún más borrosa.

+0

Absolutamente cierto. He hecho aproximadamente 4 aplicaciones web de buen tamaño con Spring, y definitivamente no es un hack, el servlet (o en primavera, el controlador) configura todos los datos para la vista, y el JSP contiene SOLAMENTE la lógica para mostrar los datos proporcionados a por el controlador. Funciona muy bien, y es realmente fácil de mantener, definitivamente quieres seguir esta ruta, no es un truco. – Zoidberg

5

coloque objetos Java en el Request/Response/Session y utilizar un javax.servlet.RequestDispatcher en el servlet, algo así:

RequestDispatcher dispatcher = request.getRequestDispatcher("/test.jsp"); 
dispatcher.forward(request,response); 

Un delantero es del lado del servidor y el servlet de destino/JSP recibe los mismos objetos de solicitud/respuesta como el servlet/JSP original. Por lo tanto, puede pasar datos entre ellos usando request.setAttribute().

La otra opción es utilizar response.sendRedirect(String location) que es del lado del cliente (este método envía una respuesta de redirección temporal para el cliente) por lo que la URL de la ubicación recibe una nueva petición del cliente, y la única manera de pasar datos es a través de la sesión o con parámetros web (url? name = value).

Esto es básicamente lo que hacen los frameworks MVC (y no, no es un hack).

+0

¿dispatcher.forward() realmente envía un 302 al cliente o lo maneja todo del lado del servidor? Creo que puedo estar sobrecargando mi terminología HTML. –

+0

@Sean, todo del lado del servidor. –

+0

He actualizado mi respuesta para cubrir ambas mayúsculas y minúsculas (lado del servidor y lado del cliente) –

Cuestiones relacionadas