今天遇到这样一个问题:
调用http://127.0.0.1:8080/StrustTEST2/helloWorld
java.lang.NoSuchMethodException: com.test.strutsAction.HelloWorldAction.index()
struts.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 搜索包路径 -->
<constant name="struts.convention.package.locators" value="example,strutsAction" />
</struts>
web.xml加入以下属性:
<display-name>Struts 2 Rest Example</display-name>
<!-- Filters -->
<!-- START SNIPPET: filter -->
<filter>
<filter-name>action2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>struts-default.xml,struts-plugin.xml,struts/struts.xml,classpath*:struts/struts_*.xml</param-value>
</init-param>
</filter>
<!-- END SNIPPET: filter -->
<filter-mapping>
<filter-name>action2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
struts.properties :
struts.i18n.reload=true
struts.configuration.xml.reload=true
struts.multipart.maxSize=5597152
struts.messages.invalid.token =\u5BF9\u4E0D\u8D77\uFF0C\u4E0D\u80FD\u91CD\u590D\u63D0\u4EA4\u6570\u636E
java:
public class HelloWorldAction extends ActionSupport {
private static final Log log = LogFactory.getLog(HelloWorldAction.class);
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Action(value="/helloWorld",results={@Result(name="success",location="/demo1/demo2.jsp"),@Result(name="fail",location="/demo1/demo3.jsp")})
public String getHelloWorld(){
if(log.isDebugEnabled()){
log.debug("调用helloWorld成功,ID=="+id);
}
HttpServletRequest request = ServletActionContext.getRequest();
id=request.getParameter("id");
if(id!=null){
request.setAttribute("id", id);
if(id.equals("1")){
return "success";
}else{
return "fail";
}
}
return this.SUCCESS;
}
}
按以往的理解 为了实现项目的零配置,采用struts2的注解方式进行配置,会直接调getHelloWorld方法。
那么为何会报错呢?
看了Struts2的调用全过程,发现其实调用mapper的时候 是直接指向org.apache.struts2.dispatcher.mapper.Restful2ActionMapper 而不是DefaultActionMapper,
这样就导致了调用到rest里面的
if (mapping.getMethod() == null) {
if (lastSlashPos == actionName.length() - 1) {
if (isGet(request)) {
mapping.setMethod("index");
} else if (isPost(request)) {
mapping.setMethod("create");
}
}
所以直接报NoSuchMethodException。
可配置文件中没有配置支持Restful2ActionMapper。
那是否struts2.3.24中jar包有插件直接支持呢?
果然发现了:struts2-rest-plugin-2.3.24.jar 这个包中的:struts-plugin.xml
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="rest" class="org.apache.struts2.rest.RestActionProxyFactory" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="rest" class="org.apache.struts2.rest.RestActionMapper" />
<constant name="struts.mapper.class" value="rest" />
这个导致了Restful2ActionMapper的调用。
下面是解决方法:
第一种:
struts.properties :添加mapper指向
struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMappe
第二种删除struts2-rest-plugin-2.3.24.jar即可解决