2010-06-09 2 views
2

현재 Jersey/Tomcat을 사용하여 REST 웹 서비스를 개발 중입니다 (그러나 일반적인 서블릿/컨테이너 응답을 환영합니다). 클라이언트가 MySQL 연결에서 많은 양의 데이터를 반환하는 서비스에서 일부 GET 요청을 수행하는 경우.서블릿에서 예기치 않은 요청 처리하기

OOM 예외를 피하기 위해 MySQL 용 스트리밍 모드를 사용합니다.

그러나로드하는 동안 클라이언트가 요청을 중단하면 MySQL 연결이 닫히지 않습니다. 그 후에 서버는 한 번에 하나의 "스트리밍"요청 만 가능하기 때문에 다른 요청을 처리하지 않습니다.

질문은 다음과 같습니다. 요청이 내 서버에서 종료 될 때마다 (보통 또는 비정상적으로) 어떻게 알림을받을 수 있습니까? 어떤 종류의 리스너를 등록 할 수 있습니까? 또는 UncaughtExceptionHandler를 사용 하시겠습니까?

저지에서 예외를 처리하여 "응답"으로 변환하는 방법은 많이 있지만 요청의 조기 종료를 처리하는 방법은 없습니다. 저지 또는 톰캣은 알림없이 내 스레드를 단순히 파괴 할 수도 있습니다. 스레드 인터럽트가 발생할 때마다 내 메서드의 중요한 부분에서 일부 예외를 잡을 수 있습니까? 다른 측면에서 연결을 중단 반면 flush() 또는 close()response.getOutputStream()에서 호출 될 때마다 당신의 도움에 미리

감사합니다, 보통

답변

2

라파엘, IOException가 슬로우됩니다.

일반적으로 DB 연결 (및 기타 리소스) 닫기는 열린 곳의 try 블록의 finally 블록에서 이루어져야합니다. 따라서 예외가 발생하더라도 닫히게됩니다.

이 예제는 어떻게해야 요약 : 출력 스트림 종료 할 필요가

String search = getItSomehow(); 
Connection connection = null; 
PreparedStatement statement = null; 
ResultSet resultSet = null; 

try { 
    connection = database.getConnection(); 
    statement = connection.prepareStatement(SQL_FIND); 
    statement.setString(1, search); 
    resultSet = statement.executeQuery(); 

    if (resultSet.next()) { 
     response.setContentType(resultSet.getString("contentType")); 
     response.setContentLength(resultSet.getInt("contentLength")); // Optional. 
     BufferedInputStream input = null; 
     BufferedOutputStream output = null; 
     try { 
      input = new BufferedInputStream(resultSet.getBinaryStream("content")); 
      output = new BufferedOutputStream(response.getOutputStream()); 
      byte[] buffer = new byte[1024]; 
      for (int length; (length = input.read(buffer)) > 0;) { 
       output.write(buffer, 0, length); 
       output.flush(); 
      } 
     } finally { 
      if (output != null) try { output.close(); } catch (IOException logOrIgnore) {} 
      if (input != null) try { input.close(); } catch (IOException logOrIgnore) {} 
     } 
    } else { 
     response.sendError(HttpServletResponse.SC_NOT_FOUND); 
    } 
} catch (SQLException e) { 
    throw new ServletException("Something failed at SQL/DB level.", e); 
} finally { 
    if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {} 
    if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {} 
    if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {} 
} 
+0

없습니다 - 서블릿이 당신을 위해 그것을 할 것입니다. 또한, PrintWriter를 사용한다면 flush 대신 checkError를 사용하십시오. –

+0

@andrew : http://stackoverflow.com/questions/1829784/should-i-close-the-servlet-outputstream/1829823#1829823 – BalusC