Preface
在浏览本文之前,请确定你是在以下相似environment和condition下遇到相似问题。
Environment:
OS: Windows XP
Language: Java 1.5
Framework: Struts 1.3
IDE: MyEclipse 6.0
Condition:
在jsp page正常,在actionForm中用到object class。
Introduction
本文讲述在actionForm中用到object class时可能会导致的Exception。
Section1 - Problem
HTTP Status 500 -
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspException: Getter for property countryRegionCode threw exception: java.lang.NullPointerException org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:541) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:417) 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
javax.servlet.ServletException: javax.servlet.jsp.JspException: Getter for property countryRegionCode threw exception: java.lang.NullPointerException org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:850) org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:779) org.apache.jsp.fundInformation.fundHouseSearch_jsp._jspService(fundHouseSearch_jsp.java:365) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) javax.servlet.http.HttpServlet.service(HttpServlet.java:803) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393) 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
javax.servlet.jsp.JspException: Getter for property countryRegionCode threw exception: java.lang.NullPointerException org.apache.struts.taglib.html.SelectTag.calculateMatchValues(SelectTag.java:245) org.apache.struts.taglib.html.SelectTag.doStartTag(SelectTag.java:177) org.apache.jsp.fundInformation.fundHouseSearch_jsp._jspx_meth_html_005fselect_005f0(fundHouseSearch_jsp.java:487) org.apache.jsp.fundInformation.fundHouseSearch_jsp._jspService(fundHouseSearch_jsp.java:197) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) javax.servlet.http.HttpServlet.service(HttpServlet.java:803) org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:393) 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)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.13 logs.
Apache Tomcat/6.0.13
Section 2 - Reason
例如首先在jsp page上有这样一个property
<html:text property="fundHouseID" styleClass="text_general"></html:text>
用其default创建下的actionForm是没有问题的,但从reuse和abstract的aspect角度来说,一般在actionForm中define的private property都是仅仅在jsp page有该property而实际的object class中却没有该property,或者该property需要经过经过action去转换成object class需要的property。所以在jsp page上的property和实际object class的property对应时,在actionForm中不再为jsp page上的property define一个新的property,而是通过getter和setter call object class上的getter和setter来操作property,但是这样就经常容易出现一种错误,因为必须要在actionForm中new一个object class的instance,如果没有new到会碰到以上Exception,如一下Code:
actionForm:
/** fundHouse property */
private FundHouse fundHouse;
/** fundHouseName property */
private String fundHouseID;
/**
* @return the fundHouse
*/
public FundHouse getFundHouse() {
return fundHouse;
}
/**
* @param fundHouse the fundHouse to set
*/
public void setFundHouse(FundHouse fundHouse) {
this.fundHouse = fundHouse;
}
/**
* @return the fundHouseID
*/
public String getFundHouseID() {
return fundHouseID;
}
/**
* @param fundHouseID the fundHouseID to set
*/
public void setFundHouseID(String fundHouseID) {
this.fundHouseID = fundHouseID;
}
Object Class:
private String fundHouseID;
/**
* @return the fundHouseID
*/
public String getFundHouseID() {
return fundHouseID;
}
/**
* @param fundHouseID the fundHouseID to set
*/
public void setFundHouseID(String fundHouseID) {
this.fundHouseID = fundHouseID;
}
Section 3 - Solution
很简单,只是很容易被忽略,一定要new一个object class的instance,对以上的actionFrom fundHouse property修改如下:
private FundHouse fundHouse = new FundHouse();