文章目录
简介原理
Oracle Form开发时都是基于组件的,比如canvas、button、text等等,其实底层就是一个个的JavaBean,在执行时会被转换成Java Applet在JVM中运行。在Form Builder的组件属性中可以看到一个叫“实施类”的属性,其实就是该组件对应的java类,一般标准的组件都为空,无须明确指出。
当然Oracle也允许我们开发自己的组件并应用到form中,但是局限还是挺大的。客制化的JavaBean必须继承Oracle提供的VBean,仅提供了set_custom_property和get_custom_property两个方法调用JavaBean,在JavaBean中也可以通过发布CustomEvent来触发Form的触发器WHEN-CUSTOM-ITEM-EVENT,从而执行相应的处理。
- Form调用JavaBean:
Set_custom_property(<BeanName>,<InstanceId>,<MethodName>,<Value>)对应JavaBean setter
Get_custom_property(<BeanName>,<InstanceId>,<MethodName>)对应JavaBean getter - JavaBean调用form:
1)dispatchCustomEvent(new CustomEvent(<Handler>, < PropertyID>))
触发form中Bean区域项的When-Custom-Item-Event
2)System.Custom_Item_Event保存Java发布的事件名称
3)Custom_Item_Event_Parameters获取Java发布事件时设置的属性值
一、JavaBean开发实例(上传Excel文件)
1、准备工作
1)下载jar包frmmain.jar,服务器路径cd $ORACLE_HOME/forms/java,或者用本地Oracle开发套件安装目录下的也可以D:\DevSuiteHome_1\forms\java
2)使用Idea导入jar包frmmain.jar
2、Javabean开发
这里用了IntelliJ IDEA来开发,依赖管理用maven,Java代码如下
package com.bitland.ebs.forms.beans;
import oracle.ewt.util.WindowUtils;
import oracle.forms.api.FException;
import oracle.forms.handler.IHandler;
import oracle.forms.properties.ID;
import oracle.forms.ui.CustomEvent;
import oracle.forms.ui.VBean;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import java.awt.*;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
/**
* @author qiucheng.he
* @version 1.0.0
* @ClassName: UploadBean
* @Description: 导入本地文件
* @date 2020-11-20 11:09
*/
public class UploadBean extends VBean {
private final static ID FILETOREAD = ID.registerProperty("FILETOREAD");
private final static ID LASTDIR = ID.registerProperty("LASTDIR");
private final static ID SHEETCOUNT = ID.registerProperty("SHEETCOUNT");
private final static ID ROWCOUNT = ID.registerProperty("ROWCOUNT");
private final static ID SHEETNUM = ID.registerProperty("SHEETNUM");
private final static ID RETURNCODE = ID.registerProperty("RETURNCODE");
private final static ID RETURNMSG = ID.registerProperty("RETURNMSG");
private final static ID SQLSTATMENT = ID.registerProperty("SQLSTATMENT");
private final static ID VALUESTATMENT = ID.registerProperty("VALUESTATMENT");
private final static ID OPENDIALOG = ID.registerProperty("OPENDIALOG");
private final static ID CREATEWORKBOOK = ID.registerProperty("CREATEWORKBOOK");
private final static ID CREATESHEET = ID.registerProperty("CREATESHEET");
private final static ID READROW = ID.registerProperty("READROW");
private final static ID RELEASE = ID.registerProperty("RELEASE");
private final static String CRLF = "\r\n";
private final static String ORACLENULL = "false"; //Oracle Null值转换为java的object为"false"
private final static String NULLSTRING = "";
private final static int MAXCOLUMN = 60;
private static String fileLastDir = "";
private static String fileToRead = "";
private static int sheetNum = 0;
private static int sheetCount = 0;
private static int rowCount = 0;
private static String splitStr = "~#~";
private static String sqlStatment = "";
private static String valueStatment = "";
private static MessageBean msgBean = new MessageBean("S", "");
private Workbook workbook;
private Sheet sheet;
IHandler mHandler;
//init
public void init(IHandler handler) {
super.init(handler);
mHandler = handler;
}
/**
* 设置bean属性,set_custom_property调用
*
* @param id
* @param value
* @return
*/
public boolean setProperty(ID id, Object value) {
try {
if (id == OPENDIALOG) {
selectFile(value.toString());
} else if (id == LASTDIR) {
fileLastDir = value.toString();
} else if (id == RETURNCODE) {
msgBean.setCode(value.toString());
} else if (id == RETURNMSG) {
msgBean.setText(value.toString());
} else if (id == CREATEWORKBOOK) {
creatWorkbook();
} else if (id == CREATESHEET) {
createSheet(value.toString());
} else if (id == READROW) {
readRow(Integer.parseInt(value.toString()));
} else {
return super.setProperty(id, value);
}
} catch (FException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 获取Bean属性,get_custom_property调用
*
* @param id
* @return
*/
public Object getProperty(ID id) {
if (id == FILETOREAD) {
return fileToRead;
} else if (id == LASTDIR) {
return fileLastDir;
} else if (id == RETURNCODE) {
return msgBean.getCode();
} else if (id == RETURNMSG) {
return msgBean.getText();
} else if (id == SHEETCOUNT) {
return String.valueOf(sheetCount);
} else if (id == ROWCOUNT) {
return String.valueOf(rowCount);
} else if (id == SHEETNUM) {
return String.valueOf(sheetNum);
} else if (id == SQLSTATMENT) {
return sqlStatment;
} else if (id == VALUESTATMENT) {
return valueStatment;
} else if (id == RELEASE) {
releaseResource();
} else {
return super.getProperty(id);
}
return "";
}
/**
* 打开对话框选择文件
*
* @param filepath
* @throws FException
*/
private boolean selectFile(String filepath) throws FException {
msgBean.setCode("S");
msgBean.setText("");
FileDialog filedialog = new FileDialog(WindowUtils.getSharedOwnerFrame(), "打开", FileDialog.LOAD);
//路径为空则打开上次的路径
if (filepath.equals(ORACLENULL)) {
filedialog.setDirectory(fileLastDir);
} else {
filedialog.setDirectory(filepath);
}
//filedialog.show(); //已过时
filedialog.setVisible(true);
fileToRead = filedialog.getFile();
fileLastDir = filedialog.getDirectory();
if (fileLastDir != null && fileToRead != null) {
fileToRead = (fileToRead.equals("null") ? NULLSTRING : fileLastDir.concat(fileToRead));
//System.out.println("filetoread:" + this.fileToRead);
//System.out.println("filelastdir:" + this.fileLastDir);
//自定义事件,事件发布后触发from上bean区域组件的when-custom-item-event
CustomEvent customevent = new CustomEvent(mHandler, OPENDIALOG); //自定义事件句柄
mHandler.setProperty(FILETOREAD, fileToRead);
mHandler.setProperty(LASTDIR, fileLastDir);
mHandler.setProperty(RETURNCODE, msgBean.getCode());
mHandler.setProperty(RETURNMSG, "OPENDIALOG: " + msgBean.getText());
dispatchCustomEvent(customevent);
}
return true;
}
/**
* 读取Excel文件
*
* @throws FException
*/
private void creatWorkbook() throws FException {
try {
workbook = WorkbookFactory.create(new File(fileToRead), null, true); //仅读方式打开文件
sheetCount = workbook.getNumberOfSheets();
} catch (IOException e) {
msgBean.setCode("E");
msgBean.setText(e.getMessage());
e.printStackTrace();
}
CustomEvent customevent = new CustomEvent(mHandler, CREATEWORKBOOK);
mHandler.setProperty(RETURNCODE, msgBean.getCode());
mHandler.setProperty(RETURNMSG, "CREATEWORKBOOK: " + msgBean.getText());
dispatchCustomEvent(customevent);
}
/**
* 创建Sheet对象
*
* @param sheetIndex
* @throws FException
*/
private void createSheet(String sheetIndex) throws FException {
try {
if (sheetIndex.trim().equals(ORACLENULL)) {
sheetNum = workbook.getActiveSheetIndex();
} else {
sheetNum = Integer.parseInt(sheetIndex);
}
sheet = workbook.getSheetAt(sheetNum);
rowCount = sheet.getLastRowNum();
} catch (Exception e) {
msgBean.setCode("E");
msgBean.setText(e.getMessage());
e.printStackTrace();
}
CustomEvent customevent = new CustomEvent(mHandler, CREATESHEET);
mHandler.setProperty(RETURNCODE, msgBean.getCode());
mHandler.setProperty(RETURNMSG, "CREATESHEET: " + msgBean.getText());
dispatchCustomEvent(customevent);
}
/**
* 读取指定Excel行数据
*
* @param rownum
* @throws FException
*/
private void readRow(int rownum) throws FException {
Row row = sheet.getRow(rownum);
if (row == null) {
sqlStatment = "";
valueStatment = "";
return;
}
try {
StringBuffer sqlStr = new StringBuffer("INSERT INTO BITC_UPLOAD_TMP(FILE_ID,SHEET_NUM,ROW_NUM");
StringBuffer sqlStrPostfix = new StringBuffer(") VALUES (?,?,?");
StringBuffer valueStr = new StringBuffer();
boolean insertFlag = false;
int columnCount = row.getLastCellNum();
//System.out.println("columnCount:" + columnCount);
for (int i = 0; i < columnCount; i++) {
if (i == MAXCOLUMN) {
break;
}
sqlStr.append(",ATTRIBUTE" + (i + 1));
sqlStrPostfix.append(",?");
String cellValue;
Cell cell = row.getCell(i);
if (cell == null) {
cellValue = "";
} else {
insertFlag = true;
cellValue = getCellValue(cell, cell.getCellType().getCode());
}
valueStr.append(splitStr + cellValue);
}
sqlStr.append(sqlStrPostfix).append(")");
if (insertFlag) {
sqlStatment = sqlStr.toString();
valueStatment = valueStr.toString().replaceFirst(splitStr, "");
} else {
sqlStatment = "";
valueStatment = "";
}
} catch (Exception e) {
msgBean.setCode("E");
msgBean.setText(e.getMessage());
e.printStackTrace();
}
CustomEvent customevent = new CustomEvent(mHandler, READROW);
mHandler.setProperty(RETURNCODE, msgBean.getCode());
mHandler.setProperty(RETURNMSG, "READROW: " + msgBean.getText());
dispatchCustomEvent(customevent);
}
private static String getCellValue(Cell cell, int cellType) {
short f = cell.getCellStyle().getDataFormat();
switch (cellType) {
case 0: // NUMERIC 数值类型-整数、小数、日期
DecimalFormat decimalFormat = new DecimalFormat("#.0000000000");
if (HSSFDateUtil.isCellDateFormatted(cell) || f == 58 || f == 14
|| f == 31 || f == 32) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return simpleDateFormat.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue()));
} else if (cell.getCellStyle().getDataFormatString().contains("%")) {
//数字要去掉后面多余的0
return BigDecimal.valueOf(Double.parseDouble(decimalFormat.format(cell.getNumericCellValue() * 100))).stripTrailingZeros().toPlainString() + "%";
} else {
return BigDecimal.valueOf(Double.parseDouble(decimalFormat.format(cell.getNumericCellValue()))).stripTrailingZeros().toPlainString();
}
case 1: // String 字符串
return cell.getStringCellValue();
case 2: // FORMULA 公式
return getCellValue(cell, cell.getCachedFormulaResultType().getCode());
case 3: // blank 空值
return "";
case 4: // boolean
return cell.getBooleanCellValue() + "";
case 5: // error
return cell.getErrorCellValue() + "";
default:
return "";
}
}
private void releaseResource() {
try {
if (workbook != null) {
workbook.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
}
}
return message Bean
package com.bitland.ebs.forms.beans;
/**
* @author qiucheng.he
* @version 1.0.0
* @ClassName: MessageBean
* @Description: TODO
* @date 2020-11-26 16:46
*/
public class MessageBean {
private String code;
private String text;
public MessageBean(String code, String text) {
this.code = code;
this.text = text;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
由于From调用JavaBean不能使用form同一session连接数据库,因此把插入到数据库的功能单独写一个java程序,加载到DB中(具体实现后面会介绍)。
package com.bitland.ebs;
import oracle.jdbc.OracleDriver;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @author qiucheng.he
* @version 1.0.0
* @ClassName: Load
* @Description: 把数据插入数据库
* @date 2020-12-02 8:53
*/
public class Load {
private static String splitStr = "~#~";
public static String loadRow(String sqlStatment, String valueStatment, int fileId, int sheetNum, int rowNum) {
if (sqlStatment == null || valueStatment == null || sqlStatment.length() == 0 || valueStatment.length() == 0) {
return "";
}
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = new OracleDriver().defaultConnection(); //使用同一session最后不能关闭连接
preparedStatement = connection.prepareStatement(sqlStatment);
preparedStatement.setInt(1, fileId);
preparedStatement.setInt(2, sheetNum);
preparedStatement.setInt(3, rowNum + 1);
String[] value = valueStatment.split(splitStr);
for (int i = 0; i < value.length; i++) {
if (value[i] == null || value[i].length() == 0) {
preparedStatement.setString(i + 4, "");
} else {
preparedStatement.setString(i + 4, value[i]);
}
}
preparedStatement.executeUpdate();
} catch (SQLException e) {
System.out.println("bitcload.Load.loadRow occur unexpected error" + e.getMessage());
e.printStackTrace();
return ("[ERROR]Load.loadRow: " + e.getMessage());
} finally {
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return "";
}
}
注意要点
- Form的null值传到JavaBean变为”false”
set_custom_property(g_bean_name,1,‘CREATESHEET’,null);
- 注意异常处理,若调用的java抛出空指针异常等就会导致整个session终止,form界面崩溃。
3、Idea打包成jar包
这里先打包好再上传到服务器发布比较方便,也可以直接把源码上传到服务器在编译、打包。
File>Project Structure>Artifacts
Build>Build Artifacts…
二、Jar包部署到R12应用服务器
1、把打包好的bitcupload.jar上传至服务器$JAVA_TOP/oracle/forms/fd目录下,可以指定其他目录,方便管理即可。
2、创建keystore,密码设置为:123456
keytool -genkey -dname "cn=Qiucheng He, ou=Bitland, o= Bitland, c=CN" -alias bitcufkey -keystore bitcufkeystore -validity 720
3、检查keystore(可选)
keytool -list -v -keystore bitcufkeystore
4、输出keystore到文件(可选)命令
keytool -export -keystore bitcufkeystore -alias bitcufkey -file bitcufcert.cer
5、对JAR文件进行签名,并生成新的包bitcuf.jar
jarsigner -keystore bitcufkeystore -signedjar bitcuf.jar bitcupload.jar bitcufkey
检查生产的文件
6、修改系统配置文件,添加bitcuf.jar路径 ,/OA_JAVA/oracle/forms/fd/bitcuf.jar
vi $FORMS_WEB_CONFIG_FILE
实际上是修改appsweb.cfg文件,如果上面的命令无效可以用locate指令查找出该文件来修改,注意当运行autoconfig命令会将此文件恢复。
三、导入Load.class到数据库
1、把编译好的类Load.class上传至服务器$JAVA_TOP/oracle/forms/fd下
2、载入java类
loadjava -u apps/appsapps -v Load.class
3、编译plsql包
CREATE OR REPLACE PACKAGE BODY bitc_upload_pub IS
-- insert_row
FUNCTION insert_row(p_sql_str VARCHAR2,
p_value_str VARCHAR2,
p_file_id NUMBER,
p_sheet_num NUMBER,
p_row_num NUMBER) RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'com/bitland/ebs/Load.loadRow(java.lang.String,java.lang.String,int,int,int)return java.lang.String';
END bitc_upload_pub;
四、Form开发调用JavaBean
前期准备
- 下载jar包bitcuf.jar复制到本地\DevSuiteHome_1\forms\java下
- 修改注册表FORMS_BUILDER_CLASSPATH添加D:\DevSuiteHome_1\forms\java\ bitcuf.jar;
不添加的话,后面Bean域组件设置class属性后,打开画布就会提示找不到Java类
开发
这里的开发和普通的from开发一样,只是有一些需要特殊的地方,比如调用的bean组件、触发器等。
添加bean域组件
添加组件,项类型为“Bean 区域”,并且指定实施类(自己客制Bean的类名),组件必须部署在画布上并且设置为可见,否则调用bean时会报错“unable to communicate with bean”为了隐藏可以把宽度、高度设置为0。
主要代码
包头
PACKAGE UPLOAD IS
g_bean_name varchar2(30) := 'MAIN.UPLOADBEAN';
procedure init;
procedure event_handler(event in varchar2);
procedure summit(event in varchar2);
procedure cancel(event in varchar2);
procedure clear(event in varchar2);
END;
包体
PACKAGE BODY UPLOAD IS
-- init()
procedure init is
begin
copy(to_char(null), 'global.file_id');
copy(to_char(null), 'global.file_name');
end;
--=====================
-- event_handler()
--=====================
procedure event_handler(event in varchar2) is
l_even_name varchar2(30);
l_parameter_list paramlist;
l_parameter_type number;
l_file_to_read varchar2(2000);
l_file_path varchar2(2000);
l_return_code varchar2(100);
l_return_msg varchar2(4000);
l_file_id number;
l_label_yes varchar2(30);
l_label_no varchar2(30);
l_label_cancel varchar2(30);
begin
if event = 'WHEN-CUSTOM-ITEM-EVENT' then
l_even_name := :system.custom_item_event;
--fnd_message.debug(l_even_name);
if l_even_name = 'OPENDIALOG' then
l_parameter_list := get_parameter_list(:system.custom_item_event_parameters);
get_parameter_attr(l_parameter_list,'RETURNCODE',l_parameter_type,l_return_code);
get_parameter_attr(l_parameter_list,'RETURNMSG',l_parameter_type,l_return_msg);
--fnd_message.debug('l_return_code:'||l_return_code);
if l_return_code <> 'S' then
fnd_message.set_name('FND','FND_GENERIC_MESSAGE');
fnd_message.set_token('MESSAGE',l_return_msg);
fnd_message.error;
raise form_trigger_failure;
end if;
get_parameter_attr(l_parameter_list,'FILETOREAD',l_parameter_type,l_file_to_read);
get_parameter_attr(l_parameter_list,'LASTDIR',l_parameter_type,l_file_path);
select bitc_upload_s.nextval into l_file_id from dual;
copy(l_file_id, 'global.file_id');
copy(replace(l_file_to_read, l_file_path, ''), 'global.file_name');
copy(name_in('global.file_name'),'main.file_name');
set_custom_property(g_bean_name,1,'CREATEWORKBOOK',to_char(null));
elsif l_even_name in('CREATEWORKBOOK','CREATESHEET','READROW') then
l_parameter_list := get_parameter_list(:system.custom_item_event_parameters);
get_parameter_attr(l_parameter_list,'RETURNCODE',l_parameter_type,l_return_code);
get_parameter_attr(l_parameter_list,'RETURNMSG',l_parameter_type,l_return_msg);
--fnd_message.debug('l_return_code:'||l_return_code);
--fnd_message.debug('l_return_msg:'||l_return_msg);
if l_return_code <> 'S' then
upload.clear('WHEN-BUTTON-PRESSED');
fnd_message.set_name('FND','FND_GENERIC_MESSAGE');
fnd_message.set_token('MESSAGE',l_return_msg);
fnd_message.error;
raise form_trigger_failure;
end if;
end if;
elsif event = 'OPEN-DIALOG' then
if name_in('global.file_name') is not null then
fnd_message.set_name('FND','YES');
l_label_yes := fnd_message.get;
fnd_message.set_name('FND','NO');
l_label_no := fnd_message.get;
fnd_message.set_name('FND','CANCEL');
l_label_cancel := fnd_message.get;
fnd_message.set_name('BITC','BITC_FILE_ALREADY_EXISTS');
if fnd_message.question(l_label_yes,l_label_no,l_label_cancel,1,2,'question') <> 1 then
raise form_trigger_failure;
end if;
end if;
upload.init;
copy(to_char(null),'main.file_name');
--clear current session data
forms_ddl('truncate table bldsa.bitc_upload_tmp');
set_custom_property(g_bean_name,1,'OPENDIALOG',to_char(null));
else
app_exception.invalid_argument(procname => 'event_handler',
argument => 'event',
value => event);
end if;
end event_handler;
--=====================
-- summit()
--=====================
procedure summit(event in varchar2) is
l_sheet_index varchar2(10);
l_sheet_count number;
l_row_count number;
l_return_code varchar2(100);
l_return_msg varchar2(4000);
l_message varchar2(1000);
l_sqlstatment varchar2(1000);
l_valuestatment VARCHAR2(32767, CHAR);
begin
if event = 'WHEN-BUTTON-PRESSED' then
l_sheet_index := name_in('parameter.sheet_index');
fnd_message.set_name('BITC','BITC_READING_FILE');
l_message := fnd_message.get;
if name_in('global.file_name') is null then
fnd_message.set_name('BITC','BITC_NOT_SELECT_FILE');
fnd_message.show;
raise form_trigger_failure;
end if;
if l_sheet_index = 'ALL' then
l_sheet_count := get_custom_property(g_bean_name,1,'SHEETCOUNT');
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'BUSY');
APP_WINDOW.PROGRESS(0,l_message);
for i in 1..l_sheet_count loop
set_custom_property(g_bean_name,1,'CREATESHEET',to_char(i-1));
l_row_count := get_custom_property(g_bean_name,1,'ROWCOUNT');
for j in 1..l_row_count loop
set_custom_property(g_bean_name,1,'READROW',to_char(j));
l_sqlstatment := get_custom_property(g_bean_name,1,'SQLSTATMENT');
l_valuestatment := get_custom_property(g_bean_name,1,'VALUESTATMENT');
--TODO call api to insert
if l_sqlstatment is not null then
l_return_msg := bitc_upload_pub.insert_row(p_sql_str => l_sqlstatment,
p_value_str => l_valuestatment,
p_file_id => name_in('global.file_id'),
p_sheet_num => i,
p_row_num => j);
if l_return_msg is not null then
APP_WINDOW.PROGRESS(1,l_message); --close
fnd_message.set_name('FND','FND_GENERIC_MESSAGE');
fnd_message.set_token('MESSAGE',l_return_msg);
fnd_message.error;
raise form_trigger_failure;
end if;
end if;
end loop;
APP_WINDOW.PROGRESS(i/l_sheet_count,l_message);
end loop;
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'DEFAULT');
else
set_custom_property(g_bean_name,1,'CREATESHEET',to_char(l_sheet_index-1));
l_sheet_index := get_custom_property(g_bean_name,1,'SHEETNUM');
l_row_count := get_custom_property(g_bean_name,1,'ROWCOUNT');
--fnd_message.debug('l_row_count:'||l_row_count);
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'BUSY');
APP_WINDOW.PROGRESS(0,l_message);
for j in 1..l_row_count loop
set_custom_property(g_bean_name,1,'READROW',to_char(j));
l_sqlstatment := get_custom_property(g_bean_name,1,'SQLSTATMENT');
l_valuestatment := get_custom_property(g_bean_name,1,'VALUESTATMENT');
--TODO call api to insert
if l_sqlstatment is not null then
l_return_msg := bitc_upload_pub.insert_row(p_sql_str => l_sqlstatment,
p_value_str => l_valuestatment,
p_file_id => name_in('global.file_id'),
p_sheet_num => to_number(l_sheet_index+1),
p_row_num => j);
if l_return_msg is not null then
APP_WINDOW.PROGRESS(1,l_message); --close
fnd_message.set_name('FND','FND_GENERIC_MESSAGE');
fnd_message.set_token('MESSAGE',l_return_msg);
fnd_message.error;
raise form_trigger_failure;
end if;
end if;
APP_WINDOW.PROGRESS(j/l_row_count,l_message);
end loop;
SET_APPLICATION_PROPERTY(CURSOR_STYLE, 'DEFAULT');
end if;
--forms_ddl('commit');
l_return_code := get_custom_property(g_bean_name,1,'RELEASE');
app_custom.close_window('UPLOAD');
else
app_exception.invalid_argument(procname => 'summit',
argument => 'event',
value => event);
end if;
end;
--=====================
-- cancel()
--=====================
procedure cancel(event in varchar2) is
begin
if event = 'WHEN-BUTTON-PRESSED' then
upload.clear('WHEN-BUTTON-PRESSED');
app_custom.close_window('UPLOAD');
else
app_exception.invalid_argument(procname => 'cancel',
argument => 'event',
value => event);
end if;
end;
--=====================
-- clear()
--=====================
procedure clear(event in varchar2) is
l_return_code varchar2(10);
begin
if event = 'WHEN-BUTTON-PRESSED' then
copy(to_char(null),'global.file_name');
copy(to_char(null),'global.file_id');
copy(to_char(null),'main.file_name');
l_return_code := get_custom_property(g_bean_name,1,'RELEASE');
else
app_exception.invalid_argument(procname => 'clear',
argument => 'event',
value => event);
end if;
end;
END;
Form编译部署
略
效果展示
查看日志
调用javabean报错日志:
cd $LOG_HOME/ora/10.1.3/Apache
或者打开java控制台查看日志
五、PLSQL调用Java
1、编写JAVA程序
程序方法必须是static类型的
public class sayhello {
public static String sayHello(String name){
return "hello,"+name;
}
}
2、把java导入Oracle数据库
主要有两种方式:
1)、直接编写plsql执行,适合比较简单的情况;
create or replace and compile java source named JavaName as [Java代码]
2)、使用LoadJava指令,参数有
-u(用于输入用户名及密码)
-v(用于输出详细的反馈信息)
-resolve(对于没有编译的Java文件可以用resolve来编译)
-f(不管之前是否已经导入过该Java类,都强制再次导入)
当导入Class文件时,可以用如下命令:
loadjava –u username/userpassword –v filename.class
当删除Class文件时,可以用如下命令:
dropjava –u username/userpassword –v filename.class
当导入Java文件时,可以用如下命令:
loadjava –u username/userpassword –v -resolve filename.java
当删除Java文件时,可以用如下命令:
dropjava –u username/userpassword –v filename.java
当导入jar文件时,可以用如下命令:
loadjava –u username/userpassword –v -resolve filename.jar
当删除jar文件时,可以用如下命令:
dropjava –u username/userpassword –v -resolve filename.jar
3)、导入后查看对象是否可用,导入后状态是IVALID,第一次调用后状态才变为VALID
SELECT OBJECT_ID, OBJECT_NAME, OBJECT_TYPE, STATUS
FROM USER_OBJECTS
WHERE OBJECT_TYPE LIKE 'JAVA%'
3、编写PLSQL程序
可用编写成function、procedure、trigger等
CREATE OR REPLACE PACKAGE BODY bitc_upload_pub IS
-- insert_row
FUNCTION insert_row(p_sql_str VARCHAR2,
p_value_str VARCHAR2,
p_file_id NUMBER,
p_sheet_num NUMBER,
p_row_num NUMBER) RETURN VARCHAR2 AS
LANGUAGE JAVA NAME 'com/bitland/ebs/Load.loadRow(java.lang.String,java.lang.String,int,int,int)return java.lang.String';
END bitc_upload_pub;
注意:
- 这里的java类型如果不是基本类型则必须为全路径,例如java.lang.String
- Java包名之间用’/’划分
4、调用测试
略
六、参考文献
1、黄建华《深入浅出 Oracle+EBS+Forms开发指南_中级》
2、https://blog.csdn.net/chenxianping/article/details/81173072
3、https://www.cnblogs.com/59nice/archive/2020/06/19/13164173.html