深入浅出Oracle之OAF开发参考_第1页
深入浅出Oracle之OAF开发参考_第2页
深入浅出Oracle之OAF开发参考_第3页
深入浅出Oracle之OAF开发参考_第4页
深入浅出Oracle之OAF开发参考_第5页
已阅读5页,还剩112页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

OracleERPOracleERP最佳实践E-BUSINESSSUITEORACLE核心应用技术OAF开发参考Author:CreationDate:LastUpdated:DocumentVersion:Approvals:<Approver1><Approver2>

赵振坤April26,2013April25,2022<DocumentReferenceNumber>1.0CopyNumber DocumentControlChangeRecordDateDateAuthorVersion ChangeReferenceReviewersNameNamePositionDistributionCopyNo. NameCopyNo. NameLocation1234NoteToHolders:Ifyoureceiveanelectroniccopyofthisdocumentandprintitout,pleasewriteyournameontheequivalentofthecoverpage,fordocumentcontrolpurposes.Ifyoureceiveahardcopyofthisdocument,pleasewriteyournameonthefrontcover,fordocumentcontrolpurposes.ContentsDocumentControl ii深入浅出OAF–入门篇 4OAF简介 4环境搭建 7HelloWorld 10一个简单的查询 19应用发布 28编码规范 30深入浅出OAF-基础篇 32实现增删改 32数据校验 54常用布局 57常用组件 69常用JAVA代码 81使用CSS和JS 83深入浅出OAF-中级篇 84纯代码添加组件 84PPR的使用 84OAF和Form相互调用 87OAF个性化 89深入浅出OAF–高级篇 95探究MVC 95实体对象 99视图对象 104BC4J对象缓存 108解析OAF页面元数据结构 111Reference 116OpenandClosedIssuesforthisDeliverable. 117OpenIssues 117ClosedIssues 117深入浅出OAF入门篇OAF简介概述OracleApplicationFramework(OAFramework是Oracle提供的基于HTML应用的开发和发布平台OAFramework由一系列的中间层服务和OracleJDeveloper的扩展(OracleApplicationsExtensionOAExtension组成OAF使用OracleBusinessComponentsforJAVA(BC4J)框架作为其模型部分,来实现业务逻辑和数据操作。OAF使用元数据库支持的(整个页面由XML来定义,定义存储于Oracle数据库中)UIX框架作为其视图部分,将BC4J中的数据展示给用户。OAF页面是通过JDeveloper工具定义XML结构,一般情况下不需要编程实现。特征良好的用户体验例如页面局部刷新、翻页、LOV(值列表)选择、统一的CSS风格。企业级可靠性息(例如用户信息)会被中间层缓存,从而实现快速响应。提高开发者效率OAF基于Model-View-Controller(MVC)的架构设计,使用OAF设计的用户界面以符合业界标准的XML格式存在,借助OAF开发人员可以方便扩展OracleE-BusinessSuite。开放标准OAF基于J2EE,很多特征都符合业界标准(例如:XML,HTML,Java,JSP,SQL、WebServices)。框架结构OAFramework是基于工业标准J2EEMVC设计模式的OAFramework模型通过BC4J(OracleBusinessComponentsforJava)视图链接对象、应用模块对象、事务对象等。OAFramework视图通过UIX(UIXML)实现,以XML来描述页面。OAFramework控制器通过Java类来实现,简单的页面流程直接使用控制器对象实现,实现对Request/Response逻辑处理;而复杂的则使用OracleWorkflow来实现。版本查看EBS中有关OAF组件版本的方法如下登录进去EBS环境在页面左下角,有“关于此页”的链接,点击进入,(档3.4.1)点击“技术组件”,就会看到有关OAF组件版本的基本信息。第一个便是OAF本信息,它决定了开发工具的版本。OAF与ADF在开发OAF开始前,明确一个问题。有些部分同学会搞不懂OAF、ADF有什么联系?ADF:ApplicationDeveloperFramework可以任何Java环境中运行,属于Oracle中间件。OAF:OracleApplicationFramework.只能在EBS环境中运行,属于OracleEBS。两者都是基于MVC原理的框架二者本质上并没有什么区别。我觉得两者关系有点类似于OracleForm与OracleEBS-Form。当然ADF的技术范围比较广。学习基础SQL、PL/SQL呵呵,不解释。JAVA基础OAF技术采用的是JAVA开发语言,所以在您学习OAF之前,必须先掌握JAVA发语言的基础知识J2EEMVC基础(非必须)MVC代表的是ModuleView代表的是ControlOAF是基于工业标准J2EEMVC设计模式的,如果有J2EEMVC的基础,学习起来会很好理解OAF的结构和对象。XML基础(非必须)OAF中大量使用XML来完成配置,包括页面结构、lov、AMserver、VO、EO等等,但是XML结构非常简单,OAF中也不用手动编写,看懂即可。环境搭建安装JDeveloper下载p9879989_R12_GENERIC.zip(可以从metalink下载,EBSJDeveloper开发工具)将p9879989_R12_GENERIC.zip解压到一个目录下,如D:\(注意:解压的目录不能含有空格、中文等)jdevbin中是jdeveloper10gwithOAExtension的程序文件和OAF的类库jdevdoc中存放Javadoc手册和OAF培训文档jdevhome存放OAF用户文件和虚拟的OAF环境在Windows系统的环境变量中配置JDEV_USER_HOME为:D:\p9879989_R12_GENERIC\jdevhome\jdev\JDeveloper的执行程序为jdevbin\jdev\bin\jdevw.exe,可将其建立桌面快捷方式初次打开JDeveloper,会有“是否从之前版本移植”的提示,选否打开之后,如果是win7系统,会发现win7置文件jdevbin\jdev\bin\jdev.conf,将“AddVMOption-Dsun.java2d.noddraw=true”注释打开即可。获取了DBC文件登陆应用层的$FND_SECURE目录,下载*.dbc文件至jdevhome\jdev\dbc_files\secure打开dbc文件,找到APPS_JDBC_URL,可看到含有很多“\”,把所以的“\”都去掉(注:该操作只针对APPS_JDBC_URL属性)配置数据库连接打开JDeveloperApplications和Connections,Applications是项目目录,Connections是数据库目录,进入Connections右键Database>CreateDataConnection,可以为此Connection起个名字,我用默认的DBConnection1,ConnectionType选默认值Oracle(JDBC),下一步输入链接数据库的用户名和密码(一般情况用户名选apps),Role为Normal,选择DeployPassword,可记住密码输入连接数据库的信息进行测试,返回success则说明连接成功HelloWorld创建OAProject在JDeveloper左侧导航栏进入Applications右键Applications>NewOAWorkspace,为Application起个名字,其他默认随之会跳出新建OAProject的对话框,为Project起个名字,下一步勾选UseRepositoryforDesignTime,Connection选择刚刚创建的DBConnection1,下一步DBCFileName选择\jdevhome\jdev\dbc_files\secure目录下的dbc文件,UserName和Password是登录EBS使用的用户名和密码,ApplicationShortName和ResponsibilityKey是EBS环境定义职责时的应用产品简称和责任关键字,下一步,完成。设置项目选中刚创建的项目,Tools>ProjectPropertise,进入设置界面在左侧,打开OracleApplications,下边有三个子目录,DatabaseConnections和RuntimeConnections已在上一步创建项目时进行了设置,打开RunOption,一般OAOADeveloperModeandOADiagnostic,确定创建页面至此,进入OAF真正的主题右键项目,选New,选择OAComponent>Page,确定Name输入:HelloWorldPG,Package输入:mycompany.oracle.apps.cux.hello.webui,一般Package输入格式为:<company_name>.oracle.apps.<application_shortname>.<optional_modulename>.webui,其中应用简称依据项目而定,如ar、ap、eam,这里用cux代替点击HelloWorldPG.xml,下边出现Structure导航,这是该页面的结构,可以看到含有一个region1,单击,JDeveloper右侧出现PropertyInspector导航,这是它对应的属性,可以进行修改右键hello,点击NewApplicationModulePackage输入mycompany.oracle.apps.cux.hello.server,Name输入HelloAM,下一步,保持默认值,到完成修改region1属性属性WindowTitleTitleAM

值HelloWorldHellomycompany.oracle.apps.cux.hello.server.HelloAM

说明浏览器窗口名称页面标题右键HelloWorldPG,run,运行页面可看到运行结果至此,初步运行成功!几个问题关于dbc文件,从服务器下载后,需要进行修改,已在1.2.2果运行时浏览器报“找不到服务器”这样的错误,应查看dbc文件,看DB_HOST和DB_PORT是否正确,能否ping通,以及APPS_JDBC_URL是否正确。运行时出现“URL参数,它将被忽略”错误,页面回到EBS主页,如下图JDeveloper中,Tools>EmbeddedOC4JServerPreferences,左侧选择Startup,选择DefaultLocalIPAddress,重新运行JDeveloperJDeveloper>PreferencesWebrandProxy,手动设置浏览器位置即可添加item我们要在页面添加一个输入框和一个按钮,方法是在HelloWorldPG的regin1加两个item,分别设置属性属性IDItemPrompt

值 说明HelloNamemessageTextInputPleaseInputyourname:属性值说明IDItemStyleGoBtnsubmitButton提交按钮PromptGO按钮显示运行HelloWorldPG,可以看到运行结果,但是点击GO,没有任何反应添加CO右键region1,点击SetNewControllerPackageName输入mycompany.oracle.apps.cux.hello.webui,ClassName输入HelloWorldCO,一般来说,CO和Page名字设置相同,后缀固定,为CO、PG,之后还有EO、VO等等。可以看到JDeveloper生成了一个HelloWorldCO的java文件,这个类似于web里的servelet,CO里默认有两个方法,processRequest和processFormRequest,processRequest在页面加载时自动调用,processFormRequest是在页面提交时调用。我们在processFormRequest方法里加上如下代码(注:不要去掉super方法)if(pageContext.getParameter("GoBtn")!=null){//检测GO按钮被点击StringuserNamepageContext.getParameter("HelloName");//获得nameStringmessage="Hello,"+userName+"!";System.out.println(message);//输出}再次运行HelloWorldPG,输入一个name,点击GO,在JDeveloper后台可看到输出,如下图至此,HelloWorld结束,相信大家对OAF有了初步了解。一个简单的查询创建组件创建AM,名字为SearchAM,路径为mycompany.oracle.apps.cux.search.server创建VO(ViewObject),名字为EmployeeVO,路径为mycompany.oracle.apps.cux.search.server5步,SQLStatement,输入如下SQLSELECTppf.person_id,ppf.date_of_birth,ppf.full_nameFROMper_people_fppfWHERESYSDATEBETWEENppf.effective_start_dateANDppf.effective_end_date然后下一步,选择数据库连接DBConnection1,确定,然后下一步到结束。双击AMAMEmployeeVO加入到SearchAM中,点击确定。创建PG,名字为SimpleSearchPG,路径为mycompany.oracle.apps.cux.search.webui修改SimpleSearchPG中的region1属性属性IDWindowTitleTitleAM

值 说明PageLayoutRN简单查询员工mycompany.oracle.apps.cux.search.server.SearchAM基于结果的查询在PageLayoutRN下创建Region,修改属性属性 值 说明IDRegion

QueryRNqueryConstructionModeIncludeSimpleIncludeViewsPanelIncludeAdvancedPanel

resultsBasedSearchTrueTrueTrue

简单搜索高级搜索接下来创建员工列表Region右键QueryRN,NewRegionUsingWizard,AM选择mycompany.oracle.apps.cux.search.server.SearchAMAvailableViewObjects列表中选择视图对象实例EmployeeVO,下一步,在RegionProperties页中设置RegionID的值为ResultsTable,RegionStyle的值为table,ViewAttributesAvailableViewAttributes列表中的所有属性到SelectedViewAttributes列表中下一步,在RegionItems页中,设置如下的属性值IDPersonIdDateOfBirthEmployeeNumberFullName下一步,完成。

PromptPersonIdBirthdayNumberName

StylemessageStyledTextmessageStyledTextmessageStyledTextmessageStyledText

DataTypeNUMBERDATEVARCHAR2VARCHAR23)修改ResultsTable属性属性ID值ResultsTable说明RegionStyletableAMDefinitionAdditional

必须为空,如果有值则删除员工列表RecordsWidth

10100%

每页显示数量分别修改PersonId、EmployeeNumber属性值属性IDSearchAllowedSelectiveCriteria

值PersonIdTrueTrue

说明可搜索何条件,这个属性IDSearchAllowedSelectiveCriteria

值 说明TrueTrue运行,并且可以从数据库查出正确数据,表明成功。使用自动客户化查询条件LOV种简单的查询已不能满足,接下来我们使用“自动客户化查询条件”模式。首先修改QueryRN属性,调整为“自动客户化查询”模式属性 值 说明IDIDQueryRNRegionStylequeryConstructionModeautoCustomizationCriteria自动客户化查询IncludeSimplePanelTrueIncludeViewsPanelFalseIncludeAdvancedPanelFalse增加一个简单的查询区域右键QueryRN,New>simpleSearchPanel,一个header区域(region2)和messageComponentLayout区域(region1)自动创建改变region2的ID为SimpleSearchHdr改变region1的ID为EmployeeSimpleSearch创建PersonId查询项目属性值说明IDSearchPersonIdRegionStyle属性值说明IDSearchPersonIdRegionStylemessageTextInput文本输入DataTypeNUMBER与数据库一致PromptPersonId创建EmployeeNumber查询项目属性值说明IDSearchEmployeeNumberRegionStyle属性值说明IDSearchEmployeeNumberRegionStylemessageTextInput文本输入DataTypeVARCHAR2与数据库一致PromptEmployeeNumber建立查询条件和查询结果表之间的映射右键QueryComponents文件夹,NewsimpleSearchMappings,选择simpleSearchMappings下的默认映射,并设置其属性为下列值:属性属性值说明IDSearchResultItem

PersonIdMapSearchPersonIdPersonId右键simpleSearchMappings,New>queryCriteriaMap,并设置属性属性IDSearchResultItem

值 说明EmployeeNumberMapSearchEmployeeNumberEmployeeNumber运行SimpleSearchPG页面添加LOV接下来,为PersonId添加LOV。在LOV中,PersonId的值来自fnd_user表的employee_id字段首先创建LOV所需的VO。名字为EmployeeIdVO,路径为mycompany.oracle.apps.cux.search.lov.server,其它保持默认值,一直下一步,到第5步,SQLStatement,输入如下SQLSELECTfu.user_name,fu.employee_idFROMfnd_userfuWHEREfu.employee_idISNOTNULL双击AMEmployeeIDVO加入到SearchAM中,点击确定。新建一个Region,作为LOV的弹出页面名字为EmployeeIdRN,路径为mycompany.oracle.apps.cux.search.lov.webui,Style为listOfValues。新建后,设置EmployeeIdRN的属性。属性IDScopeAdvancedAllowed

值 说明EmployeeIdRNPublicTrue右键EmployeeIdRN,New>tableUsingWizardAM选SearchAM,VO选EmployeeIdVO下一步,在RegionProperties页中设置RegionID的值为EmployeeIdVO,RegionStyle的值为table,ViewAttributesAvailableViewAttributes列表中的所有属性到SelectedViewAttributes列表中下一步,在RegionItems页中,设置如下的属性值IDUserNameEmployeeId

PromptUserNameEmployee

Style DataTypemessageStyledText messageStyledText NUMBERUserName和EmployeeIdSearchAllowedSelectiveSearchCriteriaTrueLOV的设置SearchPersonId能够使用LOV属性值说明ID属性值说明IDSearchPersonIdItemStylemessageLovInputExternalLOV/mycompany/oracle/apps/cueIdRNDisableValidationFalse值校验此时在SearchPersonId下有个lovMappings,这是lov取到值后映射到界面的设置,在它下可添加lovMap,默认已经有一个,设置其属性属性属性值说明IDPersonIdLovMapLOVRegionItemEmployeeIdLOV的值ReturnItemSearchPersonId返回到的itemCriteriaItemSearchPersonId运行SimpleSearchPG页面(注:浏览器可能会阻止弹出页面,会有提示,允许弹出即可)应用发布上传进入jdevhome\jdev\myclasses\mycompany\oracle\apps目录。将整个cux目录上传到EBS应用层的$JAVA_TOP\mycompany\oracle\apps手动创建。编译需要编译的是页面,有两个,SimpleSearchPG和EmployeeIdRN,编译命令如下:javaoracle.jrad.tools.xml.importer.XMLImporter$JAVA_TOP/mycompany/oracle/apps/cux/search/webui/SimpleSearchPG.xml-rootdir$JAVA_TOP-usernameapps-passwordapps -dbconnectiono)(PORT=1521)))(CONNECT_DATA=(SID=VIS)))"javaoracle.jrad.tools.xml.importer.XMLImporter$JAVA_TOP/mycompany/oracle/apps/cux/search/lov/webui/EmployeeIdRN.xml-rootdir$JAVA_TOP-usernameapps-passwordapps -dbconnectiono)(PORT=1521)))(CONNECT_DATA=(SID=VIS)))"导入成功即可看到:挂菜单进入EBS环境,应用开发员>应用产品>功能,添加功能类型HTML

