HTTP 404 - 没有为名称空间 [/modeldriven] 映射的操作和与上下文路径 [/FormularioMD] 关联的操作名称 [datosUsuario]

HTTP 404 - There is no Action mapped for namespace [/modeldriven] and action name [datosUsuario] associated with context path [/FormularioMD]

我是 struts2 的初学者。我在 eclipse 上创建了一个动态 web 项目,以便使用 struts 2. 它有问题,我只是不知道为什么。控制台输出是:

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)

我的目录结构如下:

Resources
--src
  --action and model.
WebContent
--modeldriven
  --nuevo-usuario.jsp
  --datos-usuario.jsp
--WEB-INF
  --lib
  --web.xml

我的JSP文件输入数据:

<%@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>

我的操作 class,注意: 我使用注释:

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;
     }
}

我的 JSP 文件显示结果:

<%@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>

我的 web.xml 文件:

<?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>

所以,有人可以帮助我吗?谢谢。

Convention 插件,顾名思义,使用命名约定工作。

它搜索某些包,并在其中查找具有特定名称或实现特定接口的操作。

来自 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 or actions. 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 implement com.opensymphony.xwork2.Action or if their name ends with Action (i.e. FooAction)

因为您的包裹是:

package com.java.rmo.controladores;

Convention 插件不会在其中搜索任何内容。

你有两个选择:

  • 重构您的包以包含插件请求的名称之一,例如:

    package com.java.rmo.actions;

  • 将您的包添加到插件将扫描操作的包列表中,如here所述。

我个人会选择第一个解决方案...坚持默认,避免自己可能出现的问题或不必要的副作用。