2013-04-27 5 views
0

간단한 Struts2 클래스를 코딩하여 비디오 파일을 다운로드하려고합니다. java.lang.IllegalStateException이 발생했기 때문에 다운로드 대화 상자에서 다운로드를 취소 할 때를 제외하고는 제대로 작동합니다 (페이지가 제대로 작동하고 예외가 기록됨). 의 struts.xml 파일에 정의 된 작업을파일 다운로드 대화 상자의 IllegalStateException

public class FileDownloaderAction extends ActionSupport { 

/** The Constant serialVersionUID. */ 
private static final long serialVersionUID = 1L; 

/** The relative route to the file to download. */ 
private String relRoute; 

/** The name of the file to download. */ 
private String fileName; 

/** The InputStream to be downloaded. */ 
private InputStream fileStreamToDownload; 

/** The size of the file to download. */ 
private long fileSize; 

@Override 
public final String execute() throws Exception { 
    MyUtils mu = new MyUtils(); 

    try { 
     File file = mu.getFile(relRoute + fileName); 

     if (file != null) { 
      fileStreamToDownload = new FileInputStream(file); 
      fileSize = file.length(); 

      return Action.SUCCESS; 
     } else { 
      return Action.ERROR; 
     } 
    } catch (Exception ex) { 
     return Action.ERROR; 
    } 
} 

/** Sets the content disposition. 
* @return the content disposition. 
*/ 
public final String getContentDisposition() { 
    return "attachment;filename=\"" + fileName + "\""; 
} 

/** 
* @return the relRoute 
*/ 
public final String getRelRoute() { 
    return relRoute; 
} 

/** 
* @param mRelRoute the relRoute to set 
*/ 
public final void setRelRoute(final String mRelRoute) { 
    this.relRoute = mRelRoute; 
} 

/** 
* @return the fileStreamToDownload 
*/ 
public final InputStream getFileStreamToDownload() { 
    return fileStreamToDownload; 
} 

/** 
* @param mFileStreamToDownload the fileStreamToDownload to set 
*/ 
public final void setFileStreamToDownload(final InputStream mFileStreamToDownload) { 
    this.fileStreamToDownload = mFileStreamToDownload; 
} 

/** 
* @return the fileName 
*/ 
public final String getFileName() { 
    return fileName; 
} 

/** 
* @param mFileName the fileName to set 
*/ 
public final void setFileName(final String mFileName) { 
    this.fileName = mFileName; 
} 

/** 
* @return the fileSize 
*/ 
public final long getFileSize() { 
    return fileSize; 
} 

/** 
* @param mFileSize the fileSize to set 
*/ 
public final void setFileSize(final long mFileSize) { 
    this.fileSize = mFileSize; 
} 

} 한편

:

<action name="downloadFile" class="org.test.action.FileDownloaderAction" method="execute"> 
    <result name="success" type="stream"> 
     <param name="contentType">application/octet-stream</param> 
     <param name="inputName">fileStreamToDownload</param> 
     <param name="contentDisposition">${contentDisposition}</param> 
     <param name="contentLength">${fileSize}</param> 
     <param name="bufferSize">4096</param> 
     <param name="allowCaching">true</param> 
     <param name="contentCharSet">UTF-8</param> 
    </result> 
    <result name="error">/error.jsp</result> 
</action> 

이 코드의 기반이되는 다음

는 클래스입니다 내가 찾은 몇 가지 예입니다. 예외가 발생할 때 Tomcat이이를 인쇄합니다.

abr 28, 2013 12:11:59 AM org.apache.catalina.core.StandardWrapperValve 
invoke SEVERE: Servlet.service() para servlet default lanzó excepción java.lang.IllegalStateException 
at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:407) 
at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:867) 
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:569) 
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) 
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
at java.lang.Thread.run(Thread.java:722) 

이 예외를 피할 수있는 방법이 있습니까? 사전에

감사합니다.

+0

취소 버튼을 눌렀을 때 어떤 서버 쪽 요청을 보내시겠습니까? –

+0

나는 믿지 않는다. @ dev-blanked가 작성한대로 Cancel을 클릭하면 클라이언트 측에서 발생하지만 서버는 계속 데이터를 보내므로 예외가 발생합니다. 또한, [Stream Result page] (http://struts.apache.org/release/2.0.x/docs/stream-result.html)는 많은 도움이되지 않습니다 ... – dcordonu

+0

@dcordonu 출력을 막을 수 있습니다. 오류를 보내지 않도록 발송자에게 알리는 것입니다. 어쨌든 예외 인터셉터를 통해 예외를 처리 할 수 ​​있습니다. http://stackoverflow.com/questions/16213900/there-is-no-action-mapped-for-action-name-index-how-to-catch-the-exception-bec/16214532#16214532 –

답변

0

응답 파일에 파일 (사례 비디오) 데이터를 쓸 때 저장/취소 대화 상자가 브라우저에서 나타납니다. 브라우저가 파일임을 감지하고 파일 저장 대화 상자를 사용자에게 제공합니다. 사용자가 취소를 선택하면 브라우저에서 서버로의 연결이 취소되므로 서버가 나머지 파일을 응답에 쓰려고 할 때이 예외가 기록됩니다. 이 동작은 믿을 만하다. 취소 조치는 클라이언트 측 (즉, 브라우저 내부)에서 발생하기 때문에 서버에서 수행 할 수있는 작업은 없습니다.

+0

확인, 그게 의미가 있지만, 이것을 모니터링하고 예외가 기록되지 않도록하는 방법이 있습니까? 또는 최소한 전체 오류 추적 대신 사용자 지정 텍스트를 작성하십시오. – dcordonu

+0

@dcordonu 물론 다른 시나리오에서도 같은 예외가 발생할 수 있습니다. 다운로드 비디오 작업이 호출되었음을 기록 할 수 있습니다. 따라서 로그를 통해 위의 스택 추적을 찾아서 비디오 다운로드가 실행되었다는 로그가 나타나면 취소 버튼이 클릭되었다고 결론 내릴 수 있습니다. –

+0

예, 맞습니다. 하지만 사용자가 '취소'버튼을 클릭했음을 감지하려면 어떻게해야합니까? – dcordonu

관련 문제