值 说明CUXEMPCUX_员工查询SSWAjsp函数OA.jsp?page=/mycompany/oracle/apps/cux/search/webui/SimpleSearchPG进入:应用开发员>应用产品>菜单,新建菜单CUX_OAF,添加功能CUX_员工查询,保存。将CUX_OAF作为子菜单添加到CUX_客户化开发的主菜单即可。重启oacore因为OAF的运行机制是应用启动时,会把所需的OAF界面、classjs等web元素全部加载到缓存中,所以OAF不像FORM那样,编译后即可显示结果。关闭服务器cd$ADMIN_SCRIPTS_HOMEadoacorectl.shstop开启服务器cd$ADMIN_SCRIPTS_HOMEadoacorectl.shstart查看结果正确运行,发布成功!编码规范OAF编码规范OAF开发所有包和命名规则(类、方法和UI组件)都应遵循了OAF文件标准。主要有:OracleBrowserLook-and-Feel(BLAF)UI准则这是Oracle公司为基于浏览器应用所设计的UI标准OracleApplicationsJava编码标准在Oracle产品中编写Java代码的标准和准则OAF模型编码标准使用在MVC应用中的OAF模型编码标准OAF视图编码标准使用在MVC应用中的OAF视图编码标准OAF控制器编码标准使用在MVC应用中的OAF控制器编码标准JSR227SpecificationJava投票通过的Java规范。JCP官方主页:/en/home/index。Oracle号称或者是JSR227JSR227到底规范了什么呢?呵呵!原来JSR227是Oracle发起的。很有意思的是IBMBEA投了反对票(BEA还未被Oracle收购!)。深入浅出OAF基础篇实现增删改创建客户化表创建两张客户化表,部门和员工,为头行结构。部门表CREATETABLECUX.CUX_OAF_TEST_DEPARTMENT(DEPARTMENT_IDNUMBERNOTNULL,DEPARTMENT_NUMBERVARCHAR2(100)NOTNULL,DEPARTMENT_NAMEVARCHAR2(100)NOTNULL,DEPARTMENT_DESCVARCHAR2(240),CREATION_DATEDATEDEFAULTSYSDATENOTNULL,CREATED_BYNUMBERDEFAULT-1NOTNULL,LAST_UPDATED_BYNUMBERDEFAULT-1NOTNULL,LAST_UPDATE_DATEDATEDEFAULTSYSDATENOTNULL,LAST_UPDATE_LOGINNUMBER,ATTRIBUTE_CATEGORYVARCHAR2(30),ATTRIBUTE1VARCHAR2(240),ATTRIBUTE2VARCHAR2(240),ATTRIBUTE3VARCHAR2(240),ATTRIBUTE4VARCHAR2(240),ATTRIBUTE5VARCHAR2(240),ATTRIBUTE6VARCHAR2(240),ATTRIBUTE7VARCHAR2(240),ATTRIBUTE8VARCHAR2(240),ATTRIBUTE9VARCHAR2(240),ATTRIBUTE10VARCHAR2(240),ATTRIBUTE11VARCHAR2(240),ATTRIBUTE12VARCHAR2(240),ATTRIBUTE13VARCHAR2(240),ATTRIBUTE14VARCHAR2(240),ATTRIBUTE15VARCHAR2(240));ALTERTABLECUX.CUX_OAF_TEST_DEPARTMENTADDCONSTRAINTCUX_OAF_TEST_DEPARTMENT_PKPRIMARYKEY(DEPARTMENT_ID);CREATEUNIQUEINDEXCUX.CUX_OAF_TEST_DEPARTMENT_U1ONCUX.CUX_OAF_TEST_DEPARTMENT(DEPARTMENT_NUMBER)TABLESPACECUXIDX;CREATESEQUENCECUX.CUX_OAF_TEST_DEPARTMENT_SSTARTWITH10001;CREATESYNONYMAPPS.CUX_OAF_TEST_DEPARTMENT_SFORCUX.CUX_OAF_TEST_DEPARTMENT_S;CREATESYNONYMAPPS.CUX_OAF_TEST_DEPARTMENTFORCUX.CUX_OAF_TEST_DEPARTMENT;员工表CREATETABLECUX.CUX_OAF_TEST_EMPLOYEE(EMPLOYEE_IDNUMBERNOTNULL,EMPLOYEE_NUMBERVARCHAR2(100)NOTNULL,EMPLOYEE_NAMEVARCHAR2(100)NOTNULL,EMPLOYEE_DESCVARCHAR2(240),EFFECTIVE_DATE_FROMDATENOTNULL,EFFECTIVE_DATE_TODATE,DEPARTMENT_IDNUMBERNOTNULL,CREATION_DATEDATEDEFAULTSYSDATENOTNULL,CREATED_BYNUMBERDEFAULT-1NOTNULL,LAST_UPDATED_BYNUMBERDEFAULT-1NOTNULL,LAST_UPDATE_DATEDATEDEFAULTSYSDATENOTNULL,LAST_UPDATE_LOGINNUMBER,ATTRIBUTE_CATEGORYVARCHAR2(30),ATTRIBUTE1VARCHAR2(240),ATTRIBUTE2VARCHAR2(240),ATTRIBUTE3VARCHAR2(240),ATTRIBUTE4VARCHAR2(240),ATTRIBUTE5VARCHAR2(240),ATTRIBUTE6VARCHAR2(240),ATTRIBUTE7VARCHAR2(240),ATTRIBUTE8VARCHAR2(240),ATTRIBUTE9VARCHAR2(240),ATTRIBUTE10VARCHAR2(240),ATTRIBUTE11VARCHAR2(240),ATTRIBUTE12VARCHAR2(240),ATTRIBUTE13VARCHAR2(240),ATTRIBUTE14VARCHAR2(240),ATTRIBUTE15VARCHAR2(240));ALTERTABLECUX.CUX_OAF_TEST_EMPLOYEEADDCONSTRAINTCUX_OAF_TEST_EMPLOYEE_PKPRIMARYKEY(EMPLOYEE_ID);CREATEUNIQUEINDEXCUX.CUX_OAF_TEST_EMPLOYEE_U1ONCUX.CUX_OAF_TEST_EMPLOYEE(EMPLOYEE_NUMBER)TABLESPACECUXIDX;CREATESEQUENCECUX.CUX_OAF_TEST_EMPLOYEE_SSTARTWITH10001;CREATESYNONYMAPPS.CUX_OAF_TEST_EMPLOYEE_SFORCUX.CUX_OAF_TEST_EMPLOYEE_S;CREATESYNONYMAPPS.CUX_OAF_TEST_EMPLOYEEFORCUX.CUX_OAF_TEST_EMPLOYEE;插入这里以新建部门为例,并实现部门和员工的关联,从而可新建员工。创建AM。名称为TestAM,路径为mycompany.oracle.apps.cux.test.server。创建EOtest,NewEntityObjectDepartmentEO,路径为mycompany.oracle.apps.cux.test.schema.server,SchemaObject为CUX.CUX_OAF_TEST_DEPARTMENT下一步,点击NewfromTable,一般会勾选所有字段,确定。一直下一步,到第4步,勾选CreateMethod,ValidationMethod和RemoveMethod。下一步到完成。使EO在创建时,其ID自动获取sequence的值点击DepartmentEO,双击DepartmentEOImpl.java找到方法publicvoidcreate(AttributeListattributeList),在super.create(attributeList);后加入:this.setDepartmentId(this.getOADBTransaction().getSequenceValue("CUX_OAF_TEST_DEPARTMENT_S"));创建VOmycompany.oracle.apps.cux.test.server,这里的VOEO择刚刚创建的DepartmentEO下一步,选择所有属性一路下一步,到完成。将DepartmentVO加入到TestAM中,确定。创建PG。名称为CreateOrUpdateDepartmentPG,路径为mycompany.oracle.apps.cux.test.webui。从名称可以看出,这个页面进行部门的添加和修改。可看到创建了页面,点击region1,对其属性进行修改属性AMWindowTitleTitle

