Hi All:
I needed to passed an integer value from the following code:

<%=ic.getTotalNumOfRecords()%>

to an attribute of a custom tag

<inquiry:tableClaimHistory numberOfRecords="5" dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

The function getTotalNumOfRecords returns an int.
The attribute numberOfRecords expects an string.
Here are the different ways I tried in a jsp page but I get also the following errors:
1.)

<%@ include file="../common/page_imports.jsp" %>
<inquiry:tableClaimHistory numberOfRecords=<%=ic.getTotalNumOfRecords()%> dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

Error Message:

claimHistoryView.jsp:190:3: Unterminated tag.
<inquiry:tableClaimHistory numberOfRecords=<%=ic.getTotalNumOfRecords()%> dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

2.)

<%@ include file="../common/page_imports.jsp" %>
<inquiry:tableClaimHistory numberOfRecords="<%=ic.getTotalNumOfRecords()%>" dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

Error Message:

claimHistoryView.jsp:190:4: The required attribute "numberOfRecords" is missing.
<inquiry:tableClaimHistory numberOfRecords="<%=ic.getTotalNumOfRecords()%>" dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

3.)

<%@ include file="../common/page_imports.jsp" %>
<inquiry:tableClaimHistory numberOfRecords="<%ic.getTotalNumOfRecords();%>" dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

Error Message:

java.lang.NumberFormatException: For input string: "<%ic.getTotalNumOfRecords();%>"

4.)

<%@ include file="../common/page_imports.jsp" %>
<%
int records1 = ic.getTotalNumOfRecords();
Integer records2 = new Integer(records1);
String numberOfRecords2 = records2.toString();
 %>
<inquiry:tableClaimHistory numberOfRecords="<%numberOfRecords2;%>" dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

error message:

java.lang.NumberFormatException: For input string: "<%numberOfRecords2;%>"
 at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1224)
 at java.lang.Double.valueOf(Double.java:447)
 at java.lang.Double.(Double.java:539)
 at com.DisplayTableClaimHistoryTag.displayTable(DisplayTableClaimHistoryTag.java:63)

5.)

<%
   int records1 = ic.getTotalNumOfRecords();
   Integer records2 = new Integer(records1);
   String numberOfRecords2 = records2.toString();
   %>
  <inquiry:tableClaimHistory numberOfRecords=<%numberOfRecords2;%> dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

error message:

claimHistoryView.jsp:194:3: Unterminated tag.
  <inquiry:tableClaimHistory numberOfRecords=<%numberOfRecords2;%> dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

In the custom tag java code called "DisplayTableClaimHistoryTag"
I tried to used the following code:

InquiryContext ic = InquiryContext.getContext(session);

The problem is that in order to get session I needed HttpSession object. I don't know how to passed HttpSession "session" object
to a custom tag. Is there a way to do this?

public class DisplayTableClaimHistoryTag extends InquiryTag
{
 String numberOfRecords;
 public void setNumberOfRecords(String numberOfRecords)
 {
  this.numberOfRecords = numberOfRecords;
 }

 public String getNumberOfRecords()
 {
  return numberOfRecords;
 }

