1. 程式人生 > >Oracle儲存過程如何呼叫java程式併發送Http請求

Oracle儲存過程如何呼叫java程式併發送Http請求

專案中有個需求是資料庫自動定時掃描資料庫,給符合要求的使用者傳送推送訊息,這就需要在儲存過程中自動呼叫傳送推送的程式,由於程式複雜,所以利用orcle 的pl/sql傳送http請求來間接呼叫外部程式。

1.首先,在orcle中建立傳送http請求的java程式碼。

java source資料夾是用來存放java方法的,裡面的程式碼通過orale中的jdk編譯,可以在儲存過程中直接執行。


在資料夾中新建類HttpInvoker,其實就是普通的HttpClient傳送post請求的java方法,注意開頭要寫create or replace and compile java source named httpinvoker as。

create or replace and compile java source named httpinvoker as
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.util.*;
import java.net.URLEncoder;

public class HttpInvoker
{
    
     public static String sendRequest(String name, String userId,String orderNum) throws Exception{
         //處理引數
        String re=""; 
        re="訂單‘"+name+"’已選中你,快去接單吧";
      
        Map<String,String> p=new HashMap<String,String>();
        //全體傳送pushtype為ALL,不寫target
        p.put("pushType","ALIAS");
        p.put("alert",re);
        p.put("target",userId);
        p.put("msgCode","1005");
        p.put("orderNum",orderNum);
        //活動id
        p.put("activityId","");
        String s="";
        for (Map.Entry<String, String> entry : p.entrySet()) {
            s+="&"+entry.getKey()+"="+entry.getValue();
        }
        s=s.substring(1);
        //請求地址
        String url="http://112.64.35.222:9002/itcast/jpush/push";
        //請求引數
        String param=s;       
         //傳送post請求程式碼開始
         PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 開啟和URL之間的連線
            URLConnection conn = realUrl.openConnection();
            // 設定通用的請求屬性
            conn.setRequestProperty("accept", "application/json, text/javascript, */*; q=0.01");
            conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
            conn.setRequestProperty("Connection", "keep-alive");
            conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
            conn.setRequestProperty("Content-Length", "80");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36");
                
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 傳送POST請求必須設定如下兩行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 獲取URLConnection物件對應的輸出流
            OutputStreamWriter outWriter = new OutputStreamWriter(conn.getOutputStream(), "utf-8");  
            out = new PrintWriter(outWriter);
            // 傳送請求引數
            out.print(param);
            // flush輸出流的緩衝
            out.flush();
            // 定義BufferedReader輸入流來讀取URL的響應
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(),"UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("傳送 POST 請求出現異常!"+e);
            e.printStackTrace();
            result=e.getMessage();
        }
        //使用finally塊來關閉輸出流、輸入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(IOException ex){
                ex.printStackTrace();
            }
        }
        return result;
    }
    
}

2.在functions資料夾中建立呼叫java程式的過程


function 和procedure儲存過程很像,不過function必須返回一個結果,procedure可以返回也可以不反回

create or replace function HttpInvoker(name VARCHAR2, userId VARCHAR2 ,orderNum VARCHAR2) return    VARCHAR2
      as language java name
      --加密函式
      'HttpInvoker.sendRequest (java.lang.String,java.lang.String,java.lang.String) return java.lang.String';

注意我建立的是function,所以必須返回結果,如果你建立的是procedure,則可以不返回

3.在你的儲存過程程式碼中呼叫function

IV_RESULT:=HttpInvoker(orderInfo.order_name,IV_TAKER_USER_ID,orderInfo.order_num);

在需要呼叫的地方呼叫,傳入引數即可

4.這時你test測試時會發現connection連線時報錯,根本傳送不出去,這是因為沒有給使用者配置許可權

java.security.AccessControlException: the Permission (java.net.SocketPermission localhost:10000 listen,resolve) has not been granted to RADIUS. The PL/SQL to grant this is dbms_java.grant_permission( 'RADIUS', 'SYS:java.net.SocketPermission', 'localhost:10000', 'listen,resolve' )

5.如果還不行,可能是acl的問題

