views:

86

answers:

3

I've been intermixing JSPs and Servlets in the web app I'm building and I'm starting to find that my more complex JSPs end up containing a lot of code, which flies in the face of all the MVC lessons that have been pounded into me. I know I can do this by just forwarding to the JSP, but this seems like a stupid hack.

What I'd like to do is use a servlet to do processing and then send a set of values to the JSP to render the HTML and return the response. Something along the lines of:

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

         // ... Do some processing

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

    }

}

I've been poking around Sun's documentation and found this: http://java.sun.com/developer/technicalArticles/javaserverpages/servlets_jsp/ It seems like the JSP Model 2 architecture is exactly what I want to implement, but I cannot find an example of how one can set that up. For technical reasons, I cannot use one of the more advanced template frameworks like Struts.

Is this possible or a lost cause?

+4  A: 

You describe forwarding to the JSP as a hack, but really, that's exactly what the MVC frameworks do (Spring MVC and Struts, at least).

The "model" is the request attributes, which the servlet populates; then the JSP just retrieves them to show. You can wrap that in a "ModelAndView" like Spring MVC does, but it's really about it.

You can get more sophisticated on the JSP, of course, parsing request parameters, session attributes or servlet context ("global") attributes. I've found, in general, it's cleaner to let the front controller/servlet marshall all those into request attributes and have the page just pull from them. If you're using JSTL, the difference between request and session can be even blurrier.

tpierzina
Absolutely true. I have done about 4 decent sized web apps with spring, and this is definitely not a hack, the servlet (or in spring, the controller) setsup all the data for the view, and the JSP contains ONLY logic for displaying the data provided to it by the controller. It works great, and is really easy to maintain, you definitely want to go this route, its not a hack.
Zoidberg
+3  A: 

Put Java objects in the Request/Response/Session and use a javax.servlet.RequestDispatcher in your servlet, something like that:

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

A forward is server-side and the target servlet/JSP receives the same request/response objects as the original servlet/JSP. Therefore, you can pass data between them using request.setAttribute().

The other option is to use response.sendRedirect(String location) which is client-side (this method sends a temporary redirect response to the client) so the location URL receives a new request from the client, and the only way to pass data is through the session or with web parameters (url?name=value).

This is basically what MVC frameworks do (and no, it's not a hack).

Pascal Thivent
Does dispatcher.forward() actually send a 302 to the client or does it handle it all server side? I think I may be getting my HTML terminology overloaded.
Sean Lynch
@Sean, all server side.
tpierzina
I've updated my answer to cover both case (server-side and client-side)
Pascal Thivent
+3  A: 

Put the object(s) in the request, forward the request to the jsp page and then use the object(s) in the jsp to render the response.

In your servlet,

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

If your result JSP should not be accessed directly from a URL you should hide it inside the WEB-INF directory where it can be accessed only through the forward directive.

Then on your jsp you can have,

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

To retrieve the object and used it as needed.

As others suggested, eventually it would be a good idea to learn to use JSTL and maybe an MVC framework like Spring MVC. The tutorial can be found here.

Elliot Vargas
Does rd.forward send a 302 back to the client or does it handle it all on the server side? I may just be getting my terminology confused.
Sean Lynch
@Sean Lynch - The forward directory is server side. That's why you can access JSP pages inside the WEB-INF directory using it.
Elliot Vargas