I'm a beginner to struts2. I created a dynamic web project on eclipse so as to using struts 2. There are something wrong with it, and i just don not know why. the Console output is:
There is no Action mapped for namespace [/modeldriven] and action name [datosUsuario] associated with context path [/FormularioMD]. - [unknown location]
at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185)
at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:37)
at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:554)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:306)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:323)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1719)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I have the following directory structure:
Resources
--src
--action and model.
WebContent
--modeldriven
--nuevo-usuario.jsp
--datos-usuario.jsp
--WEB-INF
--lib
--web.xml
My JSP file to input data:
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<s:form action="datosUsuario">
<s:textfield name="nombre" label="Nombre" />
<s:textfield name="username" label="Username" />
<s:password name="password" label="Password" />
<s:textfield name="edad" label="Edad" />
<s:textfield name="fechaNacimiento" label="Fecha de Nacimiento" />
<s:submit value="Enviar" />
</s:form>
</body>
</html>
My action class, NOTE: I using annotations:
package com.java.rmo.controladores;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import com.java.rmo.modelos.Usuario;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
@Namespace(value = "/modeldriven")
@Action(value = "datosUsuario", results={
@Result(name="success", location="/modeldriven/datos-usuario.jsp")
})
public class UsuarioAction extends ActionSupport implements ModelDriven<Usuario> {
private Usuario usuario = new Usuario();
public Usuario getModel(){
return usuario;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
My JSP file to show result:
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Nombre: <strong><s:property value="nombre" /></strong> <br />
Username: <strong><s:property value="username" /></strong> <br />
Password: <strong><s:property value="password" /></strong> <br />
Edad: <strong><s:property value="edad" /></strong> <br />
Fecha de Nacimiento: <strong><s:property value="fechaNacimiento" /></strong>
</body>
</html>
My web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>struts2HelloWord</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
So, can anybody help me?, thank's.
The Convention plugin, as the name suggests, works using naming conventions.
It searches for certain packages, and inside them, it looks for actions with certain names, or implementing a specific interface.
From the documentation:
By default, the Convention plugin will find all action classes that implement
com.opensymphony.xwork2.Action
or whose name ends with the word Action in specific packages.These packages are located by the Convention plugin using a search methodology. First the Convention plugin finds packages named
struts
,struts2
,action
oractions
. Any packages that match those names are considered the root packages for the Convention plugin. Next, the plugin looks at all of the classes in those packages as well as sub-packages and determines if the classes implementcom.opensymphony.xwork2.Action
or if their name ends withAction
(i.e.FooAction
)
Since your package is:
package com.java.rmo.controladores;
the Convention plugin won't search for anything inside it.
You have two options:
Refactor your package to include one of the names requested by the plugin, for example:
package com.java.rmo.actions;
Add your package to the list of packages the plugin will scan for actions, as described here .
I'd personally go with the first solution... stick to the default, and avoid yourself possible problems or unwanted side effects.