值 说明mycompany.oracle.apps.cux.test.server.TestAM添加/修改部门Oracle-CUX部门管理右键region1,New—Region,并设置如下属性属性值说明IDRegionStyleDeptRNmessageComponentLayout网格组件Width60%宽度Rows1行Columns2列在DeptRN下添加三个item,并设置属性,使其关联VO属性IDItemStyleRequiredMaximumPromptViewInstance

值messageTextInputyes100部门编号DepartmentVO

说明必输与数据库一致VO的名称ViewAttributeViewAttributeDepartmentNumberVO的字段属性属性值说明IDDepartmentDescItemStylemessageTextInputMaximumLength240与数据库一致Prompt部门描述ViewInstanceDepartmentVOVO的名称ViewAttributeDepartmentDescVO的字段属性属性值说明IDDepartmentNameItemStylemessageTextInputRequiredyes必输MaximumLength100与数据库一致Prompt部门名称ViewInstanceDepartmentVOVO的名称ViewAttributeDepartmentNameVO的字段这样,就添加了三个输入框。然后,我们添加一个页面button属性值说明IDPageBtnRNRegionStyle属性值说明IDPageBtnRNRegionStylepageButtonBar属性值说明IDDepartmentNameItemStyle属性值说明IDDepartmentNameItemStylesubmitButtonPrompt 保存运行页面CreateOrUpdateDepartmentPG,看一下效果右键region1,SetNewController,路径为mycompany.oracle.apps.cux.test.webuiCreateOrUpdateDepartmentCO,可看到region1多了控制器属性,并生成了对应的java文件编辑CreateOrUpdateDepartmentCO方法,是的在进入页面的时候,VO创建一行数据,点击保存时,将其保存到数据库改变processRequest方法,此方法在页面进入时调用在cessRequest(pageContext,webBean);后添加代码://获得AMOAApplicationModuleam=pageContext.getApplicationModule(webBean);//反射方式新建一行if(!pageContext.isFormSubmission()){am.invokeMethod("deptNewRow");}改变processFormRequest方法,此方法在页面提交时调用在cessFormRequest(pageContext,webBean);后添加代码:OAApplicationModuleam=pageContext.getApplicationModule(webBean);if(pageContext.getParameter("SaveBtn")!=null){am.invokeMethod("save");}点击TestAM,双击打开TestAMImpl添加方法deptNewRow和save,都为publicpublicvoiddeptNewRow(){DepartmentVOImplvo=getDepartmentVO();if(!vo.isPreparedForExecution()){vo.setMaxFetchSize(0);vo.executeQuery();}Rowrow=vo.createRow();vo.insertRow(row);row.setNewRowState(Row.STATUS_INITIALIZED);}publicvoidsave(){this.getTransaction().commit();DepartmentVOImplvo=getDepartmentVO();ObjectdeptNum=vo.first().getAttribute("DepartmentNumber");//抛出消息MessageToken[]tokens={newMessageToken("DEPTNUMBER",deptNum.toString())};thrownewOAException("CUX","CUX_DEPT_SAVE_SUCCESS",tokens,OAException.CONFIRMATION,null);}添加一条消息CUX_DEPT_SAVE_SUCCESS&DEPTNUMBER保存成功!“&DEPTNUMBER”是占位符,前后应有空格,是可以替换的变量。测试点击保存,保存成功,后台查表头行关联已经实现了部门的插入,部门下面的员工可以与部门进行关联,实现类似Form行结构首先创建员工EO,方法同创建部门EO,这里就省略啦。注意修改create方法。然后创建员工VO,方法同创建部门VO,这里也省略啦。注意命名规范。先别急着将EmployeeVO加入到TestAMVL,然后通过VL将EmployeeVO加入到TestAM。右键test下的server,NewViewLink,路径为mycompany.oracle.apps.cux.test.serverDeptEmpVL,下一步,选择对应关系1对多,左侧选择DepartmentVO下的DepartmentId,右侧选择EmployeeVO下的DepartmentId,然后点击Add,如图然后下一步到完成。双击EmployeeVOviaDeptEmpVLDepartmentVO,将其加入到AM中如果右侧不选中DepartmentVO,会弹出提示框,说EmployeeVOviaDeptEmpVL只能加入到DepartmentVO下,选Yes即可。这样,EmployeeVO就通过DeptEmpVL加入到了AM中。接下来,我们在之前的CreateOrUpdateDepartmentPG页面,添加操作Employee的Region,一个部门对应多个员工,所以要创建的Region应该是支持多行数据的,我们使用table。在region1下创建一个region,并设置属性属性IDRegionText

