对REST插件没有收到响应的Struts2的POST请求
我有一个使用struts2-rest-plugin v.2.2.3的struts2应用程序。对REST插件没有收到响应的Struts2的POST请求
当涉及到将请求路由到动作及其方法时,所有工作都很好,而且我还使用ModelDriven指定要在使用JSON和XML等扩展时序列化的对象。
我遇到的问题是,当我发送POST或PUT请求到struts层时,我只是得到一个空的响应。
我正在发送POST请求,如下所示:http://localhost:8080/alert-settings!update.json
。我在该方法中有一个断点,它被调用并且代码运行并完成。我有一种感觉,问题可能是我试图使用ModelDriven接口将回复发送给我,由于某种原因,其余插件不喜欢这样,但我不知道它为什么会这样。
在使用其余插件时,是否存在接收POST请求响应的已知问题?我到处寻找,真的找不到它。
任何帮助表示赞赏,我可以根据要求提供更多细节。
其实我想通了,这是在其他线路插件造成的:
// don't return any content for PUT, DELETE, and POST where there are no errors
if (!hasErrors && !"get".equalsIgnoreCase(ServletActionContext.getRequest().getMethod())) {
target = null;
}
这是org.apache.struts2.rest.RestActionInvocation
在selectTarget()
方法。我觉得这很烦人,因为它并不真正遵循REST体系结构,就像在某些情况下可以为POST,DELETE和PUT请求返回响应对象一样。
我工作围绕这通过扩展RestActionProxyFactory
和RestActionInvocation
并指定使用这在我的支柱XML像这样:
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="restOverride" class="uk.co.ratedpeople.tp.rest.RPRestActionProxyFactory" />
<constant name="struts.actionProxyFactory" value="restOverride" />
这让我使用Struts插件贯穿而在POST请求返回的对象。
RestActionProxyFactory
public class RPRestActionProxyFactory extends RestActionProxyFactory {
@Override
public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) {
if (namespace.startsWith(this.namespace)) {
ActionInvocation inv = new RPRestActionInvocation(extraContext, true);
container.inject(inv);
return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
} else {
return super.createActionProxy(namespace, actionName, methodName, extraContext, executeResult, cleanupContext);
}
}
}
RestActionInvocation
public class RPRestActionInvocation extends RestActionInvocation {
public RPRestActionInvocation(Map extraContext, boolean pushAction) {
super(extraContext, pushAction);
}
@SuppressWarnings("unchecked")
@Override
protected void selectTarget() {
// Select target (content to return)
Throwable e = (Throwable)stack.findValue("exception");
if (e != null) {
// Exception
target = e;
hasErrors = true;
} else if (action instanceof ValidationAware && ((ValidationAware)action).hasErrors()) {
// Error messages
ValidationAware validationAwareAction = ((ValidationAware)action);
Map errors = new HashMap();
if (validationAwareAction.getActionErrors().size() > 0) {
errors.put("actionErrors", validationAwareAction.getActionErrors());
}
if (validationAwareAction.getFieldErrors().size() > 0) {
errors.put("fieldErrors", validationAwareAction.getFieldErrors());
}
target = errors;
hasErrors = true;
} else if (action instanceof ModelDriven) {
// Model
target = ((ModelDriven)action).getModel();
} else {
target = action;
}
// don't return any content for PUT, DELETE, and POST where there are no errors
// if (!hasErrors && !"get".equalsIgnoreCase(ServletActionContext.getRequest().getMethod())) {
// target = null;
// }
}
}
可能有更好的方法来解决这个问题,所以请分享,如果有的话。 – noShowP
我已经使用在过去的混合结果类型,返回JSON,XML和瓷砖例如Struts动作。我不确定是否推荐这样做,但即使使用约定,也需要使用struts.xml进行一些配置。也许你已经这样做了,不确定是否没有足够的信息来说明。
struts.xml的设置:
<constant name="struts.convention.default.parent.package" value="restful"/>
<package name="restful" extends="rest-default, struts-default, json-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult" />
<result-type name="json" class="com.googlecode.jsonplugin.JSONResult"/>
</result-types>
....
</package>
我已经安装额外的结果类型将在后面的具体行动中。在动作类中,您可以通过操作或方法来设置结果类型。
Action类:
@Results({
@Result(name = "JsonSuccess", type = "json"),
@Result(name = "success", type = "tiles", location = "/tickets.tiles")
})
public class EventController extends RestActionSupport implements ModelDriven<EventBean>{
...
}
别的东西需要注意的JSON结果,我注意到,当我有一个序列化的对象返回的结果是,如果该对象包含与其他复杂的对象getter/setter返回嵌入对象,我会经常收到一个空结果或没有结果。我经常最终编写json包装器对象,用于我的json结果,其getter/setter只返回java类型(String,int,Boolean等),而不是嵌入式对象。我认为使用委托getter/setter解决了这个问题,但我必须回头看看一些旧代码。
我已经完成了你在这里完成的任务,除了我已经使用了struts2-rest-plugin v.2.2.3来处理结果。因此,您不需要指定JsonSuccess类型,只需将.json添加到url的末尾,以便/job.json将调用JobAction的索引方法并以JSON格式返回其结果。这个问题具体到它的行为,当请求是一个POST时,它不会从任何操作返回任何内容(所以POST到/job.json不会返回任何数据,只是成功或失败)。 – noShowP
我找不到解决的办法上一次的设置,但我对通过返回DefaultHttpHeaders而不是改变响应代码解决SUCCESS。我认为这可能是POST和PUT请求的方式。 – noShowP
嗨,我正在使用struts2-rest-plugin,并且无法使update()方法接受JSON有效内容并将其正确映射到模型。你介意分享你是如何做到的吗?谢谢.. – shaunlim