这是我的文件。
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<!-- restrictToGET to false makes the response to be of JSON type when request if of type POST, PUT, DELETE-->
<constant name="struts.rest.content.restrictToGET" value="false"/>
<constant name="struts.convention.action.suffix" value="Controller"/>
<constant name="struts.convention.action.mapAllMatches" value="true"/>
<constant name="struts.convention.default.parent.package" value="rest-default"/>
<constant name="struts.convention.package.locators" value="action"/>
<constant name="struts.enable.SlashesInActionNames" value="true"/>
<constant name="struts.mapper.alwaysSelectFullNamespace" value="false"/>
<constant name="struts.patternMatcher" value="regex"/>
<constant name="struts.matcher.appendNamedParameters" value="true"/>
<package name="action" namespace="/" extends="rest-default,json-default">
<interceptors>
<interceptor name="json" class="org.apache.struts2.json.JSONInterceptor"/>
<interceptor-stack name="jsonStack">
<interceptor-ref name="json"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<action name="hello" class="com.wildcard.action.HelloController">
<interceptor-ref name="jsonStack"/>
<result type="json">
<param name="root">uid</param>
</result>
</action>
<action name="hello/*" class="com.wildcard.action.HelloController">
<interceptor-ref name="jsonStack"/>
<param name="id">{1}</param>
<result type="json">
<param name="root">uid</param>
</result>
</action>
</package>
</struts>
HelloController.java
package com.wildcard.action;
import com.opensymphony.xwork2.ModelDriven;
import com.wildcard.model.Hello;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
public class HelloController implements ModelDriven<Object> {
private Hello hello = new Hello();
private String id;
private String uid;
private Object model = new Object();
public HttpHeaders index() {
hello.setName("index");
System.out.println("index() : " + hello);
System.out.println("index() uid: " + uid);
return new DefaultHttpHeaders("index");
}
public HttpHeaders show() {
hello.setName("show");
System.out.println("show() : " + hello);
System.out.println("show() id: " + id);
System.out.println("show() uid: " + uid);
return new DefaultHttpHeaders("show");
}
public HttpHeaders create() {
//hello.setName("create");
System.out.println("create() : " + hello);
System.out.println("create() id: " + id);
System.out.println("create() uid: " + uid);
return new DefaultHttpHeaders("create");
}
public HttpHeaders update() {
hello.setName("update");
System.out.println("update() : " + hello);
System.out.println("update() id: " + id);
System.out.println("update() uid: " + uid);
return new DefaultHttpHeaders("update");
}
public HttpHeaders destroy() {
hello.setName("destroy");
System.out.println("destroy() : " + hello);
System.out.println("destroy() id: " + id);
System.out.println("destroy() uid: " + uid);
return new DefaultHttpHeaders("destroy");
}
@Override
public Object getModel() {
model = hello;
return model;
}
public void setModel(Object model) {
this.model = model;
}
public Hello getHello() {
return hello;
}
public void setHello(Hello hello) {
this.hello = hello;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
}
Hello.java
package com.wildcard.model;
public class Hello {
private String name;
public Hello() {
}
public Hello(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hello{" +
"name='" + name + '\'' +
'}';
}
}
当我发送请求GET
[ /hello.json
, /hello/{id}.json
], POST [ /hello.json
], PUT
[ /hello/{id}.json
], DELETE
[ /hello/{id}.json
] 时,没有JSON Body
,它工作正常。当我添加JSON Body
到上述请求时,只有以下内容有效GET
,,POST
[ /hello.json
]。当我添加{id}
到 URL 路径时,我收到以下错误。
> HTTP ERROR: 500 Unable to show problem report:
>
> freemarker.core.InvalidReferenceException: The following has evaluated
> to null or missing:
>
> ==> rootloc.URI [in template "org/apache/struts2/dispatcher/error.ftl" at line 84, column 15]
>
> ---- Tip: It's the step after the last dot that caused this error, not those before it.
> ---- Tip: If the failing expression is known to legally refer to something that's sometimes null or missing, either specify a default
> value like myOptionalVar!myDefault, or use <#if
> myOptionalVar??>when-present<#else>when-missing</#if>. (These only
> cover the last step of the expression; to cover the whole expression,
> use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
> ----
>
> ---- FTL stack trace ("~" means nesting-related):
> - Failed at: ${rootloc.URI} [in template "org/apache/struts2/dispatcher/error.ftl" at line 84, column 13]
> ----
>
> Class: freemarker.core.InvalidReferenceException File:
> InvalidReferenceException.java Method: getInstance Line: 134 -
> freemarker/core/InvalidReferenceException.java:134:-1
> RequestURI=/wildcard_sample/hello/2.json
>
> Powered by Jetty://
Java 堆栈跟踪(针对程序员):
freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above ...]
at freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:134)
at freemarker.core.EvalUtil.coerceModelToTextualCommon(EvalUtil.java:481)
at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:401)
at freemarker.core.EvalUtil.coerceModelToStringOrMarkup(EvalUtil.java:370)
at freemarker.core.DollarVariable.calculateInterpolatedStringOrMarkup(DollarVariable.java:100)
at freemarker.core.DollarVariable.accept(DollarVariable.java:63)
at freemarker.core.Environment.visit(Environment.java:334)
at freemarker.core.Environment.visit(Environment.java:340)
at freemarker.core.Environment.visit(Environment.java:340)
at freemarker.core.Environment.process(Environment.java:313)
at freemarker.template.Template.process(Template.java:383)
at org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler.handleErrorInDevMode(DefaultDispatcherErrorHandler.java:118)
at org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler.handleError(DefaultDispatcherErrorHandler.java:76)
at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:923)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:589)
at org.apache.struts2.dispatcher.ExecuteOperations.executeAction(ExecuteOperations.java:79)
at org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:141)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:726)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:206)
at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:648)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)