 public int doStartTag()throws JspException
 {

  InquiryContext context = (InquiryContext)pageContext.getSession().getAttribute(Constrain.CONTEXT);
  if(context==null)
   throw new JspException(TAG_EXCEPTION+ "InquriyContext is null.");
  String hasData = (String)context.getAttribute(Constrain.CONTROL_HAS_DATA);
  if(hasData==null)
   throw new JspException(TAG_EXCEPTION + "The hasData property can not be null.");
  boolean hd = Boolean.valueOf(hasData).booleanValue();
  Debug.println("hasData="+hd);
  Debug.println("hasDataString="+hasData);
  if(hd)
   displayTable();
  else
   disPlayError();
  return SKIP_BODY;
 }
 private void displayTable() throws JspException
 {

  String outString ="";
  Debug.println("dispalyTable() ********* dataAction="+ dataAction);
  JspWriter out = pageContext.getOut();
  /*
   * Minimum height height= 103,70
   * 21.7 per row
   * First row==103+21.5=124.5
   * Second row ==103+21.5*2=146
   * Third row ==103+21.5*3=167.5
   */
  Double numberOfRecordsBigDouble = new Double(numberOfRecords);
  double numberOfRecordsDouble = 70 + 21.8*numberOfRecordsBigDouble.intValue();
  if(order==null || order.equals("0"))            
  // outString = "<iframe src=\"" + "/inquiry/" + dataAction + "?order=0"+ "\"" + " name=\"dataFrame\" id=\"dataFrame\" height=\""+numberOfRecordsDouble+"\"" +" width=\"100%\" scrolling=\"NO\" frameborder=\"0\"></iframe>";
  // outString = "<iframe src=\"" + "/inquiry/" + dataAction + "?order=0"+ "\"" + " name=\"dataFrame\" id=\"dataFrame\" style=\"height:"+numberOfRecordsDouble+"px; width:100%\"  scrolling=\"NO\" frameborder=\"0\"></iframe>";
  // outString = "<iframe src=\"" + "[URL]"+ "\"" + " name=\"dataFrame\" id=\"dataFrame\" style=\"height:"+numberOfRecordsDouble+"px; width:100%\"  scrolling=\"NO\" frameborder=\"0\"></iframe>";
  outString = "<iframe src=\"" + "/inquiry/" + dataAction + "?order=0"+ "\"" + " name=\"dataFrame\" id=\"dataFrame\" style=\"height:"+numberOfRecordsDouble+"px; width:100%\"  scrolling=\"NO\" frameborder=\"0\"></iframe>";

  else
  {
   String orderStr = "?order=" + order;
   outString = "<iframe src=\"" + "/inquiry/" + dataAction + orderStr + "\"" + " name=\"dataFrame\" id=\"dataFrame\" height=\""+numberOfRecordsDouble+"\"" +" width=\"100%\" scrolling=\"NO\" frameborder=\"0\"></iframe>";
   //outString = "<iframe src=\"" + "/inquiry/" + dataAction + orderStr + "\"" + " name=\"dataFrame\" id=\"dataFrame\" height=\"161\" width=\"100%\" scrolling=\"NO\" frameborder=\"0\"></iframe>";
  }
  Debug.println("dispalyTable() ********* outString = "+ outString);

  try {
   out.println(outString);
  } catch (IOException e) {
   this.log.error(TAG_EXCEPTION + e.toString(), e);
   throw new JspException(e);
  }
 }

Any hint would be greated appreciated.
Yours,
Frustrated

Dani AI

Generated

— the errors you saw come from two separate issues: the JSP parser/handler not getting a plain runtime value for the tag attribute, and the tag code trying to parse a literal string that still contained scriptlet markers. The clean, maintainable fixes are to stop using scriptlets in attributes and either (A) pass a scoped value and use EL/JSTL, or (B) declare the tag/TLD to accept a numeric type so the container does the conversion.

Recommended approach (controller + JSTL/EL):

/* set the value in your servlet/controller */
request.setAttribute("numRecords", ic.getTotalNumOfRecords());

Then in the JSP use EL (no scriptlets):

<c:set var="numRecords" value="${requestScope.numRecords}" />
<inquiry:tableClaimHistory numberOfRecords="${numRecords}" dataAction="..." emptyKey="..." />

If you control the tag/TLD, declare the attribute type and allow runtime expressions so the container converts numbers for you:

<attribute>
  <name>numberOfRecords</name>
  <required>true</required>
  <rtexprvalue>true</rtexprvalue>
  <type>int</type>
</attribute>

And offer a numeric setter in the tag handler (avoid parsing strings):

public void setNumberOfRecords(int numberOfRecords) {
    this.numberOfRecords = Integer.toString(numberOfRecords);
}

If you cannot change TLD, use <jsp:attribute> to supply a dynamic value safely, or compute the string in the controller and set it as a request/session attribute. Inside a classic tag handler the session is reachable via the provided pageContext (so you do not need to pass an HttpSession explicitly).

As advised, prefer JSTL/EL for clarity and separation; is right that some containers will choke on scriptlets-in-tags. Troubleshoot by checking the TLD rtexprvalue, ensuring the attribute setter type matches what you pass, and printing/logging the attribute value the tag actually receives before numeric conversion.

Recommended Answers

All 2 Replies

<%
   int records1 = ic.getTotalNumOfRecords();
   Integer records2 = new Integer(records1);
   String numberOfRecords2 = records2.toString();
   %>
<inquiry:tableClaimHistory numberOfRecords="<%= numberOfRecords2 %>" dataAction="claimHistoryViewData.do" emptyKey="error.noData"/>

Though this approach is not recommended and you are better off using JSTL to reduce the clutter and better separation of presentation and business logic.

in fact some JSP compilers will reject that code because it's so bad :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.