Firing Struts Action When JSP Loads

Hi,

I am moving to MVC with struts and reapplying my older code/logic. On my original JSPs at the top just inside the BODY tag I used a jsp:useBean tag to fire a database select like so;

<jsp:useBean id="getAllRecsBean" scope="request" class="invsys.RecAllSel"      type="invsys.RecAllSel" />
<%
getAllRecsBean.execute("","");                      
%>
      
This was then used to populate a dropdown list (via a for loop)  before the user was presented with the JSP.

I  want to use a collection/action to populate the drop down list (via a forEach) instead therefore can someone advise me how do I kick off an /action as a JSP loads, I cant find any good references on the web or in EE.


thanks
adlikonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

bloodredsunCommented:
In struts, you never directly access a JSP. Instead you go from an action to a JSP with data being passed between the two via an ActionForm. This means that your database logic would be done in an action (or more accurately in a helper class called in the action). The results of this would then be passed into the ActionForm which the JSP then outputs.

E.g. some pseudo-code

myAction.do
-----------
Maps in the struts_config.xml: action is myAction.java, with myActionForm.java and going to myAction.jsp

myAction.java
----------------
execute method( params...){
myActionForm myForm = (myActionForm)form ;
myForm.setDatabaseResults( myHelperclass.staticDbMethod() ) ;
forward("success") ; //goes to myAction.jsp
}


myActionForm.java
----------------------
//has method that populates an arraylist/colllection to hold the results


myAction.jsp
----------------

<!-- get form from correct scope by name specified in the config file and call method using dot notation-->
<c:forEach items='requestScope.myActionForm.databaseResults' var='row'>
    <c:out value='row.row' /><!--iterate over arraylist outputting value -->
</c:forEach>
adlikonAuthor Commented:
I had not thought about it like that, ie the action being the starting point , but then how do I fire the action from my web page? (Originally I had a webpage that called my JSP's via links)

(points increased) :)
adlikonAuthor Commented:
!!!!! SORRY !!!!!! - my last question is not correct.

I am effectively building an object which I will use to populate a drop down list on my jsp, therefore my question is how do I call the action to populate the dropdown when I load the jsp (without interaction from the user) ? Or is 'useBean' the preferred approach for this ?  
CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

adlikonAuthor Commented:
Am I making something simple too  complicated ?
bloodredsunCommented:
>>but then how do I fire the action from my web page?

Via the mapping in the struts-config.xml. Here's an example

----------
      <action path="/my_action"
            type="com.bloodredsun.myAction"      
            name="myActionForm"
            validate="false"
            input="/WEB-INF/pages/home.jsp"
            scope="request">
                  <forward name="reset" path="/WEB-INF/pages/home.jsp" />
                  <forward name="success" path="/WEB-INF/pages/results.jsp" />          
                        <forward name="failure" path="/WEB-INF/pages/shared/error.jsp" />
          </action>
-------

This means that when someone types in "/my_action.do" it triggers this action mapping (struts adds ".do" on the end of the value specified in the "path" attribute ). It uses the action specified by the attribute "type" with the form specified in the attribte "name", "input" is where the action should be returned to if the page fails validation and "scope" is the scope where the actionForm is stored. The forward tags declares which JSP the action forwards to once it has completed its logic.

Think of an action as a specialised type of servlet which does all your pre-processing before forwarding on to a jsp using RequestDispatcher.forward() (look this up if you haven't used it before) and the struts-config.xml is where you need to declare the action mapping instead of the web.xml to declare the servlet mapping.

>>(points increased) :)
Thank you, much appreciated. I'm trying to be the first Sage and then Genius in this forum so I need all the points I can get (only 175,000 to Sage and then another 500,000 to Genius!) :-)
bloodredsunCommented:
>>therefore my question is how do I call the action to populate the dropdown when I load the jsp (without interaction from the user) ? Or is 'useBean' the preferred approach for this ?  

Don't use "usebean". The example above should show you that the action would create the data to populate the drop down. It then puts it in the actionform and then the JSP outputs the values from the actionForm.

>> Am I making something simple too  complicated ?
Yep! It's dead simple. Think about it this way

Action - Does all the pre-processing: database access etc
ActionForm - A data transfer object (DTO) used as a container for the information created in the Action so that this info can be accessed in the JSP
JSP - Presentation layer; does no processing but only outputs the data contained in the ActionForm  passed to it by the Action.

Therefore, rather that using javabeans to take the java code out of the jsp, you now use the action to contain all your code.
bloodredsunCommented:
If I'm not being clear, please ask me to clarify any areas...
adlikonAuthor Commented:
Hi, OK, i have the drop down list being populated by an action, this list is a simple jsp that I have created to Include in other jsps using <jsp:include>;

