Help coderanch get a
new server
by contributing to the fundraiser
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Struts mapping problem: "No action instance for path __ could be created"

 
Ranch Hand
Posts: 66
3
Netbeans IDE Notepad Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi! I'm trying to setup up a basic web project that does some pretty basic stuff like keep track of variables and pass them from one page to another, but it's been... Uncooperative.

It's throwing an error I've never even heard of:

No action instance for path /AddPerson could be created

Also, I'm getting this error in the Tomcat server output in Netbeans:

Cannot retrieve mapping for action: "/AddPerson"

Also this:

com.servlets.AddPerson cannot be cast to org.apache.struts.action.Action

There is another thread on here about this exact same issue, but the responses were inconclusive. The OP never said if their problem was resolved, and although someone did say someone's advice helped them, they don't say whose advice it was. Also I've looked into all the stuff mentioned in the comments there, and it all appears to be unrelated.

This is the other thread:
https://coderanch.com/t/52847/Struts/action-instance-path-userRegistration-created

This is the form declaration in the JSP page, which is called AddPerson.jsp

<html:form method="post" action="/AddPerson">
<html:text property="name" />
<html:text property="sheep" />
<html:submit />
</html:form>

And this is my action mapping thing, in struts-config.xml

<action
path="/AddPerson"
type="com.servlets.AddPerson"
name="AddPerson"
input="/AddPerson.jsp">
<forward name="name" path="/ConfirmAdd.jsp" />
<forward name="sheep" path="/ConfirmAdd.jsp" />
</action>

So I'm a little confused about what exactly it's having issues finding? I'm trying to learn all this in a hurry, so I may have some pretty fundamental things wrong here, but if I'm getting this right:

The form on the JSP page is calling an action called "AddPerson" on submit, and it's looking for that action in the struts-config file because the web.xml tells it to handle 'action' by looking there, and the declaration in that file directs it to an ActionForm located at com.servlets.AddPerson so it can do stuff with the inputs from the JSP form if needed?

Also if I'm not mistaken, the program the way I have it set up isn't actually using any java code I've written, it just needs it because it needs to use the servlet methods that the java class got from extending org.apache.struts.action.ActionForm?

So... Do I have *any* of this right? And what exactly is it having problems finding?
 
Alex Lieb
Ranch Hand
Posts: 66
3
Netbeans IDE Notepad Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I fixed it!

It couldn't make an "action instance" for the path "/AddPerson" because it wasn't actually finding my action mapping declaration. I misunderstood the purpose of the "Path" parameter for action declarations.

So apparently all these parameters in the action declaration do things, and I'm still a little fuzzy on exactly what they do, but here's what I worked out:

In your struts config you also declare a Form Bean, which is more important here than I thought.

The form bean stores the values from the fields on the jsp page.

The form bean's type parameter should refer to the java class which is designed to hold your data, so it should have getter and setter methods that match up with all the fields on your jsp page.
The form bean's name parameter is what the action declaration references so it knows where to try to store the data from the jsp page, name it anything. It's not pointing at anything, it's providing a reference point so other things can point to it.

The action declaration:
The name parameter tells it which formBean to try to use to store the values it gets from the jsp page's form elements.
The type parameter should point to a different java class that verifies that handles errors in the field input and executes whatever back-end code you want executed when the 'submit' button is clicked.
The input parameter should say the name of the jsp page you're getting the values *from*.
The path parameter confused me for the longest time because I thought it was an outward-looking parameter, but it turns out "path" is just a marker that other elements use to find that specific action declaration. So you can make it anything, but whatever you call it, this is what you use to tell your form element *on your jsp page* what action to use when the user hits 'submit'.

Also, forwards are interesting. There are some circumstances in which you *do* include forward definitions in your action mapping declaration, but I don't really know why yet; I think it's mostly for error handling purposes, but anyway; generally you won't do that.

There's methods in the back-end java class you can call to tell the thing to look for a "forward" in the "Global forwards" list on the struts-config and use it.

Forwards can be as simple as just a name (the thing you use to tell the back-end java what "forward" to use) and a path (what page to send the user to if that "forward" is used).

