setting a jstl bean varable?
i have a java bean like this:
<jsp:useBean id="empskill" class="com.Database.EmployeeSkill" scope="page">
<jsp:setProperty name="empskill" property="ename" value="<%= session.getAttribute( "ename" ) %>"/>
<jsp:setProperty name="empskill" property="skill.skillname" value="<%= session.getAttribute( "sname" ) %>"/>
<jsp:setProperty name="empskill" property="yearsexperience" value="<%= session.getAttribute( "yexp" ) %>"/>
</jsp:useBean>
and i have java set method in employeeskill :
publicvoid setSkill(Skill skill){this.skill = skill;}
and i have a java set method in skill :
publicvoid setSkillname(String skillname){ this.skillname = skillname;}
why is it that i cant set the parameter like this, i get this error:
org.apache.jasper.JasperException: An exception occurred processing JSP page /main.jsp at line 277
274:
275:<jsp:useBean id="empskill" class="com.Database.EmployeeSkill" scope="page">
276:<jsp:setProperty name="empskill" property="ename" value="<%= session.getAttribute( "ename" ) %>"/>
277:<jsp:setProperty name="empskill" property="skill.skillname" value="<%= session.getAttribute( "sname" ) %>"/>
278: <jsp:setProperty name="empskill" property="yearsexperience" value="<%= session.getAttribute( "yexp" ) %>"/>
279:</jsp:useBean>
280:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:555)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:414)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
org.apache.jasper.JasperException: org.apache.jasper.JasperException: Cannot find any information on property'skill.skillname' in a bean of type'com.Database.EmployeeSkill'
org.apache.jasper.runtime.JspRuntimeLibrary.handleSetProperty(JspRuntimeLibrary.java:666)
org.apache.jsp.main_jsp._jspService(main_jsp.java:353)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:390)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
org.apache.jasper.JasperException: Cannot find any information on property'skill.skillname' in a bean of type'com.Database.EmployeeSkill'
org.apache.jasper.runtime.JspRuntimeLibrary.getWriteMethod(JspRuntimeLibrary.java:794)
org.apache.jasper.runtime.JspRuntimeLibrary.handleSetProperty(JspRuntimeLibrary.java:663)
org.apache.jsp.main_jsp._jspService(main_jsp.java:353)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:390)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
[4654 byte] By [
h1400046a] at [2007-11-26 21:59:55]