jsp_list.jsp
=======
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>          
<TH align="left" width="92"> Type:</TH>
<TD width="329">
<SELECT size="1" name="cd_type">
<c:forEach var="row" items="${requestScope.RowsFound}">                                     
     <OPTION value="<c:out value='${row.REC_TYPES_REC_K}'/>"> <c:out value='${row.REC_TYPES_REC_DESC}'/> </OPTION>
</c:forEach>
</SELECT>
</TD>      

Now this is a bit tricky because the action has a success forward to the above "jsp snipet", but I want to display a main jsp that includes this jsp snipet ie preload the jsp snipet before it is included at runtime into the main  jsp - how do I do this.? If I call the action /ActionList.do how do I get it to output the success to the jsp snipet first and then load the main jsp ? Or should I first call the main jsp and then somehow as a preload step fire the /ActionList.do without getting the user to click on a button.

My objective is to have this drop down list in serveral jsp forms therefore i am attemtping to design the ddlist as an object I can include in any jsp, the alternative I think would be to hardcode the dropdown list in all my jsp's and have multiple success forwards to them from the one action and somehow parameterise the forward.  have i explained this ok?


                                    
 
adlikonAuthor Commented:
I think I need to use the <BODY onload> paramter to fire my /action.do but am unsure of the syntax -
adlikonAuthor Commented:
The more I think about this I dont see I can achieve this using an action.

heres what i am doing

step 1: action populates a fragment jsp
step 2: main jsp is called with include statement to load the fragment jsp & its result from step 1

if initiate step one via /action.do how do i then initiate step 2 ? will the "jsp:include" statement load the result of step 1 or just a static version ?

what happens when i have multiple fragment jsp's that are populated by actions and that i want to combine on the same main form? For this situation use Bean is seemlingly a lot simpler.
adlikonAuthor Commented:
i have increased the points as I have another question. As I have described above I think this is getting too tricky becaue I want to use include jsp's. Unless you have an idea how I can get this to work then I think useBean is a suitable alternative because it will all fit in my JSP snipets that I want to include. In this case though I want to use forEach as it is neater than <% if {} %> syntax which is mesy and confusing can you advise how I get forEach to work with a use Bean staement ?

thanks
bloodredsunCommented:
>>The more I think about this I dont see I can achieve this using an action.

Using an action is just removing the Java code from your JSPs, just as you do with JavaBeans or custom tags. The difference is that you can the added benefits of a mature MVC framework such as easy re-configuration and validation. You may be correct in saying that the javabean method is best for you. For a simple webapp, it may well be but you notice the benefits when you scaled up to bigger apps.

>>if initiate step one via /action.do how do i then initiate step 2 ? will the "jsp:include" statement load the result of step 1 or just a static version ?

see next answer

>>what happens when i have multiple fragment jsp's that are populated by actions and that i want to combine on the same main form? For this situation use Bean is seemlingly a lot simpler.

If you are using a "composite view" pattern (a main jsp made up of smaller jsps) then your main jsp would call the action or actions and the action would return the html from it's associates JSP. One of the benefits of Struts is that you can use Tiles which is a compositing framework built in.
e.g.
main.jsp
---------
<html>
<head><title>main</title></head>
<body>
<div>
      <jsp:include page="headerAction.do"/>
</div>
<div>
      <jsp:include page="leftNavAction.do"/>
</div>
<div>
      My Content goes here
</div>
<div>
      <jsp:include page="footerAction.do"/>
</div>

</body>
</html>

>>I want to use forEach as it is neater than <% if {} %> syntax which is mesy and confusing can you advise how I get forEach to work with a use Bean staement ?

Good choice. I always use JSTL when I can. Here's how to loop over a list/collection/map/array...

<%@ page import="com.bloodredsun.beans.*" %>
<jsp:useBean id="connectionbean" class="com.bloodredsun.beans.DbConnectionBean" scope="request"/>
<html>
<head><title>C:forEach</title></head>
<body>

<%-- Get the bean from the scope and use dot notation to call the hypothetical getMyList() method which returns an arraylist  that we can loop over--%>

<c:forEach var='alItem' items='${requestScope.connectionbean.mylist}' varStatus='status'>
    Output value of arraylist: <c:out value='${alItem}'/>
</c:forEach>

</body>
</html>

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
adlikonAuthor Commented:
thats great, thanks for your help its all comming together for me .... :-)

points increased

take it easy
bloodredsunCommented:
cheers dude, thanks for the points,  glad to help :-)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JSP

From novice to tech pro — start learning today.