定義ACL,若沒有ACL,則無法訪問網路。

  1. --定義ACL 取名:httprequestpermission.xml
  2. BEGIN
  3.     dbms_network_acl_admin.create_acl(acl         => 'httprequestpermission.xml',  
  4.                                       DESCRIPTION => 'Normal Access',  
  5.                                       principal   => 'CONNECT',  
  6.                                       is_grant    => TRUE,  
  7.                                       PRIVILEGE   => 'connect',  
  8.                                       start_date  => NULL,  
  9.                                       end_date    => NULL);  
  10. END;  
  1. --檢視ACL是否增加成功
  2. SELECT any_path  
  3. FROM resource_view   
  4. where any_path  like'/sys/acls/%.xml'
  5. ;  
  6. --給使用者增加acl許可權,這裡是 SD_JY 注意是大寫,小寫不識別
  7. begin  dbms_network_acl_admin.add_privilege(acl     => 'httprequestpermission.xml',  
  8.                                          principal  => 'SD_JY',  
  9.                                          is_grant   => TRUE,  
  10.                                          privilege  => 'connect',  
  11.                                          start_date => null,  
  12.                                          end_date   => null);  
  13. end;  
  14. --新增對應主機 ,將對應主機和埠新增到ACL。這裡是 192.168.0.156 和 8080 ,這個ip和埠要和上面儲存過程中定義的地址一致
  15. begin
  16.     dbms_network_acl_admin.assign_acl(acl        => 'httprequestpermission.xml',  
  17.                                       host       => '192.168.0.156',  
  18.                                       lower_port => 8080,  
  19.                                       upper_port => NULL);  
  20. end;  

ACL的增加過程為:建立新的acl檔案,對該檔案中,使用者授權,對該檔案中,URL和埠授權。

