You would find lots of blogs about how to create and mail PDF using XML Publisher. So I do not want to repeat it. Just want to talk about how to format the e-mail that is sent out. If you have tried to format using HTML tags only, you would have noticed that they are removed when the email is sent out. What you need to do is include the format in CDATA section. Take a look at this
doing this would preserve the HTML formatting. This is how the e-mail would like
--------------------------------------------------------------------------------------
Dear
Please find attached Supplier Report
Regards
XML Publisher Burster
--------------------------------------------------------------------------------------
Cheers
Thursday, September 17, 2009
About Me
I am working in IT industry since million years. I started working with world's biggest Oracle Applications company, you guessed right, Oracle. I had been with Oracle for real long time, worked in Product development.Working at Oracle is a great learning experience. During my tenure at Oracle, I worked in different roles, from Application Developer to Project Lead. I had authored numerous Product Requirements documents, Functional Designs, Technical Designs. I had created countless objects (Tables, Sequences, Views, Synonyms, Forms, Reports, OA Pages, Workflows, Business Events, Concurrent Programs, Patches etc etc) and have seen major Apps Release cycles during the entire tenure. I can definitely say I had great time working with Oracle.
And now I work outside Oracle supporting the very products that I was involved in building. My work currently is in Procure-to-Pay side in core modules as well as i-modules (iExpense, iProcurement). It is both fun and great learning to see how the products that one is involved creating in are perceived and used by the application users.
Most of the blog entries that you find on my blog are based on my work at different times. You are free to use the ideas, code presented on my blog as long as you point to this blog.
If they work for you, I would be happy if you leave a note here.
Cheers
And now I work outside Oracle supporting the very products that I was involved in building. My work currently is in Procure-to-Pay side in core modules as well as i-modules (iExpense, iProcurement). It is both fun and great learning to see how the products that one is involved creating in are perceived and used by the application users.
Most of the blog entries that you find on my blog are based on my work at different times. You are free to use the ideas, code presented on my blog as long as you point to this blog.
If they work for you, I would be happy if you leave a note here.
Cheers
Tuesday, September 15, 2009
Interesting IN clause
This is cool use of IN clause.
SQL>
SQL> CREATE TABLE t (a NUMBER, b NUMBER, c NUMBER, d NUMBER);
Table created.
SQL> DESC t
Name Null? Type
------------------------------- -------- ----
A NUMBER
B NUMBER
C NUMBER
D NUMBER
SQL> INSERT INTO t VALUES (1,2,3,4);
1 row created.
SQL> INSERT INTO t VALUES (5,6,7,8);
1 row created.
SQL> INSERT INTO t VALUES (1,4,5,6);
1 row created.
SQL> INSERT INTO t VALUES (1,6,7,8);
1 row created.
SQL> SELECT * FROM t WHERE 1 IN (a,b,c,d);
A B C D
---------- ---------- ---------- ----------
1 2 3 4
1 4 5 6
1 6 7 8
SQL> SELECT * FROM t WHERE 3 IN (a,b,c,d);
A B C D
---------- ---------- ---------- ----------
1 2 3 4
SQL> SELECT * FROM t WHERE 5 IN (a,b,c,d);
A B C D
---------- ---------- ---------- ----------
5 6 7 8
1 4 5 6
SQL>
Wednesday, September 9, 2009
Deferred Approvals for PO/Req
Ever faced this issue?
Approver responds to approval notification and still the document(Requisition or Purchase Order) shows status "In Process"? And the recent approval not recorded?
When this issue shows, chances are that the approver is a "Delegated Approver" means not the original approver. In this case for Delegated Approvers, to avoid context issues, the workflow is set to "Deferred" mode. You have to run Workflow Background Process to move the deferred workflow to next stage.
Refer Metalink note 387489.1 - Requisition Approval In Deferred Status If Notification Is Delegated for more.
Approver responds to approval notification and still the document(Requisition or Purchase Order) shows status "In Process"? And the recent approval not recorded?
When this issue shows, chances are that the approver is a "Delegated Approver" means not the original approver. In this case for Delegated Approvers, to avoid context issues, the workflow is set to "Deferred" mode. You have to run Workflow Background Process to move the deferred workflow to next stage.
Refer Metalink note 387489.1 - Requisition Approval In Deferred Status If Notification Is Delegated for more.
External File Upload into Apps
There are indeed a lot of programs/processes that need some external file as input. There are different ways to make this file available in Oracle Apps environment.
1. You can use some FTP UIs like SFTP, which users can login to server and post the files. You can control the folders to which what users have access to. There are obvious drawbacks to this. You need to maintain separate server accounts for users, maintain those and for users they have one more login/password information to track. Again you would need to create the same accounts on test servers also.
2. You can write simple JSP page and expose this JSP function to users
3. Or you can write OA Framework File Upload Page. I feel this approach is simpler.
Let us see how we can do file upload using Framework (11510)
All you need to do is use messageFileUpload bean, see the page XML.

Next is the controller where you do the actual reading and writing of the file.
processFormRequest is where the logic would reside.
Here is what I think should be done for download, I have not tried these steps yet, would do that sometime later.
First you need to browse through folder and generate a file-list. Java would be slower to browse if your folder has huge number of files. Better approach is to use a simple shell script that creates a flat file, it can be a one line code such as
Following code snippet is for streaming out from postFormsRequest..
.
For standard concurrent requests, FND_WEBFILE.GET_URL generates a temp URL. (Tools --> Copy on the Concurrent Request Log/Output file)
Cheers!
1. You can use some FTP UIs like SFTP, which users can login to server and post the files. You can control the folders to which what users have access to. There are obvious drawbacks to this. You need to maintain separate server accounts for users, maintain those and for users they have one more login/password information to track. Again you would need to create the same accounts on test servers also.
2. You can write simple JSP page and expose this JSP function to users
3. Or you can write OA Framework File Upload Page. I feel this approach is simpler.
Let us see how we can do file upload using Framework (11510)
All you need to do is use messageFileUpload bean, see the page XML.
Next is the controller where you do the actual reading and writing of the file.
processFormRequest is where the logic would reside.
public void processFormRequest(OAPageContext pageContext, OAWebBean webBean)
{
super.processFormRequest(pageContext, webBean);
String event = (String) pageContext.getParameter(EVENT_PARAM);
OAApplicationModule AM = (OAApplicationModule) pageContext.getApplicationModule(webBean);
DataObject fileUploadData = (DataObject)pageContext.getNamedDataObject("fileUpload");
String productName = pageContext.getParameter("productName");
String applcsfPath = pageContext.getProfile("APPLCSF_ABS_PATH");
/*this is the profile where you can put the actual physical location of the folder
where you intend to store the files. This is more like a basepath. you can have this
basepath in the profile and then for each upload function, you can pass different arguments
say for sub-floders etc.*/
if ("uploadFile".equals(event))
{
if (fileUploadData == null)
{
throw new OAException("APP", "NO_FILE_TO_LOAD");
}
String uFileName = (String)fileUploadData.selectValue(null, "UPLOAD_FILE_NAME");
BlobDomain byteStream = (BlobDomain)fileUploadData.selectValue(null, uFileName);
try
{
String filePath = applcsfPath+"/";
System.out.println("filePath : " + filePath);
System.out.println("uFileName : " + uFileName);
FileOutputStream fileOp = new FileOutputStream(filePath+uFileName);
fileOp.write(byteStream.getBytes(0,(int)byteStream.getLength()));
fileOp.close();
fileUploadData = null;
pageContext.removeNamedDataObject("fileUpload");
OAException confirmMessage = new OAException("APP", "FILE_UPLOAD_SUCCESS", null,
OAException.CONFIRMATION, null);
pageContext.putDialogMessage(confirmMessage);
}
catch(Exception e)
{
System.out.println("File Upload Error " + e.toString());
e.printStackTrace();
throw new OAException(e.getMessage(), OAException.ERROR);
}
}
}
That is all to upload a file, simple and straightforward. You would need following imports apart from the regular ones.import oracle.cabo.ui.data.DataObject; import oracle.jbo.domain.BlobDomain; import java.io.FileOutputStream;Now, let us say we want to build a download function. There is a download bean, but more about it later. You can expose specific files in httpd.conf making aliases for folders, but this approach does not provide much security.
Here is what I think should be done for download, I have not tried these steps yet, would do that sometime later.
First you need to browse through folder and generate a file-list. Java would be slower to browse if your folder has huge number of files. Better approach is to use a simple shell script that creates a flat file, it can be a one line code such as
grep -ir -v -l 'cantfindthis' $APPLCSF > 1.txtThen in java code, you can loop through the file (1.txt) and insert the data into a Global Temp table[or the grep output could be redirected directly to java which you can loop through] . Inserting this file list into table provides a good means to have search UI. Next is build search UI and a results tables. Now comes the actual download part. You can add a single-select and a button or link the filename to a submit action. This submit action should can throw open a new page and the file can be streamed out.
Following code snippet is for streaming out from postFormsRequest..
.
void throwZip(String pDocList, String pFileName,OAPageContext pageContext)
{
//System.out.println("Throwing Docs!");
URLConnection connURL = null;
URL url = null;
InputStream inStream = null;
HttpServletResponse httpResponse = null;
ZipOutputStream outStream = null;
DataObject sessionDictionary = pageContext.getNamedDataObject("_SessionParameters");
StringTokenizer stURLToken = new StringTokenizer(pDocList,",");
int urlCount = stURLToken.countTokens();
int i = 0;
boolean closeConnection = false;
while(stURLToken.hasMoreTokens())
{
i = i + 1;
String stURL = stURLToken.nextToken();
closeConnection = false;
try
{
if (i == 1)
{
httpResponse = (HttpServletResponse)sessionDictionary.selectValue(null, "HttpServletResponse");
httpResponse.setContentType("application/x-zip-compressed");
httpResponse.setHeader("Content-Disposition", "Attachment; Filename=" + pFileName);
outStream = new ZipOutputStream(httpResponse.getOutputStream());
}
url = new URL(stURL);
connURL = url.openConnection();
inStream = connURL.getInputStream();
outStream.putNextEntry(new ZipEntry(stURL.substring(stURL.lastIndexOf("/"))));
byte bytes[] = new byte[1024];
for(int bytesRead = inStream.read(bytes); bytesRead > 0;)
{
outStream.write(bytes, 0, bytesRead);
bytesRead = inStream.read(bytes);
outStream.flush();
}
outStream.closeEntry();
}
catch(Exception e)
{
System.out.println("Exception 1 " + e.toString());
closeConnection = true;
throw OAException.wrapperException(e);
}
finally
{
try
{
if (closeConnection || (i==urlCount))
{
System.out.println("Closing Connections ");
if(inStream != null)
inStream.close();
if(outStream != null)
outStream.close();
}
}
catch(Exception e)
{
System.out.println("Exception 2 " + e.toString());
throw OAException.wrapperException(e);
}
}
}
}
.For standard concurrent requests, FND_WEBFILE.GET_URL generates a temp URL. (Tools --> Copy on the Concurrent Request Log/Output file)
Cheers!
Electronic Payment Processing
Almost all Oracle Apps installations deal with Electronic Vendor Payments with Banks. In general the steps are as below --
1. Payables User/Manager creates a Payment Batch
2. Verifies all payments, removes payments that are too high or too low
3. Then payment is formatted, now at this stage, since most of the format reports are custom programs, a control could be easily set. Once the payment is formatted, the details could be sent to approver via a custom workflow. This way you have tracking of approver trails and any custom logic can be built around in the workflow.
4. Approver can review the batch contents, totals etc and then either reject or approve the payment.
5. Once it is approved by approver, the Payables Manger can confirm the batch.
6. Now comes the part where the format file is encrypted and sent to bank server.
This part could be built to have some sort of fail-safe mechanism. You can have a dedicated FTP program or mailer program whichever way your bank accepts files.
This program can take the payment batch as input and find out the formatted output for the batch. It can encrypt the file based on banks requirement, maintain a custom table where details such as who ran FTP, result of it and file names and locations for encrypted and raw file. You can also maintain login/password information for the bank servers in separate table and use this while doing FTP or mail.
You can also make this FTP program re-runnable in the sense that, you should be able to send the encrypted file for any past payment batches if needed.
There is one more important aspect. If you are using a FTP function, you can ask your bank to create a test folder and one production folder. That way you can put files from your test environment separately from production environment. For the encryption, you can also request two separate keys from the bank, one for test and one for production.
1. Payables User/Manager creates a Payment Batch
2. Verifies all payments, removes payments that are too high or too low
3. Then payment is formatted, now at this stage, since most of the format reports are custom programs, a control could be easily set. Once the payment is formatted, the details could be sent to approver via a custom workflow. This way you have tracking of approver trails and any custom logic can be built around in the workflow.
4. Approver can review the batch contents, totals etc and then either reject or approve the payment.
5. Once it is approved by approver, the Payables Manger can confirm the batch.
6. Now comes the part where the format file is encrypted and sent to bank server.
This part could be built to have some sort of fail-safe mechanism. You can have a dedicated FTP program or mailer program whichever way your bank accepts files.
This program can take the payment batch as input and find out the formatted output for the batch. It can encrypt the file based on banks requirement, maintain a custom table where details such as who ran FTP, result of it and file names and locations for encrypted and raw file. You can also maintain login/password information for the bank servers in separate table and use this while doing FTP or mail.
You can also make this FTP program re-runnable in the sense that, you should be able to send the encrypted file for any past payment batches if needed.
There is one more important aspect. If you are using a FTP function, you can ask your bank to create a test folder and one production folder. That way you can put files from your test environment separately from production environment. For the encryption, you can also request two separate keys from the bank, one for test and one for production.
Friday, September 4, 2009
Restrict Payment Types per Responsibility
There was a simple requirement to restrict payment types for Manual Payments for specific responsibilities. This can be achieved using CUSTOM.pll, by changing the actual form code or the simplest option is to use Forms Personalization.
You can create a new record group using custom query and then attach this record group to the LOV of the field. Here are the details
1. First Select Trigger Event 'WHEN-NEW-ITEM-INSTANCE', set Trigger Object as the item whose LOV is to be changed
2. The condition should verify that the record is in insert mode, i.e. a new record. You do not want to change the LOV values for older committed records
3. In the context, set all the responsibilities for which this change is to be reflected
4. Now coming to the actions, select "Builtin" as Type and select "Create Record Group from Query" as "Builtin Type"
5. Put your custom SQL in the Argument
6. Give name to your custom record group
7. In the subsequent action, set the LOV property "Record Group" to your custom record group
8. You can also add more actions to default the value for the item. Default to both description and lookup code.
Cheers!
You can create a new record group using custom query and then attach this record group to the LOV of the field. Here are the details
1. First Select Trigger Event 'WHEN-NEW-ITEM-INSTANCE', set Trigger Object as the item whose LOV is to be changed
2. The condition should verify that the record is in insert mode, i.e. a new record. You do not want to change the LOV values for older committed records
3. In the context, set all the responsibilities for which this change is to be reflected
4. Now coming to the actions, select "Builtin" as Type and select "Create Record Group from Query" as "Builtin Type"
5. Put your custom SQL in the Argument
6. Give name to your custom record group
7. In the subsequent action, set the LOV property "Record Group" to your custom record group
8. You can also add more actions to default the value for the item. Default to both description and lookup code.
Cheers!
Using Corporate Logo throughout Oracle Apps
If you want to use your company specific logo throughout Oracle Applications self service pages, then
1. Copy the image on either $OA_HTML or $OA_MEDIA, its better to have a gif image.
2. Set Profile option "Corporate Branding Image for Oracle Applications" at site level e.g. $OA_MEDIA/company.gif
3. Bounce Apache
If the user is not able to see the new image at runtime, ask the user to clear the browser cache.
1. Copy the image on either $OA_HTML or $OA_MEDIA, its better to have a gif image.
2. Set Profile option "Corporate Branding Image for Oracle Applications" at site level e.g. $OA_MEDIA/company.gif
3. Bounce Apache
If the user is not able to see the new image at runtime, ask the user to clear the browser cache.
Not Publishing Attachments
If you are using the attachments in seeded iExpense/iProcurement, you would notice a 'Publish to Catalog' button. If this is enabled, and there is no security, then any user can search existing attachments and can publish to the catalog. Exposing all catalog to everyone can have unwanted implications for the company.
If you want to disable the publishing, just take out all menu items under this menu "Attachments:Publish to catalog Permission Set".
If you want to disable the publishing, just take out all menu items under this menu "Attachments:Publish to catalog Permission Set".
Payment Batch cannot be Confirmed
Strange error today in Payables, could not confirm Payment Batch. The error message was "APP-SQLAP-10373: To Document Number accounts for more payment documents than those which are in the payment batch. Please re-enter a lower To Document Number." As per Metalink Note 265368.1, this is intended functionality.
I checked the payment batch, it had total 173 payments, out of which only 101 were made OK to pay and rest not selected for payment as they were either below zero or zero. Checked the check numbers in the prelim register and in the account setup. Everything looked okay.
Then started search for the source of the error, first figured out whats the message short name, it is AP_PAY_DOC_NOT_IN_BATCH. Found its not used in any of the PLSQL code. So started grep'ing the AP forms, and found a hit in Payment Workbench APXPAWKB.fmb form. Looked at the form routine TEST_OVERFLOW, this one calls database PLSQL AP_CONFIRM_FORM_PKG.test_overflow_checks. Ran the SQLs in this routines, everything was good. Could not figure out why this error was being thrown.
Finally tried to work around this problem. Navigate to Payment Confirm Window where you see the check numbers From /To and buttons Cancel/Confirm/Restart. Selected Restart option, and this time the Payment Batch was confirmed without any issues.
While I did not find a root cause for this issue, this work-around did work.
I checked the payment batch, it had total 173 payments, out of which only 101 were made OK to pay and rest not selected for payment as they were either below zero or zero. Checked the check numbers in the prelim register and in the account setup. Everything looked okay.
Then started search for the source of the error, first figured out whats the message short name, it is AP_PAY_DOC_NOT_IN_BATCH. Found its not used in any of the PLSQL code. So started grep'ing the AP forms, and found a hit in Payment Workbench APXPAWKB.fmb form. Looked at the form routine TEST_OVERFLOW, this one calls database PLSQL AP_CONFIRM_FORM_PKG.test_overflow_checks. Ran the SQLs in this routines, everything was good. Could not figure out why this error was being thrown.
Finally tried to work around this problem. Navigate to Payment Confirm Window where you see the check numbers From /To and buttons Cancel/Confirm/Restart. Selected Restart option, and this time the Payment Batch was confirmed without any issues.
While I did not find a root cause for this issue, this work-around did work.
Catalog Loader
Ever faced this problem?
Catalog loader fails with USR:MSG:POM_CAT_UNKNOWN_SEC Error Message
You have download sample catalog file from Apps and prepared a new one according to the sample. But still it fails.
You cross check the sample and your file, and you spot no differences.
Whats happening??
The metalink note "271354.1 - Bulk Loader Fails with USR:MSG:POM_CAT_UNKNOWN_SEC Error Message" suggest the format is wrong and says there should not exist any blank lines between the heading and its associated data lines.
This sentence "any blank lines between heading and data lines" can be misleading .
Thing is if there are blank lines at the end after all your data, the file would fail upload.
So remove all blank lines from the file and make sure the last record is indeed last record with no blanks.
Cheers!
Catalog loader fails with USR:MSG:POM_CAT_UNKNOWN_SEC Error Message
You have download sample catalog file from Apps and prepared a new one according to the sample. But still it fails.
You cross check the sample and your file, and you spot no differences.
Whats happening??
The metalink note "271354.1 - Bulk Loader Fails with USR:MSG:POM_CAT_UNKNOWN_SEC Error Message" suggest the format is wrong and says there should not exist any blank lines between the heading and its associated data lines.
This sentence "any blank lines between heading and data lines" can be misleading .
Thing is if there are blank lines at the end after all your data, the file would fail upload.
So remove all blank lines from the file and make sure the last record is indeed last record with no blanks.
Cheers!
Enforcing Attachments in iExpense/iProcurement
This is one of the cool things that I have done in quite sometime, customization to enforce attachments for Requisitions and Expense Reports. The code does not really check the contents of the attachments, it just checks if the attachments are present or not.
At first, you might think whats the big deal here, you could just use POR_CUSTOM_PKG and AP_WEB_CUST_DFLEX_PKG packages to check if the FND_ATTACHED_DOCUMENTS table has entries for the corresponding requisition or expense report. The issue with using custom hooks is, you do not have control when they would be invoked. If you use the custom hooks to enforce the check, you wont go anywhere.
You could say, why not put the check in the workflow? Return the document to users if there is no attachment. Would it not be better to prevent submission in the first place if the document does not have attachments? You bet it is much cleaner design.
But just checking this table in the custom hooks does not work at all. Why? Simply because the attachments are not pushed to database unless the requisition or expense report is submitted. And you do not want users to submit these without attachments in the first place. This means you need to check in the database as well as middle tier.
How to solve this then?
This needs playing around with Framework code. First you have to figure out the which page is doing the request submission. Once you figure that out, find out the relevant CO (Controller classes). Then you have to get handle to the FND Attachments VO, and check if the VO has any records. If you do not find any records in here, then check if the attachments are there in database. Doing it this way its going to be a foolproof solution.
The real challenge is to figure out right attachments VO. It took me quite sometime to figure out which VO it was really. Its fun, I can tell you.
At first, you might think whats the big deal here, you could just use POR_CUSTOM_PKG and AP_WEB_CUST_DFLEX_PKG packages to check if the FND_ATTACHED_DOCUMENTS table has entries for the corresponding requisition or expense report. The issue with using custom hooks is, you do not have control when they would be invoked. If you use the custom hooks to enforce the check, you wont go anywhere.
You could say, why not put the check in the workflow? Return the document to users if there is no attachment. Would it not be better to prevent submission in the first place if the document does not have attachments? You bet it is much cleaner design.
But just checking this table in the custom hooks does not work at all. Why? Simply because the attachments are not pushed to database unless the requisition or expense report is submitted. And you do not want users to submit these without attachments in the first place. This means you need to check in the database as well as middle tier.
How to solve this then?
This needs playing around with Framework code. First you have to figure out the which page is doing the request submission. Once you figure that out, find out the relevant CO (Controller classes). Then you have to get handle to the FND Attachments VO, and check if the VO has any records. If you do not find any records in here, then check if the attachments are there in database. Doing it this way its going to be a foolproof solution.
The real challenge is to figure out right attachments VO. It took me quite sometime to figure out which VO it was really. Its fun, I can tell you.
Deadlock issue in Purchase Order Approvals
Since we migrated to 11510, we have been facing locking issue during PO Approval. The workflow always errored out with table PO_HEADERS_ALL locking issue. We have had the same customizations in 1159 and 11510.
What changed in 11510 is that all updates to PO_HEADERS_ALL table are moved to autonomous session. And our custom code did not have this change. Once we changed our custom updates to be done in autonomous session, this issue was gone for good.
How did I find out the issue?
I checked through core PO code, and saw that all the updates to PO_HEADERS_ALL are done in autonomous session. Checked that on metalink too, found Note 749923.1 and Note 404774.1 which point to core code updates not being in autonomous mode leading to deadlocks. This was good enough indicator to move the custom updates to PO_HEADERS_ALL in autonomous session.
What changed in 11510 is that all updates to PO_HEADERS_ALL table are moved to autonomous session. And our custom code did not have this change. Once we changed our custom updates to be done in autonomous session, this issue was gone for good.
How did I find out the issue?
I checked through core PO code, and saw that all the updates to PO_HEADERS_ALL are done in autonomous session. Checked that on metalink too, found Note 749923.1 and Note 404774.1 which point to core code updates not being in autonomous mode leading to deadlocks. This was good enough indicator to move the custom updates to PO_HEADERS_ALL in autonomous session.
Thursday, September 3, 2009
SOAP Call from Oracle Apps
I was looking for some helper/bases classes from OA Framework to invoke a SOAP Service. Turned out there is no native structures in OA Framework and there are no specific directions. Just create a SOAP client using whatever you want and invoke the Web service.
So here is what I did ...
There is good tutorial at http://java.sun.com/javaee/5/docs/tutorial/doc/bnbhr.html
That could be another approach to invoke SOAP service.
Thanks to countless developer folks on the web, the SOAP service call was finally built and tested successfully.
For https based service requests, you would need to import the site security certificate in java's keystore. If it is simple http, then no need to do anything. To make this java program work, I had to use following libraries.
So here is what I did ...
import java.io.*;
import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.message.SOAPEnvelope;
import org.w3c.dom.*;
public class AxisClientCall
{
public AxisClientCall()
{
}
public static void callService()
{
try {
String SOAPUrl = "https://exactEndPointURL";
String SOAPAction = "SOAPAction as Defined in WSDL";
String operName = "Operation Name as Defined in WSDL";
FileInputStream fin = new FileInputStream("SOAPRequest.xml");
SOAPEnvelope requestEnv = new SOAPEnvelope ((InputStream)fin);
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(SOAPUrl) );
call.setUseSOAPAction(true);
call.setSOAPActionURI(SOAPAction);
call.setEncodingStyle(null);
call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
call.setOperationName(new QName("", operName) );
SOAPEnvelope responseEnv = call.invoke(requestEnv );
System.out.println(" responseEnv = " + responseEnv);
if (responseEnv!=null)
{
Document doc = responseEnv.getAsDocument();
oracle.xml.parser.v2.XMLElement o = (oracle.xml.parser.v2.XMLElement) doc.getDocumentElement();
OutputStream out = System.out;
o.print(out);
}
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.toString());
}
}
public static void main(String[] args)
{
AxisClientCall AxisClientCall = new AxisClientCall();
AxisClientCall.callService();
}
}
There is good tutorial at http://java.sun.com/javaee/5/docs/tutorial/doc/bnbhr.html
That could be another approach to invoke SOAP service.
Thanks to countless developer folks on the web, the SOAP service call was finally built and tested successfully.
For https based service requests, you would need to import the site security certificate in java's keystore. If it is simple http, then no need to do anything. To make this java program work, I had to use following libraries.
j2ee-1.4.jar
commons-discovery-0.2.jar
axis-wsdl4j-1.2.1.jar
axis-jaxrpc-1.4.jar
axis.jar
axis-ant.jar
commons-logging-1.1.1.jar
Subscribe to:
Comments (Atom)