值 说明EmpRNHeader员工信息右键EmpRN,New,RegionUsingWizard在弹出的对话框里,跳过引导项,AM选择TestAM,VO选择EmployeeVO下一步,RegionStyle选择table,下一步,属性选择EmployNumber,EmployName,EmployDesc,EffectiveDateFrom,EffectiveDateTo下一步,设置这五个字段的Prompt效期从,有效期至下一步,完成。可看到创建了一个table类型的region,其下包含五个item,并且其Prompt、MaximumLength、ViewInstance、ViewAttribute等属性已设置好。设置员工编号,员工姓名,有效期从的属性Required为也yes,与数据库保持一致。运行页面觉得table宽度不够,可以设置一下,建议使用百分比添加一个按钮,作用是添加一行员工在EmpRN下添加一个RN,ID为EmpBtnRN,RegionStyle为flowLayout在EmpBtnRN下添加一个item,设置属性属性IDItemPrompt

值 说明AddEmpsubmitButton添加员工在CreateOrUpdateDepartmentCO的processFormRequest方法里添加对AddEmp按钮的监听elseif(pageContext.getParameter("AddEmp")!=null){am.invokeMethod("addEmp");}在testAMImpl里,添加方法addEmppublicvoidaddEmp()EmployeeVOImplvo=getEmployeeVO();Rowrow=vo.createRow();vo.insertRowAtRangeIndex(vo.getRowCountInRange(),row);row.setNewRowState(Row.STATUS_INITIALIZED);}测试页面,运行CreateOrUpdateDepartmentPG部门表员工表删除我们在每个员工信息的最后添加一个删除图标,点击可以删除该行记录在EmployeeVO下添加一个item,设置属性属性IDItemStylePromptImageURIActionEventParameters

