程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> 簡單解決復雜的Oracle IAS問題

簡單解決復雜的Oracle IAS問題

編輯:Oracle數據庫基礎

筆者做了一個小的系統輔助功能,可以周期性訪問某個URL、執行某個SQL語句 or 執行某個系統命令。

執行SQL語句和系統命令比較簡單,這裡不再詳述,主要說一下訪問某個URL。

實際上JDK自身已有工具類用於創建HTTP請求,類名是:Java.Net.HttpURLConnection,但考慮到基礎類通常比較粗糙,很多情況要自己考慮和處理,就轉頭去Google了下,發現果然有開源的工具包可以使用,幾個工具包中以HttpClIEnt較為常用,而且是apache的東東,於是決定采用HttpClIEnt。

從apache上down了包commons-httpclient-3.1.jar和commons-codec-1.3.jar兩個包,後者是HttpClIEnt依賴的包。

幫助寫的很好,即便是像我這樣英文很爛,也能很快上手。

public boolean visitURL(String url) {

// Commons HttpClIEnt 3.1
HttpClient client = new HttpClIEnt();
HttpMethod method = new GetMethod(url);

// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));

boolean rs = false;

try {

// Execute the method.
int statusCode = clIEnt.executeMethod(method);

if (statusCode != HttpStatus.SC_OK) {
logger.error("Method failed: " + method.getStatusLine());
}
else {
rs = true;   
}

} catch (HttpException e) {
logger.error("Fatal protocol violation: " + e.getMessage());
} catch (IOException e) {
logger.error("Fatal transport error: " + e.getMessage());
} finally {
// Release the connection.
method.releaseConnection();
}

return rs;
}

本機Tomcat下run一下,工作正常,隨即丟到服務器(Oracle IAS環境)上測試,程序應該出乎意料的報了個錯。

09/03/16 19:03:43 Java.lang.NoClassDefFoundError
09/03/16 19:03:43 at org.apache.commons.httpclIEnt.HttpMethodBase.writeRequestLine(HttpMethoDBase.Java:2015)
09/03/16 19:03:43 at org.apache.commons.httpclIEnt.HttpMethodBase.writeRequest(HttpMethoDBase.Java:1864)
09/03/16 19:03:43 at org.apache.commons.httpclIEnt.HttpMethodBase.execute(HttpMethoDBase.Java:975)
09/03/16 19:03:43 at org.apache.commons.httpclIEnt.HttpMethodDirector.executeWithRetry(HttpMethodDirector.Java:368)
09/03/16 19:03:43 at org.apache.commons.httpclIEnt.HttpMethodDirector.executeMethod(HttpMethodDirector.Java:164)
09/03/16 19:03:43 at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClIEnt.Java:437)
09/03/16 19:03:43 at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClIEnt.Java:324)
09/03/16 19:03:43 at com.zbht.util.TimerTaskManager.runURLTask(TimerTaskManager.Java:237)
09/03/16 19:03:43 at _system._timer__task._test._JSPService(_test.Java:182)
09/03/16 19:03:43 at com.orionserver.http.OrionHttpJSpPage.service(OrionHttpJSPPage.Java:59)
09/03/16 19:03:43 at Oracle.jsp.runtimev2.JSpPageTable.service(JSPPageTable.Java:462)
09/03/16 19:03:43 at Oracle.jsp.runtimev2.JSpServlet.internalService(JSPServlet.Java:594)
09/03/16 19:03:43 at Oracle.jsp.runtimev2.JSpServlet.service(JSPServlet.Java:518)
09/03/16 19:03:43 at javax.servlet.http.HttpServlet.service(HttpServlet.Java:856)
09/03/16 19:03:43 at com.evermind.server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.Java:713)
09/03/16 19:03:43 at com.evermind.server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.Java:370)
09/03/16 19:03:43 at com.evermind.server.http.HttpRequestHandler.doProcessRequest(HttpRequestHandler.Java:871)
09/03/16 19:03:43 at com.evermind.server.http.HttpRequestHandler.processRequest(HttpRequestHandler.Java:453)
09/03/16 19:03:43 at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.Java:302)
09/03/16 19:03:43 at com.evermind.server.http.AJPRequestHandler.run(AJPRequestHandler.Java:190)
09/03/16 19:03:43 at Oracle.oc4j.Network.ServerSocketReadHandler$SafeRunnable.run(ServerSocketReadHandler.Java:260)
09/03/16 19:03:43 at com.evermind.util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.Java:303)
09/03/16 19:03:43 at java.lang.Thread.run(Thread.Java:595)

錯誤信息看上去比較低級:NoClassDefFoundError,類沒找到,迅速了檢查了一下本機和服務器上的jar包是否相同,“一模一樣”!這就奇怪了。

檢查本機的開發環境,只添加了這兩個jar,其他的都沒有動過,又檢查服務器的運行環境,一樣沒有變化。於是刪掉本機開發環境下的這兩個jar,問題浮出來了,類中對httpclIEnt的7、8個引用中只有1個提示未找到指定的類,看來Oracle自己的某個包中已經包含某個較低版本的httpclIEnt,jar包沖突的問題是件讓人沮喪的事情,嘗試解決這種問題會所耗費的時間也許是其他方法的N倍,無心戀戰。

其實此處要進行的操作很簡單,就是訪問指定的URL,根據返回的內容檢查是否成功,HttpClIEnt是完整模擬浏覽器,考慮了很多種問題,使用起來反倒是復雜了,決定轉用JDK的基礎類:Java.Net.HttpURLConnection

事情出奇的順利,空間裡找到了之前寫的一個方法,正好解決這個問題,以下是代碼清單:

private boolean visitURL(String strUrl, String successFlag) {

boolean rs = false;
HttpURLConnection jconn = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

try {
URL url = new URL(strUrl);

jconn = (HttpURLConnection) url.openConnection();
jconn.setDoOutput(true);
jconn.setDoInput(true);
jconn.connect();

InputStream in = jconn.getInputStream();
byte[] buf = new byte[4096];

int bytesRead;
while ((bytesRead = in.read(buf)) != -1) {
byteArrayOutputStream.write(buf, 0, bytesRead);
}

String strRead = new String(byteArrayOutputStream.toByteArray());

logger.debug(strRead);

strRead = StringUtil.NVL(strRead);

if(strRead.indexOf(successFlag) != -1) {
logger.info("Visit URL < " + strUrl + " > success !");
rs = true;
}

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
jconn.disconnect();

try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

return rs;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved