2

This is what I have in my action class code:

private List<PersonDO> listPerson;

public void setListPerson(List<PersonDO> listPerson) {
    this.listPerson = listPerson;
}

public List<PersonDO> getListPerson() {
    return listPerson;
}

public String Details() {
   PersonDO personDO = new PersonDO()
   personDO.setName("Bob");
   personDO.setAge("20");
   
   this.listPerson = new ArrayList<PersonDO >();
   this.listPerson.add(personDO)

   return "success";
}

I know the object is passed into the valuestack when the "Details" action is call as I can iterate "listPerson" in my JSP as such

<s:iterator value="listPerson" status="rowSts" var="mapItem">
   <td style="vertical-align:middle;"><s:property value="#mapItem.name" /></td>
   <td style="vertical-align:middle;"><s:property value="#mapItem.age" /></td>
</s:iterator>

But my problem is I want to pass it into a common nested jsp without directly calling it with the name "listPerson" as this jsp be used through out my application

I have tried the following

main.jsp

<s:include value="sub.jsp">
    <s:param name="listResult" value="listPerson">
</s:include>

sub.jsp

<%pageContext.setAttribute("listResult" , request.getParameter("listResult")); %>
<s:set var="listResult" value="%{#attr.listResult}"/>


 <s:iterator value="listPerson" status="rowSts" var="mapItem">
      <td style="vertical-align:middle;"><s:property value="#mapItem.name" /></td>
      <td style="vertical-align:middle;"><s:property value="#mapItem.age" /></td>
 </s:iterator>

It is not working, I am trying to set a variable "listResult" to reference "listPerson" and iterate it in the sub.jsp.

UPDATE:

To clarify why I am doing this is because I want to reuse sub.jsp twice within main.jsp to avoid duplicate coding with only trivial differences such as a different variable name of a list.

I was able to solve my problem as such

<c:set var="listResult"  value="${listPerson}"  scope="request"/>
<s:include value="sub.jsp">
    <s:param name="shortlist">true</s:param>
</s:include>

<c:set var="listResult"  value="${listCompany}"  scope="request"/>
<s:include value="sub.jsp">
    <s:param name="shortlist">true</s:param>
</s:include>

I think it works because the jsp is generated top down and variable "listResult" is set another value before sub.jsp is rendered again. Correct me if I am wrong and please let me know if there are any issues with this method or if you propose a better solution.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
ron
  • 239
  • 3
  • 18
  • WHY are you doing that ? If you have your list loaded in a base action, and want do achieve DRY, just put the iterator inside sub.jsp and include sub.jsp in your other jsps – Andrea Ligios Dec 21 '16 at 11:28
  • Because in my situation, I will be including sub.jsp twice in main.jsp. Each one will be displaying a list. One will be displaying values from a "listPerson" while the other is displaying items from "listCompany". I want to reuse sub.jsp to avoid extra coding of the same thing but having trivial differences like a different variable name of a list. – ron Dec 21 '16 at 11:39
  • But if you are iterating two list of different objects, then also the attributes printed out inside the iteraion will differ... a Person is not a Company, so how do you handle that ? Parameterizing also the attribute names ? Dude, this is not the right way, IMHO. If you have multiple pages where you print Persons and/or Companies, you can create person.jsp and company.jsp, each one with ITS iteration inside, and include those. Otherwise, do two iterations, it's not a repetition, since they're different objects – Andrea Ligios Dec 21 '16 at 11:49
  • It would be also wrong if ALL the attributes of Person and Company would match; what if tomorrow you'll add an attribute to Person that is not on Company ? You'll be in trouble, and will need to start doing – Andrea Ligios Dec 21 '16 at 11:51
  • I don't mean any disrespect but lets just disregard the specifics and stick with the question. First off "person" and "company" both are is the exact same bean but are retrieved from the database with different conditions. So essentially they will be displaying the same columns. I am just trying to keep my question simple without overloading it with unneccesary information. – ron Dec 21 '16 at 11:53
  • To make myself more clear "person" and "company" are the exact same bean and the data is retrieved from the same table, if an attribute was added it would affect both but named differently. If you find that an structural problem then i have nothing to say, the database schema is not within my scope. – ron Dec 21 '16 at 12:05
  • Well, that *is* an antipattern but, sticking to the question: can't you just name your Lists with the same name ? `private List list;`, `private List list;` -> `` – Andrea Ligios Dec 21 '16 at 13:06
  • It actually both are List but just named different. I guess i could have made this more clear in my example. Both list will be displayed in the same page top down and the result list in the sub.jsp will exist in other pages as well hence why I am trying to achieve DRY. And in this case, two different instances of the same object will be in the same page. Unless their is a better solution I am going to stick with in the main.jsp just before each sub.jsp since the page is rendered top down. – ron Dec 21 '16 at 13:57
  • Your `` solution is good, then. It's the DRYest thing I can think of ATM. – Andrea Ligios Dec 21 '16 at 14:03
  • Thank you for the input! – ron Dec 21 '16 at 14:16
  • 1
    @ron Please use answer section for answering. And don't forget to accept your answer as well. – Aleksandr M Dec 21 '16 at 18:33

1 Answers1

0

You are trying to create a request scope variable and access it from included page. It might be an alternative to access request scope params.

Note, that parameters are accessed only as request params:

Parameters are passed as request parameters, so use the ${param.ParamName} notation to access them. Do not use the s:property tag to access parameters in included files.

Why not to use value stack and push the parameter that you want to access from iterator within included page?

<s:push value="listPerson">
  <s:include value="sub.jsp">
    <s:param name="shortlist">true</s:param>
  </s:include>
</s:push>

<s:push value="listCompany">
  <s:include value="sub.jsp">
    <s:param name="shortlist">true</s:param>
  </s:include>
</s:push>

If you need both lists as parameters, you can push both (one after another). The value stack is not limited with its size.

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Thank you for your input now I learned a new way of doing it, by using push. But this wouldn't work in my case since the they will both still be named "listPerson" and "listCompany" respectively. I am trying to set a variable "listResult" to reference them because that is how it is named within the "sub.jsp" – ron Dec 22 '16 at 01:33
  • If you push an object to the value stack it has not a name. You can reference iterable object directly from the stack. If you want to *set* a named variable then you can use `s:set` tag. In this way the object by default goes into `action` scope, so you can get it either in `s:iterator` or `c:forEach`. – Roman C Dec 22 '16 at 17:38
  • @ron did you try this solution? – Roman C Jan 02 '17 at 20:58