值DeleteEmpImgimage删除deleteicon_enabled.giffireActiondeleteEmpEmpId O.EmployeeId}

说明参数Submit true 注意:不是commit在CreateOrUpdateDepartmentCO的processFormRequest方法里添加代码,用来监听deleteEmp事件elseif("deleteEmp".equals(pageContext.getParameter(EVENT_PARAM))){StringempId=pageContext.getParameter("EmpId");am.invokeMethod("deleteEmp",newString[]{empId});}在testAMImpl里添加方法deleteEmppublicvoiddeleteEmp(StringempId)EmployeeVOImplvo=getEmployeeVO();Rowrow;intRowCount=vo.getRowCount();for(inti=0;i<RowCount;i++){row=vo.getRowAtRangeIndex(i);Stringid=row.getAttribute("EmployeeId").toString();if(id.equals(empId)){row.remove();break;}}}测试页面,先添加两行,保存查看数据库删除一行,保存查看数据库,只有一条数据,说明删除成功查询扩展页面DepartmentQueryPG和DepartmentQueryVO下面对次查询进行一些扩展。一些情况的查询需要代码辅助,比如范围查询,查询包含某一员工的部门等等。DateTypeDate,如下图此时使用单纯的queryCriteriaMap已经不能满足要求,这需要在点击“搜索”时,对VO增加限制,首先为该页面添加一个CO,取名DepartmentQueryCO,在processFormRequest方法后添加“搜索”按钮的捕捉事件。OAQueryBeanqueryRN=(OAQueryBean)webBean.findIndexedChildRecursive("QueryRN");System.out.println(queryRN.getCurrentSearchPanel())//当前搜索面板System.out.println(queryRN.getGoButtonName());//搜索按钮名称if(SEARCH.equals(queryRN.getCurrentSearchPanel())&&pageContext.getParameter("customizeSubmitButton")!=null){System.out.println("eee");}这是先做个测试,确定捕捉到了“搜索”按钮,而且屏蔽其他的提交事件。VO首先修改DepartmentQueryCO的processFormRequest方法OAApplicationModuleam=pageContext.getApplicationModule(webBean);OAQueryBeanqueryRN=(OAQueryBean)webBean.findIndexedChildRecursive("QueryRN");if(SEARCH.equals(queryRN.getCurrentSearchPanel())&&pageContext.getParameter("customizeSubmitButton")!=null){OAMessageDateFieldBeancreationDateFrom=(OAMessageDateFieldBean)webBean.findChildRecursive("CreationDateFrom");OAMessageDateFieldBeancreationDateTo=(OAMessageDateFieldBean)webBean.findChildRecursive("CreationDateTo");Objectfrom=creationDateFrom.getValue(pageContext);Objectto=creationDateTo.getValue(pageContext);am.invokeMethod("QueryCreationDate",newString[]{from==null?null:from.toString().substring(0,10),to==null?null:to.toString().substring(0,10)});}然后在TestAMImpl里添加方法QueryCreationDatepublicvoidQueryCreationDate(Stringfrom,Stringto){StringfromDate=from==null?"trunc(creation_date)":"to_date('"+from+"','yyyy-mm-dd')";StringtoDate=to==null?"trunc(creation_date)":"to_date('"+to+"','yyyy-mm-dd')";StringwhereClause="trunc(creation_date)between"+fromDate+"and"+toDate;DepartmentQueryVOImplvo=getDepartmentQueryVO();vo.setWhereClause(null);vo.setWhereClause(whereClause);vo.executeQuery();}测试,成功如果有业务需求是SearchDeptNum和SearchDeptName至少输入一个,一个属性就可以办到。设置SearchDeptNum和SearchDeptName的属性SelectiveSearchCriteria为True,测试,二者都不输入,就可以看到抛出错误查询界面添加按钮,创建部门,点击按钮实现页面调整到CreateOrUpdateDepartmentPG页面,并创建一行数据。右键部门table,New,tableActions,创建一个Region在其下创建一个item,并设置属性属性IDItemPrompt

