POST request to Struts2 with REST plugin not receiving response

前端 未结 3 1016
终归单人心
终归单人心 2021-01-12 10:22

I have a struts2 application which uses the struts2-rest-plugin v.2.2.3.

Everything is working great when it comes to the routing of the requests to the actions and

3条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-12 11:06

    I actually figured out that it was a line in the rest plugin causing this:

    // don't return any content for PUT, DELETE, and POST where there are no errors
    if (!hasErrors && !"get".equalsIgnoreCase(ServletActionContext.getRequest().getMethod())) {
      target = null;
    }
    

    This is in org.apache.struts2.rest.RestActionInvocation in the selectTarget() method. I find this to be quite annoying as it doesn't really follow the REST architecture, id like the option to be able to return response objects for POST, DELETE and PUT requests in some cases.

    I worked around this by extending RestActionProxyFactory and RestActionInvocation and specifying the use of this in my struts xml like so:

    
    
    

    This allows me to use the struts plugin throughout while returning object on POST requests.

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

提交回复
热议问题