POST request to Struts2 with REST plugin not receiving response
我有一个使用 struts2-rest-plugin v.2.2.3 的 struts2 应用程序。
在将请求路由到操作及其方法方面,一切都很好,我还使用 ModelDriven 来指定在使用 JSON 和 XML 等扩展时要序列化的对象。
我遇到的问题是,当我向 struts 层发送 POST 或 PUT 请求时,我得到一个空响应。
我正在向操作发送一个 POST 请求,如下所示:
在使用 REST 插件时接收来自 POST 请求的响应是否存在已知问题?我到处找,真的找不到任何关于它的东西。
感谢任何帮助,我可以根据要求提供更多详细信息。
我遇到了同样的问题。您是否尝试在 struts.xml 文件中设置:
1 | struts.rest.content.restrictToGET = false |
查看其余插件文档中的最后一个设置
我实际上发现这是其余插件中的一行导致此:
1 2 3 4 | // don't return any content for PUT, DELETE, and POST where there are no errors if (!hasErrors && !"get".equalsIgnoreCase(ServletActionContext.getRequest().getMethod())) { target = null; } |
这是在
我通过扩展
1 2 | <bean type="com.opensymphony.xwork2.ActionProxyFactory" name="restOverride" class="uk.co.ratedpeople.tp.rest.RPRestActionProxyFactory" /> <constant name="struts.actionProxyFactory" value="restOverride" /> |
这允许我在 POST 请求中返回对象时始终使用 struts 插件。
RestActionProxyFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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; // } } } |
我过去使用过具有混合结果类型的 struts 操作,例如返回 json、xml 和图块。我不确定这是否是推荐的方法,但即使使用了约定,它也需要使用 struts.xml 进行一些配置。也许您已经这样做了,但不确定提供的信息不足。
Struts.xml 设置:
1 2 3 4 5 6 7 8 9 10 | <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> |
我已经设置了额外的结果类型,以便稍后用于特定操作。在动作类中,您可以通过动作或方法设置结果类型。
动作类:
1 2 3 4 5 6 7 8 | @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 package器对象以用于我的 json 结果,其中 getter/setter 只返回 java 类型(String、int、Boolean 等)而不是嵌入式对象。我认为已经使用委托 getter/setter 解决了这个问题,但我必须回去看看一些旧代码。