值 说明CreateDepartmentsubmitButton创建部门运行页面,预览一下然后,在CO里编写其监听事件elseif(pageContext.getParameter("CreateDepartment")!=null){pageContext.forwardImmediately("OA.jsp?page=/mycompany/oracle/apps/cux/test/webui/CreateOrUpdateDepartmentPG",null,OAWebBeanConstants.KEEP_MENU_CONTEXT,null,null,true,OAWebBeanConstants.ADD_BREAD_CRUMB_NO);}测试,页面进行了调整,输入一个数据,保存成功添加链接,进入修改界面在部门的table下,添加一个item,并设置属性属性IDItemStylePromptImageURIActionEventParameters

值UpdateDeptImgimage修改updateicon_enabled.giffireActionupdateDeptDeptId ${oa.DepartmentmentId}

说明参数Submit预览一下效果

true 注意:不是commit然后在CO里添加监听事件elseif("updateDept".equals(pageContext.getParameter(EVENT_PARAM)))StringdeptId=pageContext.getParameter("DeptId");HashMapmap=newHashMap();map.put("operation","update");map.put("deptId",deptId);pageContext.forwardImmediately("OA.jsp?page=/mycompany/oracle/apps/cux/test/webui/CreateOrUpdateDepartmentPG",null,OAWebBeanConstants.KEEP_MENU_CONTEXT,null,map,true,OAWebBeanConstants.ADD_BREAD_CRUMB_NO);}CreateOrUpdateDepartmentPG页面初始化的时候,需要判断,修改CreateOrUpdateDepartmentCO的processRequest方法OAApplicationModuleam=pageContext.getApplicationModule(webBean);Stringoperation=pageContext.getParameter("operation");StringdeptId=pageContext.getParameter("deptId");if(!pageContext.isFormSubmission()){if("update".equals(operation)&&deptId!=null){am.invokeMethod("deptQuery",newString[]{deptId});}else{am.invokeMethod("deptNewRow");}}然后,在TestAMImpl里,添加方法deptQuerypublicvoiddeptQuery(StringdeptId){DepartmentVOImplvo=getDepartmentVO();vo.setWhereClause("DEPARTMENT_ID=:1");vo.setWhereClauseParam(0,deptId);vo.executeQuery();}测试,点击更新页面跳转,并且数据已加载出来修改用到了Oracle提供的PPR技术,在本文档3.2会有介绍。数据校验Oracle内置校验Web客户端校验等等,这些如果输入有误,页面会直接弹出警告,如在点击按钮保存时,就会先进行页面校验,如果想取消该校验,设置属性DisableClientSideValidation为False即可服务器端校验这里主要是EO的校验,EO的类型,是否必输等等,在保存和更新前进行校验我们这里把部门名称的页面字段设置为非必输,然后不输人任何值,进行保存抛出异常在开发的过程中,难免会有一些数据库的变动,比如某个字段之前是必输,EO经创建好,由于业务需要,该字段变为非必输,但是此时EO没变,还是必输,这就造成了错误,解决办法是,可以让EO与数据库进行同步,右键EO这样就可以啦如果想取消该校验,设置属性DisableServerSideValidation为False即可手动校验Oracle自己的校验。CO都是从OAControllerImplprocessFormRequestprocessFormData,加入自己的校验。所以在CreateOrUpdateDepartmentCO添加方法publicvoidprocessFormData(OAPageContextpageContext,OAWebBeanwebBean){cessFormData(pageContext,webBean);}我们自己创造一个业务需求,比如部门编号至少4单if(pageContext.getParameter("SaveBtn")!=null){OAMessageTextInputBeandeptNumBean=(OAMessageTextInputBean)webBean.findChildRecursive("DepartmentNumber");ObjectdeptNum=deptNumBean.getValue(pageContext);if(deptNum.toString().length()<4){thrownewOAException("CUX","CUX_DEPTNUM_MIN_LENGTH",null,OAException.CONFIRMATION,null);}}添加一条消息CUX_DEPTNUM_MIN_LENGTH4位!”测试,成功常用布局请参考文档,文件位置是jdevdoc\index.htmflowLayout和stackLayout别不大。二者的区别在底层,所用的数据结构不一样,一个是数组,一个是堆栈。messageComponentLayout这个布局使用比较多,通常我们布局页面的时候,会遇到诸如“m行n格布局,这时候可以使用此布局。此布局局限在规范的表格布局,暂不支持合并单元格。它在放置组件的时候,是竖着排列的,这个和我们正常的思维有点不一致。我做一个3行2列的例子布局效果header和hideShowHeader先看一下header效果,text属性为“header测试”这个布局用来对界面进行分块,使界面美观、清晰。而hideShowHeader可以折叠和展开,首先在VO里添加一个自定义属性,取名HideShowFlag,类型为Boolean(true/false)修改hideShowHeaderChildViewInstance和ChildViewAttribute测试,成功table和tableLayouttable布局比较简单,也很常用,常见于多个数据的显示,之前已使用,这里不多说table下其实还可以有table,即所谓的tableintable,比如一个部门下有多个员工,在搜索出部门的同时,也要同时看到员工,如下图我们有两个VO,部门VO和员工VO,并且新建了VL,连接两个VO右键查询界面的DepartmentQueryVO,New,detail会出现detail和一个region,修改region为flowLayout,利用向导在其下添加员工table,VO使用EmployeeVO1,所有item为messageStyledTexttableEmployeeVO,设置属性ViewLinkInstance的值为DeptqueryEmpVL1单击查询界面的DepartmentQueryVO,设置属性DetailViewAttribute属性为HideShowFlag,DepartmentQueryVO中如果没有该属性,添加一个,类型为Boolean测试,成功tableLayout则是可以针对每行,每个单元格进行编辑的布局,每个tableLayout下可以新建rowLayout,每个rowLayout下可以新建cellFormat,cellFormat可以进行合并单元格,设置显示的对其方式等等属性,比较灵活。query这是查询控件,使用方法已在本文档1.4.2和1.4.3进行了介绍。switcher情况就需要使用switcher来进行切换双击DepartmentQueryVO,左侧选择SQLStatement,修改SQL语句在sql里添加一个查询字段decode(t.created_by,fnd_global.USER_ID,'UpdateDeptImg','DisUpdateDeptImg')can_update_dept点击应用,可看到DepartmentQueryVO里多了字段CanUpdateDept右键查询界面的DepartmentQueryVO,New,switcher修改switcher属性属性IDRegionStylePromptViewInstanceViewAttribute

