2016-04-01 41 views
1

我的RSS小服務程序爲和HttpServletResponse使用try-with-resource。在某些情況下SomeException被拋出,而生成RSS文件,在這種情況下,我需要一個HTTP狀態500返回給客戶端:try-with-resource vs java.lang.IllegalStateException:在提交響應後無法調用sendError()

try (ServletOutputStream out = response.getOutputStream(); 
    OutputStreamWriter writer = new OutputStreamWriter(out, "utf-8")) { 
     response.setContentType("text/xml"); 

     // Generate RSS here 

    } catch (SomeException e) { 
     response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); 
     return; 
    } 

然而,response.sendError()叫的時候,$出$已達關閉,我得到說IllegalStateException說,響應已被提交(關閉流似乎自動提交響應)。

如果我移動try-block外部的outwriter的初始化,並以finally-block(Java7之前的方式)關閉它們,則會正確發送錯誤代碼。

我想知道是否有辦法繼續使用try-with-resource,如果發生異常,仍然能夠返回錯誤代碼。

謝謝!

+1

您可以使用_outer_ try-with-resources和_inner_ try-catch ... – jtahlborn

回答

1

您不需要關閉自己沒有創建的資源。該容器本身創建了底層的OutputStream,因此也都是負責將其正確關閉。你應該想象它的容器已經在Servlet的doXxx()方法周圍嘗試了資源。另請參見Should I close the servlet outputstream?

不同地說,整個OutputStream試用資源在doXxx()內是不必要的。

只要做到:

try { 
    // Generate RSS here 

    OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), "UTF-8")) { 
    response.setContentType("text/xml"); 

    // Write RSS here. 

} catch (SomeException e) { 
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); 
} 

無關到具體的問題,如果你重新拋出任何checked異常,因爲ServletException,則容器也將全部由自己打理的正確響應代碼和信息。

try { 
    // ... 
} catch (SomeException e) { 
    throw new ServletException(e); 
} 
相關問題