Sunday, 15 May 2011

Using Java "URL" object to read text and binary data

Just a little example of "URL" object.

To read text data from remote page (for example), use the following piece of code

URL pollingUrl = new URL("http:\\www.google.com");
BufferedReader in
= new BufferedReader(new InputStreamReader( pollingUrl.openStream()));
String inputLine
="";
while (true)
{
inputLine
= in.readLine();
if (inputLine == null)
break;//end of HTML page
}// end while
in.close();
Just open a stream to specific url and use Buffered Reader to read the response, line by line. Very simple. However,

remember that response text is transfered in the html format. So if you need specific information you need to parse it.

Now if you want to download the file to your disk. The idea is the same, just instead of Buffered Reader we use DataInputStream object

FileOutputStream fout = new FileOutputStream("c:\myFile",true);
URL fileURL
= new URL("http://host/myFile.dat");
DataInputStream dis
= new DataInputStream(fileURL.openStream());
int c = dis.read();
while (c != -1 )
{
c
= dis.read(); fout.write(c);
} fout.close();dis.close();
We read bytes from InputStream and in the same time writing it to the disk

Don't forget to close your streams!!

Using servlet to download the file from Oracle Instance

As part of the project I am working on , I had to find a way to download the file from OA. I will demostrate here a way to do it on R12 instance

First of all we need to write a servlet.

Here is the code:

 

import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;

public class DownloadFile extends HttpServlet
{

//I assumed that OA is running on Unix under Korn shell and .profile file used to source the instance


private String doCommand(String cmd) throws IOException, InterruptedException
{
int exitCode = 0;
int c;
BufferedReader b;
String [] params
= new String[]{"/bin/ksh", "-c", ". profile 1> /dev/null;set -e;" + cmd};
Process subProc
= Runtime.getRuntime().exec(params);
StringBuffer sb
= new StringBuffer();

b
= new BufferedReader(new InputStreamReader(subProc.getInputStream()));

c
= b.read();

while (c != -1)
{
sb.append((
char)c);
c
= b.read();
}

b.close();

exitCode
= subProc.waitFor();
if (exitCode != 0)
{
sb
= new StringBuffer();
b
= new BufferedReader(new InputStreamReader(subProc.getErrorStream()));
c
= b.read();
while (c != -1)
{
sb.append((
char)c);
c
= b.read();
}
//end while
System.out.println("Output from 'doCommand' "+ sb.toString());
return sb.toString();
}
else
{

System.out.println(
"Output from 'doCommand' "+ sb.toString());
return sb.toString();
}
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{ PrintWriter requestOutput
= null;
String resolvedFile
=null;
try
{
String file
= request.getParameter("fileName");
resolvedFile
= doCommand("echo "+file).trim();
File documentFile
= new File(resolvedFile);
FileInputStream fin
= new FileInputStream(documentFile);
if (resolvedFile.indexOf('/')!=-1)
resolvedFile
= resolvedFile.substring(resolvedFile.lastIndexOf('/')+1) ;
response.setHeader(
"Content-disposition", "attachment; filename=" + resolvedFile);
response.setContentType(
"application/octet-stream");
response.setContentLength((
int)documentFile.length());
requestOutput
= response.getWriter();
int c;
c
= fin.read();
while (c != -1) {
requestOutput.write(c);
c
= fin.read();


}
fin.close();
}
catch (Exception e)
{
if (requestOutput == null)
{
response.setContentType(
"text/html");
requestOutput
= response.getWriter();
}
requestOutput.write(
"Error trying to get file : ");
requestOutput.write(e.toString());
requestOutput.write(
"");
}
requestOutput.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
doGet(request, response);
}
}


Compile the file. Put it under $OA_JAVA on Application Node

Now we need to add servlet definition to OA web service configuration file. It is usually located under  $ORA_CONFIG_HOME/10.1.3/j2ee/oacore/application-deployments/oacore/html/orion-web.xml

Add the following to the servlet section


<servlet>
<servlet-name>DownloadFile</servlet-name>
<display-name>DownloadFile</display-name>
<servlet-class>DownloadFile</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DownloadFile</servlet-name>
<url-pattern>/DownloadFile</url-pattern>
</servlet-mapping>

Save the file and restart OC4J service.

Now you can download any file located on the Application node simply by running http://<instance url>:<instance port>/OA_HTML/DownloadFile?fileName=/path_to_your_file. You can also use instance variables inside  the path, like http://<instance url>:<instance port>/OA_HTML/DownloadFile?fileName=$APPL_TOP/admin/myFile.txt