值 说明CanUpdateDeptswitcher更新DepartmentQueryVOCanUpdateDept新建switcher时,会自动在其下新建一个case,将查询界面DepartmentQueryVO下的UpdateDeptImg拖拽到switcher下的case下面拖拽后在刚刚创建的switcher下新建一个case在case下新建一个item,并更改属性属性IDItemStyleImage

值 说明DisUpdateDeptImgimageupdateicon_disabled.gif运行查询界面,测试,成功pageButtonbarCreateOrUpdateDepartmentPG界面已经使用过,没有特别的地方,其下一般添加button或submitButton,特点是界面上下都会显示,自动靠右。subTabLayout在数据量较大或者需要进行分类显示时,经常使用tab新建一个region,RegionStyle选subTabLayout在其下新建三个region,每个region下新建一个item右键刚刚创建的subTabLayout,New,subTabs在subTabBar1下新建三个link,ID设置为link1、link2,link3,Text设置为tab1、tab2、tab3,三个link与之前新建的三个Region相对应测试,成功shuttle这个组件只看名字比较迷茫,不知道什么东东,先来看看界面首先保证该组件所在page的form属性为true创建一个region,设置一些必要的属性,如id等,主要设置:Region的类型设置为shuttleIndexedChildren属性为trueAvailableHeader属性为空SelectedHeader属性为空OrderingAllowed属性为trueshuttleleading设置一些必要属性,如id等,主要设置:Multi-SelectAllowed属性为truePicklistViewInstance属性为VOPicklistDisplayAttribute属性为VO要显示的属性PicklistValueAttribute属性为VO要返回的属性shuttletrailingleadingVO,也可以不用。区别在于初始化时会不会显示内容。运行除此以外,还可以新建leadingFooter和trailingFooterleading和trailing下边显示CO控制OADefaultShuttleBeanshuttle=(OADefaultShuttleBean)webBean.findChildRecursive("UserList");String[]trailingItems=shuttle.getTrailingListOptionValue

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论