Also, some other things; because I listed an action that uses struts to pass info to the back end, I technically didn't need to clarify that method="post" in my form either.

So here's what it looks like now:

This is the relevant section in my struts-config.xml:

<form-beans>
<form-bean name="addPersonSubmit" type="com.Person.Person"/>
<form-bean name="EditPerson" type="com.servlets.EditPerson"/>
<form-bean name="AddPerson" type="com.servlets.AddPerson"/>
</form-beans>

<global-exceptions>
</global-exceptions>

<global-forwards>
<forward name="welcome" path="/Welcome.do"/>
<forward name="addPersonSuccess" path="/ConfirmAdd.jsp" />
</global-forwards>

<action-mappings>
<action
name="addPersonSubmit"
validate="true"
type="com.servlets.addPersonSubmit"
input="/AddPerson.jsp"
path="/addPersonPath">
</action>
</action-mappings>

This is how the front-end form is set up on the jsp page:

<html:form action="/addPersonPath">
<html:text property="name" />
<html:text property="sheep" />
<html:submit />
</html:form>

This is the java class at com.servlets.addPersonSubmit, but to clarify; not all of it is actually necessary. The text in violet could be removed and nothing would change from the user's perspective unless they refreshed their session; the other stuff there points to more back-end stuff I added to store the data entered locally so when you enter data, you can come back later and request it and it'll persist from session to session. Also I'm pretty sure it checks for errors but doesn't actually do anything special if it finds them. If I wanted more detailed error checking, I could make it redirect back to the same page or something, or have it do something else, but I think I'll worry about that later.

package com.servlets;

import javax.servlet.http.HttpServletRequest;
import com.Person.Person;
import com.Person.editLocalRecords;

import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import com.fileActions.readwrite;

public class addPersonSubmit extends org.apache.struts.action.Action{

public addPersonSubmit() {
super();
}

public ActionForward execute(ActionMapping actionMapping
, ActionForm actionForm
, HttpServletRequest servletRequest
, HttpServletResponse servletResponse)
{
ActionForward forward = null;
forward = actionMapping.findForward("addPersonSuccess");

Person FormPerson = new Person();
editLocalRecords editor = new editLocalRecords();

String name = FormPerson.getName();
String sheep = FormPerson.getSheep();
FormPerson.generateID();
int ID = FormPerson.getID();
editor.createPersonRecord(ID, name, sheep);

return forward;
}

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
{
Person FormPerson = new Person();
ActionErrors errors = new ActionErrors();
if (FormPerson.getName() == null || FormPerson.getName().length() < 1) {
errors.add("name", new ActionMessage("error.name.required"));
}
if (FormPerson.getSheep() == null || FormPerson.getSheep().length() < 1) {
errors.add("sheep", new ActionMessage("error.sheep.required"));
}
return errors;
}

}

And this is the java class at com.Person.Person. Technically I only need the getter and setter methods for name and sheep; I only put ID in as an attribute of "person" because it was part of what I mentioned earlier with recording what the user enters locally.

package com.Person;
import com.fileActions.readwrite;
import com.fileActions.readwrite;
import java.util.Scanner;

public class Person implements java.io.Serializable
{
private String name;
private String sheep;
private int ID;

public String getName() {
return name;
}

public void setName(String string) {
name = string;
}

public String getSheep() {
return sheep;
}

public void setSheep(String string) {
sheep = string;
}

public int getID() {
return ID;
}

public void setID(int a) {
ID=a;
}

public void setID(String a){
ID=Integer.parseInt(a);
}

public void generateID(){
generateID gen = new generateID();
int toSet=gen.nextID();
if(toSet==0){
System.out.println("Something broke.");
}
else
{
ID=toSet;
}
}
}
 
It is difficult to free fools from the chains they revere - Voltaire. tiny ad:
We need your help - Coderanch server fundraiser
https://coderanch.com/t/782867/Coderanch-server-fundraiser
reply
    Bookmark Topic Watch Topic
  • New Topic