# 1
The set methods aren't recursive. Besides, the propery="skill.skillname" would have to be translated to empskill.getSkill().setSkillname(String) since the setSkill(Skill) method must be void type (and thus no object to reference to call the setSkillname method on).
What exactly do you want to do with that statement? Generate a new Skill with the given name and assign it to the empskill? You would do this:
<jsp:useBean id="empskill" class="com.Database.EmployeeSkill" scope="page">
<jsp:setProperty name="empskill" property="ename" value="<%= session.getAttribute( "ename" ) %>"/>
<jsp:useBean id="tempSkill" class="the fully quallified Skill class name" scope="page"/>
<jsp:setProperty id="tempSkill" name="skillname" value="value="><%= session.getAttribute( "sname" ) %>"/>
<jsp:setProperty name="empskill" property="skill" value="<%= page.getAttribute( "tempSkill" ) %>"/>
<jsp:setProperty name="empskill" property="yearsexperience" value="<%= session.getAttribute( "yexp" ) %>"/>
</jsp:useBean>
By the way, this is not JSTL. If you wanted to use JSTL with EL, it would look something like:
<jsp:useBean id="empskill" class="com.Database.EmployeeSkill" scope="page">
<c:set target="empskill" property="ename" value="${session.ename}"/>
<jsp:useBean id="tempSkill" class="..." scope="page"/>
<c:set target="tempSkill" property="skillname" value="${session.sname}"/>
<c:set target="empskill" property="skill" value="${tempSkill}"/>
<c:set target="empskill" property="yearsexperience" value="${session.yexp}"/>
</jsp:useBean>
If generating a new skill based on a skill name is really your goal, I would think about making a method in the com.Database.EmployeeSkill class that takes the skill name as the input and generates a new skill. Something like:
public void setSkill(String skillName) {
Skill skill = new Skill();
skill.setSkillname(skillName);
this.setSkill(skill);
}
So you could do a more simple set of calls:
<jsp:useBean id="empskill" class="com.Database.EmployeeSkill" scope="page">
<jsp:setProperty name="empskill" property="ename" value="<%= session.getAttribute( "ename" ) %>"/>
<jsp:setProperty name="empskill" property="skill" value="<%= session.getAttribute( "sname" ) %>"/>
<jsp:setProperty name="empskill" property="yearsexperience" value="<%= session.getAttribute( "yexp" ) %>"/>
</jsp:useBean>
# 2
i have a number of classes which all contain a number of instance varables:
the skill class:
public class Skill {
private ResultSet rs ;//the result set to hold the data from the database
private Connection con;//holds the connection to the database
private Statement stmt;//used to run SQL
private int skillid;
private String skillname, description;
SkillType skilltype = new SkillType();
public void setSkillid(int skillid) { this.skillid = skillid; }
public void setSkillname(String skillname) { this.skillname = skillname; }
public void setDescription(String description) { this.description = description; }
public int getSkillid() { return this.skillid; }
public String getSkillname() { return this.skillname; }
public String getSkillDescription() { return this.description; }
the empskill class:
public class EmployeeSkill {
private ResultSet rs ;//the result set to hold the data from the database
private Connection con;//holds the connection to the database
private Statement stmt;//used to run SQL
private String skilllevel, description, skillname = null;
private double yearsexperience = 0;
Employee employee = new Employee();
SkillType skilltype = new SkillType();
Skill skill = new Skill();
public void setSkill(Skill skill) {this.skill = skill; }
public void setSkillType(SkillType skilltype) {this.skilltype = skilltype; }
public void setSkillid(int skillid) {this.skill.setSkillid(skillid); }
public void setEmpid(int empid) {this.employee.setEmpid(empid); }
public void setSkilllevel(String level) { this.skilllevel = level; }
public void setDescription(String description) { this.description = description; }
public void setYearsexperience(double yearsexp) { this.yearsexperience = yearsexp; }
public void setEname(String ename) { this.employee.setEname(ename); }
public Skill getSkill() { return this.skill; }
public SkillType getSkilltype() {return this.skilltype; }
public int getSkillid() { return this.skill.getSkillid(); }
public int getEmpid() { return this.employee.getEmpid(); }
public String getSkilllevel() { return this.skilllevel; }
public String getDescription() { return this.description; }
public double getYearsexperience() { return this.yearsexperience; }
public String getEname() { return this.employee.getEname(); }
a method in employeeskill is run from the jsp page. It requires three varables to be set these are skillname, employeename (ename), and years experience.
now i can set the 2 varables ename and years experience easily enough but i cannot set the skillname varable and this is were i get confused. The only way around it that i have found is to have an additional method in the empskill class:
public void setSkillname(String skillname) {this.skillname = skillname; }
but this is just repeating a method, which i dont believe is strickly right?
# 3
This is a tough looking design. Here is what I would ask myself, if I were you:
Is EmployeeSkill A Skill, or does EmployeeSkill Have A Skill?
Your design says: EmployeeSkill Has A Skill, but it seems to me that EmployeeSkill Is A Skill.
So instead of having EmployeeSkill contain an object of type Skill, maybe EmployeeSkill should extend Skill:
class Skill {
private ResultSet rs ;//the result set to hold the data from the database
private Connection con;//holds the connection to the database
private Statement stmt;//used to run SQL
private int skillid;
private String skillname, description;
SkillType skilltype = new SkillType();
public void setSkillid(int skillid) { this.skillid = skillid; }
public void setSkillname(String skillname) { this.skillname = skillname; }
public void setDescription(String description) { this.description = description; }
public void setSkilltype(SkillType skilltype) { this.skilltype = skilltype; }
public int getSkillid() { return this.skillid; }
public String getSkillname() { return this.skillname; }
public String getSkillDescription() { return this.description; }
public SkillType getSkilltype() { return this.skilltype; }
} //end Skill class
public class EmployeeSkill extends Skill {
private ResultSet rs ;//the result set to hold the data from the database
private Connection con;//holds the connection to the database
private Statement stmt;//used to run SQL
private String skilllevel;
private double yearsexperience = 0;
Employee employee = new Employee();
public void setSkilllevel(String level) { this.skilllevel = level; }
public void setYearsexperience(double yearsexp) { this.yearsexperience = yearsexp; }
public void setEmpid(int empid) {this.employee.setEmpid(empid); }
public void setEname(String ename) { this.employee.setEname(ename); }
public int getEmpid() { return this.employee.getEmpid(); }
public String getEname() { return this.employee.getEname(); }
public String getSkilllevel() { return this.skilllevel; }
public double getYearsexperience() { return this.yearsexperience; }
} //end EmployeeSkill class
In that case, because EmployeeSkill is a Skill, it has all the methods of the parent Skill type.
Choosing between inheritance (EmployeeSkill Is A Skill) and composition (EmployeeSkill Has A Skill) can be tricky sometimes. Only use the inheritance scheme if it actually fits (it does appear to fit to me), and only if the Skill referenced by EmployeeSkill doesn't change in relationship to the EmployeeSkill (for example, if the Skill's SkillType can change indepependently, or if, over the course of your application, the EmployeeSkill may point to several different Skills, while maintaining its own identity).
An Composition alternative to the above code would have delegate methods in the EmployeeSkill class to pass information to the Skill, and get it back:
public class EmployeeSkill {
private ResultSet rs ;//the result set to hold the data from the database
private Connection con;//holds the connection to the database
private Statement stmt;//used to run SQL
private String skilllevel;
private double yearsexperience = 0;
Employee employee = new Employee();
Skill skill = new Skill();
public void setSkilllevel(String level) { this.skilllevel = level; }
public void setYearsexperience(double yearsexp) { this.yearsexperience = yearsexp; }
public void setEmpid(int empid) {this.employee.setEmpid(empid); }
public void setEname(String ename) { this.employee.setEname(ename); }
public void setSkillid(int skillid) { this.skill.setSkillid(skillid); }
public void setSkillname(String skillname) { this.skill.setSkillname(skillname); }
public void setDesctiption(String description) { this.skill.setDescription(description); }
public void setSkilltype(SkillType skilltype) { this.skill.setSkilltype(skilltype); }
public int getSkillid() { return this.skill.getSkillid(); }
public String getSkillname() { return this.skill.getSkillname(); }
public String getDescription() { return this.skill.getSkillDescription(); }
public SkillType getSkilltype() { return this.skill.getSkilltype(); }
public int getEmpid() { return this.employee.getEmpid(); }
public String getEname() { return this.employee.getEname(); }
public String getSkilllevel() { return this.skilllevel; }
public double getYearsexperience() { return this.yearsexperience; }
} //end EmployeeSkill class
It looks worse because it has more methods, but it can be the better design in the long run.
I would also question the design that says 'EmployeeSkill Has An Employee'. It seems to me that the opposite should be true, the 'Employee Has An EmployeeSkill', or a bunch of them. So it might be worth thinking about how to better manage that relationship.
