aspose file tools*
The moose likes JSP and the fly likes JSP/Java Bean problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » JSP
Bookmark "JSP/Java Bean problem" Watch "JSP/Java Bean problem" New topic
Author

JSP/Java Bean problem

Alex Belt
Ranch Hand

Joined: Jul 12, 2001
Posts: 57
I've done some servlet work before, but I am new to JSP's and having a problem. I have a jsp that does a jdbc-odbc lookup and returns the data which works fine. But as soon as I move the jdbc code into a bean it quits working. I have one method that establishes the connection, then I set a key from the jsp, then run the query. Except that by the time I get to the second method, the connection and prepared statement have been dropped and I have to re-establish them, and I've tried putting them into a HashMap with the same result. Can someone see what's wrong with my code? I'm posting the jsp code and the pertinent bean code below. Thanks!
jsp code:
<html><head></head>
<%@ page language="java" import="interactive.*,java.net.*,java.sql.*" %>
<jsp:useBean id="dta" scope="session" class="interactive.BookData" />
<%
HttpSession hs = request.getSession();
String enckey = request.getParameter("link");
String key = URLDecoder.decode(enckey);
/*
if (hs.getAttribute(key) != null) {
throw new Exception("you have already read this page");
}
hs.setAttribute(key, "true"); */
if (!dta.isConnected()) {
dta.connect();
}
dta.setKey(key);
dta.doQuery();
%>
</head>
<body>
<b><%= key %></b><p>
<%= dta.getContent() %><p>
<table><tr><td width="300">
<a href="novelbean.jsp?link=<%= URLEncoder.encode(dta.getChoice1()) %>"><%= dta.getChoice1() %></a>
</td>
<% String choose = dta.getChoice2();
if (choose == null) {
choose = "<td></td>";
} else {
choose = "<td><a href=\"novelbean.jsp?link=" + URLEncoder.encode(choose) + "\">"+ choose + "</td>";
}
%>
<%= choose %>
</tr></table></body></html>
bean code:
import java.sql.*;
import java.io.*;
import java.util.*;
public class BookData implements Serializable{
protected Connection con;
protected String user = "Admin";
protected String pwd = "admin";
protected String key;
protected String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
protected String connectStr = "jdbc dbc:Interactive";
protected String stateStr = "select * from Chapter1 where Section = '?'";
protected PreparedStatement ps;
protected String content;
protected String choice1;
protected String choice2;
private HashMap hm = new HashMap();
public BookData() {
}
public void setKey(String phrase) {
key = phrase;
}
public boolean connect() {
try {
Class.forName(driver);
con = DriverManager.getConnection(connectStr);
ps = con.prepareStatement(stateStr);
return true;
} catch (SQLException se) {
System.err.println(se);
} catch (Exception e) {
System.err.println(e);
}
return false;
}
public boolean doQuery() {
try {
ps.setString(1, key);
ResultSet rs = ps.executeQuery();
rs.next();
content = rs.getString(2);
choice1 = rs.getString(3);
choice2 = rs.getString(4);
return true;
} catch (Exception se) {
se.printStackTrace();
}
return false;
}
}
Bosun Bello
Ranch Hand

Joined: Nov 06, 2000
Posts: 1510
Are you sure your connection and prepared statements are available to the second method at all? Are they in scope or how are you making them available to the second method?


Bosun (SCJP, SCWCD)
So much trouble in the world -- Bob Marley
Sean MacLean
author
Ranch Hand

