Oracle使用Java發送短信

項目上要求使用Oracle加載Java類,發送短信息。當向msg表新增記錄時就使用java類發送短信息,接收返回值並更新記錄的時間及結果。

分析:

  1. msg表新增記錄就發送短信息,此處使用觸發器最好。
  2. 接收返回值更新對應的記錄,因此使用 before insert。因爲after是不可以更新:new.[字段名]的。
  3. 觸發器調用Java方法接收返回值,此處使用Oracle的Function,爲Java方法建立Function

實現:

Oracle JavaSource
目前僅使用了兩種方式加載Java

  1. 使用Oracle loadjava
    loadjava -user test/test@test -o -v -f -r Msg_HttpRequest.java
  2. 使用pl/sql 直接創建
    代碼如下
create or replace and compile java source named "Msg_HttpRequest" as
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

public class Msg_HttpRequest {

     public static String sendPost(String mobile, String content) {
            PrintWriter out = null;
            BufferedReader in = null;
            String result = "";
            try {
                if("".equals(mobile)||"".equals(content)){return "有空值";}
                URL realUrl = new URL("短信URL");
                // 打開和URL之間的連接
                URLConnection conn = realUrl.openConnection();
                // 設置通用的請求屬性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent",
                        "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 發送POST請求必須設置如下兩行
                conn.setDoOutput(true);
                conn.setDoInput(true);
                // 獲取URLConnection對象對應的輸出流
                out = new PrintWriter(conn.getOutputStream());
                // 發送請求參數
                StringBuilder param = new StringBuilder();
                param.append("corpId=短信平臺祕鑰&");
                param.append("secretKey=祕鑰&");
                param.append("mobile="+mobile+"&");
                param.append("content=").append(URLEncoder.encode(content, "UTF-8"));
                out.print(param.toString());
                // flush輸出流的緩衝
                out.flush();
                // 定義BufferedReader輸入流來讀取URL的響應
                in = new BufferedReader(
                        new InputStreamReader(conn.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            } catch (Exception e) {
                System.out.println("發送 POST 請求出現異常!"+e);
                e.printStackTrace();
                result=e.toString();
            }
            //使用finally塊來關閉輸出流、輸入流
            finally{
                try{
                    if(out!=null){
                        out.close();
                    }
                    if(in!=null){
                        in.close();
                    }
                }
                catch(IOException ex){
                    ex.printStackTrace();
                }
            }
            return result;
        }


}
create or replace and compile java source named "Msg_run" as
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
public class Msg_run {
  public static String mainConn(String user_mobile,String msg_content) {


      try {
    // if("".equals(user_mobile)||"".equals(msg_content)){return "0";}
    Msg_HttpRequester request = new Msg_HttpRequester();

    String result = request.sendPost(user_mobile,msg_content)
    System.out.println(result);
        return result;
      } catch (Exception e) {
        e.printStackTrace();
         return "1";
      }
  }
}

創建Function

create or replace function f_send( user_mobile varchar2,  msg_contend varchar2)  return varchar2 as
language java name 'Msg_run.mainConn(java.lang.String,java.lang.String) return java.lang.String';

可以使用如下進行測試

select f_send('','') from dual;

具體使用觸發器調用函數就不再粘代碼了。

問題:

這一套流程下來,遇見幾個問題

  1. 權限問題
    爲Oracle用戶使用短信調用地址賦權
    使用本地賬戶DBA權限,和SYS /as sysdba都使用過均顯示成功。

    
    exec dbms_java.grant_permission( 'SLAB', 'SYS:java.net.SocketPermission', 'localhost:1024-', 'listen,resolve');
    exec dbms_java.grant_permission( 'SLAB', 'SYS:java.net.SocketPermission', 'localhost:1024-', 'accept, resolve');
    exec dbms_java.grant_permission( 'SLAB', 'SYS:java.net.SocketPermission', 'localhost:1024-', 'connect, resolve');

    使用賦權後,再測試f_send(),發現還是報沒有權限的問題。
    需要等待一段時間,這一點始終沒有明白。
    有一個懷疑是Java會話問題。
    希望有人可以給解答。
    參考:https://community.oracle.com/thread/726719?tstart=0

  2. Java方法中創建Connect到Oracle
    不需要再使用JDBC加載Class了
    Connection conn = DriverManager.getConnection("jdbc:default:connection:");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章