2009-06-25 2 views
0

일부 요청 매개 변수를 취하고 XML 데이터를 반환하는 원격 서비스를 호출 한 다음 XSL을 통해 데이터를 변환하고 그 결과를 반환하여 AJAX 요청에 응답하는 struts2 작업이 있습니다. 스트림 결과를 통한 XHTML. 응답은 주어진 매개 변수에 따라 다릅니다.struts2 액션을 사용하여 동시에 많은 AJAX 요청 처리하기

public class ServiceHandler extends ActionSupport { 
    private ByteArrayInputStream inputStream; 

    public String execute(){ 

     String response = ""; 

     // Get request parameters 
     // Make a request to a remote server via an http connection 
     // Transform result via XSL 

     //uses dom4j for XML/XSL stuff 
     //this should never be empty 
     response = resultDoc.asXML(); 

     inputStream = new ByteArrayInputStream(response.getBytes()); 
     return "success"; 
    } 

    public ByteArrayInputStream getInputStream(){ 
     return inputStream; 
    } 
} 

을 그리고 여기에 중요한 struts.xml 비트입니다 : 물건의 무리와 함께 작업 클래스를 꺼낸 다음

입니다

<action name="sh" class="ServiceHandler"> 
    <result name="success" type="stream"> 
     <param name="contentType">text/html</param> 
     <param name="contentDisposition">inline;filename="response.html"</param> 
     <param name="bufferSize">1024</param> 
     <param name="allowCaching">false</param> 
    </result> 
</action> 

내 문제가 있음을 나는 여러 요청이있을 때 동시에 ServiceHandler 액션을 호출 할 때가 있습니다. 가끔씩 응답이 완전히 비어있는 경우도 있습니다 (때로는 발생하지 않아야 함). 처음에는 응답이 끊어 지거나 끝이 무작위로 끝나기도하고 때로는 응답이 전환되기도합니다. A가 잘못된 응답을 수신했습니다. JAX 요청자.

이 문제는 스레드 안전성 문제이므로 모든 중요한 변수 정의를 인스턴스 변수가 아니며 모든 사용자가 공유 할 수 있도록 execute() 메서드로 옮겼습니다. 인스턴스 변수 인 유일한 재미있는 변수는 inputStream입니다. 저는이 문제를 내 문제의 원인으로보고 있습니다.

inputStream 변수가 스레드로부터 안전하도록 만드는 방법이 있습니까? 아니면 다른 해결책이 있습니까?

답변

0

정확한 방향으로 나를 이끌어 준 Henning에게 감사드립니다. struts2 문서에서 언급되지 않았기 때문에 응답 출력 스트림에 직접 쓰는 것을 생각하지 않았습니다.

출력 스트림에 직접 응답을 쓰는 이점은 inputStream에 대한 인스턴스 객체를 만들 필요가 없다는 것입니다. 이렇게하면 모든 데이터가 다른 스레드로부터 안전 한 execute() 메서드에 유지됩니다.

다음은 출력 스트림에 직접 쓰고 null 결과를 반환하는 수정 된 작업 클래스입니다.

import javax.servlet.http.HttpServletResponse; 
import org.apache.struts2.ServletActionContext; 

public class ServiceHandler extends ActionSupport { 
    public String execute(){ 

     String response = ""; 

     // Get request parameters 
     // Make a request to a remote server via an http connection 
     // Transform result via XSL 

     //uses dom4j for XML/XSL stuff 
     //this should never be empty 
     response = resultDoc.asXML(); 

     HttpServletResponse httpResponse = ServletActionContext.getResponse(); 
     try{ 
      httpResponse.getOutputStream().print(response); 
     } 
     catch(IOException e){ 
      return "failure"; 
     } 

     return null; 
    } 
} 

이것은 내가 가지고있는 문제를 해결 한 것으로 보입니다.

0

Struts 1에만 익숙하지만 DonwloadAction을 살펴보십시오. 또는 일반 struts Action을 사용하여 결과를 직접 응답 객체에 쓴 다음 전달을 null로 반환합니다.

0

저는 Struts 2를 전혀 사용하지 않지만 실제로 "성공"결과를 반환해야하고 출력물에 직접 쓸 방법이없는 경우 ThreadLocal을 사용하여 좋은 결과를 얻으실 수 있습니다. 현재의 thread에 로컬하게 스트림합니다. (패턴에 대한 자세한 내용은 스레드 로컬 저장소의 Wikipedia article도 참조하십시오.)

+0

나는 "성공"을 돌려 줄 필요가없고, 할 수있는 것과 할 수없는 한 struts2에 의해서만 제약을 받는다. 인스턴스 변수를 사용하지 않고도 직접 출력 할 수있는 방법을 찾을 수 있다면 그렇게 할 것입니다. –

+0

이 작업을 수행하는 방법을 찾았으며 직접 작성하면 내 문제가 해결 된 것으로 보입니다. –