Joined: Nov 07, 2000
Posts: 621
I think the problem is that you cannot serialize an open connection (streams, writers db connections, etc). The bean you are using is being scoped to session scope (which requires that it be serializable to function properly). You could try to scope it in request scope (because some containers won't serialize objects in this scope). You might want to consider a more layered design - this would be the best approach to solving this.
Sean
[ June 13, 2002: Message edited by: Sean MacLean ]
Alex Belt
Ranch Hand

Joined: Jul 12, 2001
Posts: 57
I tried your suggestions Sean, but I'm still having the same problem. I've tried it with the scope as page and request, but the connection and prepared statement are both dropped. I also recompiled the bean without the Serializable interface but to no avail. I've been testing on both Tomcat and Jrun with the same result.
What do you mean by a more layered design? Do you mean create the SQL handler as a separate Java object and have the bean simply be a manager for that object?
Maulin Vasavada
Ranch Hand

Joined: Nov 04, 2001
Posts: 1871
hi alex,
if i were u i'd have done something like this,
-a bean that stores the key, query and the result of the query,
- a database connection class that does connection to the database and executes the queries submitted to it.
the bean will have an object ref to the database conneciton and will submit query to it. it will retreive the results and store it within itself.
well, its a design issue but i am able to understand why ur connection is getting lost or whatever happening to ur code currently...i 'll try to think something...
regards
maulin.
Maulin Vasavada
Ranch Hand

Joined: Nov 04, 2001
Posts: 1871
btw,
u getting any errors/exceptions???
-maulin
Sean MacLean
author
Ranch Hand

Joined: Nov 07, 2000
Posts: 621
I not too suprised that didn't work. Layered design. Well, I'd create a data access object like BookUtils.java or whatever and put all book related database code in there. Now, you want to maintain a DB datasource, so create one in a static initializer in a DataAccessUtils class. Then put a getConnetion() method in there to get control over how the DB connections are dispensed (i.e. singlton, pooling). Something like this,

In the BookUtils class make a findByKey method (or whatever parameter that you require). This method will return a BookBean like the one you have now.


Ok. Now you define a pure BookBean.java with only get/set methods. Now in the jsp you can do something like
<% String key = request.getParameter( "key" );
request.setAttribute( "BookBean",
BookUtils.findByKey( key ) );
%>
Even this is not a clean as I would like. You could use a "use bean" tag and have the bean instantiate itself when you call bean.setKey( request.getParameter( "key" ) );. Or you could start to look into the Struts framework .... but that's another story. Hope this helps.
NOTE: I just typed this as pseudo code examples. None of this above has been tested and it is not expected to compile.
Sean
Alex Belt
Ranch Hand

Joined: Jul 12, 2001
Posts: 57
Thanks Sean, I may give that a try. That's a little more complexity than I had wanted to introduce at this stage of the game, but I suppose I don't have much choice. My idea was to start simple and progressively refine the pages and beans until I had a taglib that could do the work. I had hoped to avoid the whole connection pooling thing at this stage since I'm new to jdbc and such as well. Fortunately, this project is simply a learning experience and isn't going into production.
Maulin, I can't store the key in a bean since it's passed as part of the url when the jsp is invoked, that way I can re-use the page instead of having a separate page or bean for each entry in the database. And yes, I'm getting exceptions. The Tomcat and JRun logs generate contain an entry that indicates a NullPointerException in the doQuery method in the bean. If I bypass the sql statements and set the results to a hardcoded value the page returns the hardcoded results correctly. It's only when I attempt to use the previously instantiated sql variables that I get the NullPointerException. I know it's them because I've checked for null conditions and logged it. I will likely re-factor my code along the lines of Sean's suggestions.
Your help is greatly appreciated, thank you!
Sean MacLean
author
Ranch Hand

Joined: Nov 07, 2000
Posts: 621
Though it may seem more complex, it will actually turn out to be much less complex - there are just more classes As an analogy, consider which is more complex to design and build - a swiss army knife (all things fitting into one) or a set of a knife, fork and spoon. I've always found that when something starts to get messy and there is not clear path to resolution, then the fundemental elements must be questioned (and this goes for most things). Consider cooking. Imagine this - "I don't know why dinner was so bad, I cooked the fish perfectly and topped it with my favorite ice cream?". Well, fundementally, fish and ice cream just don't go together. To me this is like data access in the presentation layer. They just don't fit together and this is the root of the issue. OK, this was a weird response Best of luck.
Sean
Alex Belt
Ranch Hand

Joined: Jul 12, 2001
Posts: 57
Thanks Sean. I refactored the code and put the db handling code into a class and removed any references to it except to load it in the jsp and had the method return a pure Bean containing the data, but that wasn't the problem. the problem turned out to be the string I was using to generate the prepared statement. Seems that you're not supposed to use quotes around the ? placeholder and I was. I took them out and it solved the problem.
Thanks again for all your help.
 
jQuery in Action, 2nd edition
 
subject: JSP/Java Bean problem