可檢視對應的ACL資訊是否新增上

  1. SELECT  acl,  
  2.        principal,  
  3.        privilege,  
  4.        is_grant,  
  5.        TO_CHAR(start_date, 'DD-MON-YYYY'AS start_date,  
  6.        TO_CHAR(end_date, 'DD-MON-YYYY'AS end_date  
  7.   FROM dba_network_acl_privileges;  

相關推薦

Oracle儲存過程如何呼叫java程式併發Http請求

專案中有個需求是資料庫自動定時掃描資料庫,給符合要求的使用者傳送推送訊息,這就需要在儲存過程中自動呼叫傳送推送的程式,由於程式複雜,所以利用orcle 的pl/sql傳送http請求來間接呼叫外部程式。1.首先,在orcle中建立傳送http請求的java程式碼。java s

Oracle儲存過程呼叫bat批處理指令碼程式

        由於系統業務的複雜性,會經常用到Oracle資料的儲存過程,那些比較複雜的邏輯就寫在了儲存過程中。今天有遇到一個需求,是需要在儲存過程中呼叫windows系統上的bat批處理檔案,之前

ORACLE儲存過程呼叫儲存過程時commit的問題

如程式碼中所寫,在儲存過程proc1中呼叫儲存過程proc2,如果在proc2中commit,則sql1中的DML操作會生效。 proc1 begin begin [sql1...] call proc2;----呼叫其他的儲存過程 exc

oracle儲存過程--在應用程式中訪問儲存過程程式完整舉例

認識儲存過程和函式 儲存過程和函式也是一種PL/SQL塊,是存入資料庫的PL/SQL塊。但儲存過程和函式不同於已經介紹過的PL/SQL程式,我們通常把PL/SQL程式稱為無名塊,而儲存過程和函式是以命名的方式儲存於資料庫中的。和PL/SQL程式相比,儲存過程有很多優點,具

java呼叫Oracle儲存過程時,出現異常:java.sql.SQLException: ORA-00928: 缺失 SELECT 關鍵字(已解決)

在java中呼叫Oracle儲存過程時,出現異常:java.sql.SQLException: ORA-00928: 缺失 SELECT 關鍵字 //java程式碼 @Test public void testProcedure(){

幾種應用程式呼叫Oracle儲存過程的方法

一、Java中呼叫帶Cursor的儲存過程: 儲存過程定義: PROCEDURE GET_CURSOR_RESULT2(CR OUT CURSOR_RESULT) IS BEGIN OPEN CR FOR select t1.id, t

java呼叫oracle儲存過程例子

1,導jar包---ojdbc6.jar 2,建立一個分頁儲存過程 create or replace procedure my_page(v_in_tableName in varchar2,

java呼叫oracle儲存過程總結

這段時間開始學習寫儲存過程,主要原因還是因為工作需要吧,本來以為很簡單的,但幾經挫折,豪氣消磨殆盡,但總算搞通了,為了避免後來者少走彎路,特記述與此,同時亦對自己進行鼓勵。 一:無返回值的儲存過程 儲存過程為: CREATE OR REPLACE PROCEDURE TES

sql(join中on與where區別) / NVL函式 / oracle儲存過程中is和as區別 / JAVA呼叫資料庫儲存過程

left join :左連線,返回左表中所有的記錄以及右表中連線欄位相等的記錄。 right join :右連線,返回右表中所有的記錄以及左表中連線欄位相等的記錄。 inner join: 內連線,又叫等值連線,只返回兩個表中連線欄位相等的行。 full join:外連線,返回兩個表中的行:left jo

Oracle資料庫觸發器如何呼叫Java程式實現Openfire訊息推

寫在前面,要想實現整個過程的成功執行請先準備以下檔案: 1. 登陸Openfire服務端以及Spark客戶端相關程式(openfire_4_0_1.exe、spark_2_7_6.exe) 2. 連線Openfire和Oracle相關的jar包(presence.jar、s

Java呼叫Oracle儲存過程儲存函式

一. 編寫測試所用儲存函式或函式 --1.建立一個帶引數的儲存過程,沒有返回值 --給指定的員工漲100元的工資,並且列印漲錢和漲後的工資 create or replace procedure raisesalary(eno in number) as

Java呼叫Oracle儲存過程(無返回值)

無返回值: 1:建立儲存過程 此儲存過程向表中插入一條資料 create or replace procedure demo_procedure(id varchar2,name varchar2,age varchar2,sex varchar2,address va

Java中通過jdbc呼叫oracle儲存過程

Java呼叫Oracle儲存過程步驟主要分為三類: (1)編寫Oracle儲存過程 (2)編寫資料庫獲取連線工具類 (3)編寫簡單應用呼叫儲存過程 1、Oracle中的儲存過程程式 1.在Oracle SQL Developer中建立儲存過程 在sc

mybatis呼叫oracle儲存過程返回遊標 讀取到java的List

mapper: <select id="testP" statementType="CALLABLE" > {call P_TEST(#{v_cursor, mode=OUT, jdbcType=CURSOR})} </select> ja

Java呼叫Oracle儲存過程

步驟: 1、編寫Oracle儲存過程 2、編寫資料庫獲取連線工具類 3、編寫簡單應用呼叫儲存過程 實現: 1、Oracle儲存過程: /*測試表*/ create table test( id varchar2(32)

java面試問題:oracle儲存過程(procedure)和函式(function)的區別

oracle儲存過程(procedure)和函式(function)的區別 儲存過程 函式 用於在資料庫中完成特定的操作或者任務(如插入、刪除等) 用於特定的資料(如選擇)

C#呼叫ORACLE儲存過程返回結果集

Oracle中scott使用者下建立儲存過程: (注:從9i開始有了sys_refcursor這種型別,在以前的Oracle版本中需要使用REF CURSOR,並且還需放在一個程式包中) create or replace procedure sp_getdept (result

python呼叫oracle儲存過程

# -*- coding: utf-8 -*- import cx_Oracle conn = cx_Oracle.connect('user','pwd','tns') cursor = conn.cursor() #宣告變數 #呼叫儲存過程 sql = ''' declare result

Oracle 儲存過程、函式的建立和呼叫

一、Oracle 建立和呼叫儲存過程 1、基本語法 create or replace procedure update_emp_sal (Name in out type, Name in out type, ... ) is begin end update_emp_

儲存過程java呼叫 hana 的儲存過程

一)儲存過程寫法如下: CREATE PROCEDURE "HANA_BI"."com.WFJ.OFFLINE.PROCEDURES::TEST" (P_INT INT, out V_RESULT n