4

I print a list directly in the servlet using the print writer and the list prints.

When I try to put in the jsp however the list doesn't print whether I use JSTL or scriptlets.

I tried to test in JSTL and scriptlet if the object is null and turns out that it is!

Why does this happen and how can I fix this?

Servlet code that works

for (Artist artist:artists){
    resp.getWriter().println(artist.getName());
}

Servlet code that puts object in the request

public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws IOException {        

    ApplicationContext ctx = 
        new ClassPathXmlApplicationContext("com/helloworld/beans/helloworld-context.xml");

    ArtistDao artistDao = (ArtistDao) ctx.getBean("artistDao");
    List<Artist> artists = null;
    try {
        artists = artistDao.getAll();
    } catch (SQLException e) {
        e.printStackTrace();
    }

    req.setAttribute("artists", artists);

    try {
        req.getRequestDispatcher("index.jsp").forward(req, resp);
    } catch (ServletException e) {
        e.printStackTrace();
    }

scriptlet code that suddenly finds the object null

<% 

    List<Artist> artists = (List<Artist>) request.getAttribute("artists");

    if (artists == null) {
        out.println("artists null");
    }
    else {
        for (Artist artist: artists){
            out.println(artist.getName());
        }
    }
%>

Even the jstl code seems to agree

<c:if test="${artists eq null}">
    Artists are null
</c:if>

<c:forEach var="artist" items="${artists}">
${artist.name}
</c:forEach>

For my app I am using weblogic, spring 2.5.6 and ibatis.

Jeune
  • 3,498
  • 5
  • 43
  • 54
  • Do you have the chance to try on a different app server? I don't see any problems with the code - setAttribute/requestDispatch is a common pattern. – mdma May 17 '10 at 07:46
  • I am required to use weblogic here at work but I'll try testing in tomcat. Like you, I have been thinking it's a problem with the app server. – Jeune May 17 '10 at 07:49

3 Answers3

1

Maybe the app server is resetting your request object. You can work around this by creating a new request object, that wraps your original request, and pass that to the reqest dispatcher.

e.g. MyHttpRequest myRequest = new MyHttpRequest(req); myRequest.setAttribute(...); req.getRequestDispatcher("index.jsp").forward(myRequest, resp);

And the MyHttpReqest code:

   class MyHttpRequest extends HttpServletRequestWrapper
   {
      Map attributes = new HashMap();
      MyHttpRequest(HttpRequest original) {
         super(original);
      }
      @Override
      public void setAttribute(Object key, Object value) {
          attributes.put(key, value);
      }

      public Object getAttribute(Object key) {
          Object value = attributes.get(key);
          if (value==null)
              value = super.getAttribute(key);
          return value;
      }

      // similar for removeAttribute 
   }
mdma
  • 56,943
  • 12
  • 94
  • 128
  • How do not make the app server reset my request object? – Jeune May 17 '10 at 08:37
  • I don't know. It's not meant to, and I'm only guessing that this is the problem - I don't have access to a weblogic instance to test. Can you try the code I posted? You can then debug and check that you are getting the same MyHttpRequest instance in your JSP. – mdma May 17 '10 at 08:45
  • Can you confirm that you're adding the attributes on MyHttpRequest and not the usaual HttpServletRequest instance? The original code is a little misleading, so I've updated it. – mdma May 17 '10 at 10:58
  • will do but I'll have to get back to you tomorrow. Not in the office now. :) thanks for the help! – Jeune May 17 '10 at 13:31
  • I believe if servlet request class is not working then wrapper also behaves like the same. Surprising behaviour of the server which I never come across. – Ravindra Gullapalli May 17 '10 at 16:38
  • @RaviG - The wrapper doesn't necessarily have to behave the same since we are explicitly adding the attribute to our wrapper - the attributes are stored separately from the request attributes provided by the app server. – mdma May 17 '10 at 17:12
  • @mdma I tried your solution. Unfortunately it still doesn't work. However when I placed my index.jsp inside another folder in WEB-CONTENT/ it does (see my answer for more info) but then I won't need it anymore since the common pattern also works as well. – Jeune May 18 '10 at 01:45
  • Great that you found a solution. This here was just a shot in the dark. – mdma May 18 '10 at 04:21
1

I think it depends on the web server. But without changing your previous directory structure,

try putting the list in session like this

req.getSession(false).setAttribute("artists", artists);

and in your jsp,

write

List<Artist> artists = (List<Artist>) request.getSession(false).getAttribute("artists"); 

I think my approach will work for all web servers.

Ravindra Gullapalli
  • 9,049
  • 3
  • 48
  • 70
  • I tried this also but it didn't work too with the first directory structure above. It was really frustrating! Now that you've mentioned the session, I haven't tried if the session works with the second directory structure above. What does the problem have to do with directory structure you masy ask? Believe me I don't see the correlation either but it works. @-) – Jeune May 17 '10 at 13:28
0

I just discovered inadvertently while trying to fix my directory structure in WebContent/

My previous directory structure was

WEB-CONTENT/
    - META-INF/
    - WEB-INF/
    index.jsp

Then I tried to create a folder jsp in WEB-CONTENT and placed index.jsp there. It works!

My current directory structure now is

WEB-CONTENT/
    - META-INF/
    - WEB-INF/
    - jsp/
        -index.jsp

I don't know why it works but it did.

Anyone here with any idea why?

Jeune
  • 3,498
  • 5
  • 43
  • 54