2011-10-07 3 views
7

struts2-rest-plugin v.2.2.3을 사용하는 struts2 애플리케이션이 있습니다.REST 플러그인이 응답을받지 않는 Struts2에 대한 POST 요청

요청과 액션의 라우팅에 관해서 모든 것이 잘 작동하고 있으며 ModelDriven을 사용하여 JSON과 XML 같은 확장 기능을 사용할 때 직렬화 할 객체를 지정하고 있습니다.

내가 겪고있는 문제는 POST 또는 PUT 요청을 스트럿츠 계층에 보낼 때 빈 응답 만 얻는다는 것입니다.

다음과 같은 동작으로 POST 요청을 보내고 있습니다 : http://localhost:8080/alert-settings!update.json. 나는 그 방법에 breakpoint를 가지고 있고 그것은 호출되고 코드는 실행되고 완료된다. 그 문제가 내가 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; 
} 

이것은 selectTarget() 방법 org.apache.struts2.rest.RestActionInvocation에 있습니다

+0

의 마지막 설정을 볼 수 있지만 내가 대신 DefaultHttpHeaders을 반환하여 응답 코드를 변경에 정착 SUCCESS. POST 및 PUT 요청을 처리하는 방법 일 수 있다고 생각합니다. – noShowP

+0

안녕하세요, struts2-rest-plugin도 사용하고 있으며 JSON 페이로드를 수락하고 모델에 올바르게 매핑하는 데 update() 메소드를 가져 오는 데 문제가 있습니다. 어떻게 그 짓을했는지 공유하니? 감사합니다 .. – shaunlim

답변

4

동일한 문제가 발생했습니다. 당신이 struts.xml 파일에 설정하려고 노력 해요 :

struts.rest.content.restrictToGET = false 

내가이 주위에 방법을 찾을 수 없습니다 the rest plugin docs

1

것은 사실은이 원인이 플러그인 나머지 선 이었다는 것을 알아 냈다. POST, DELETE 및 PUT 요청에 대한 응답 객체를 반환 할 수있는 옵션과 같이 REST 아키텍처를 실제로 따르지 않으므로이 작업이 상당히 짜증나는 경우가 있습니다.

나는 RestActionProxyFactoryRestActionInvocation 확장 등처럼 내 스트럿츠 XML이의 사용을 지정하여이 문제를 해결했다 :이 날 스트럿은 POST 요청 개체를 반환하는 동안 내내 플러그인을 사용할 수 있습니다

<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="restOverride" class="uk.co.ratedpeople.tp.rest.RPRestActionProxyFactory" /> 
<constant name="struts.actionProxyFactory" value="restOverride" /> 

.

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

} 
+0

이 문제를 해결하는 더 좋은 방법이있을 수 있으므로 공유하십시오. – noShowP

0

내가 예를 들어 JSON, XML 및 타일 반환 과거에 혼합 된 결과 유형과 스트럿 작업을 사용했습니다. 컨벤션을 사용하고 있지만 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> 

나중에 특정 작업에 사용되는 여분의 결과 유형의 설정을 가지고있다. 그런 다음 작업 클래스에서 작업 또는 메서드를 사용하여 결과 유형을 설정할 수 있습니다.

액션 등급 : 다른

@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가 포함 된 객체를 반환하면 빈 결과가 나타나거나 결과가 표시되지 않습니다. 나는 종종 자바 타입 (String, int, Boolean 등) 만 반환하고 getter 객체는 포함하지 않는 getters/setter를 사용하여 json 결과에 json 래퍼 객체를 작성하게됩니다. 나는 delegate getters/setters를 사용하여이 문제를 해결했다고 생각하지만 이전 코드로 되돌아 가야 할 것이다.

+0

나는 stvuts2-rest-plugin v.2.2.3을 사용하여 결과를 처리하는 것을 제외하고는 youv가 수행 한 작업을 수행했습니다. 따라서 JsonSuccess 유형을 지정하지 않아도됩니다. URL 끝에 .json을 추가하면 /job.json이 JobAction의 index 메소드를 호출하고 그 결과를 JSON으로 반환합니다. 질문은 요청이 POST 일 때 어떤 동작에서든 아무것도 반환하지 않는 동작과 관련이 있습니다 (POST를 /job.json으로 보내면 어떤 데이터도 반환하지 않고 성공 또는 실패 만 반환합니다). – noShowP