Uploading Images Using JDeveloper
10g and
BC4J
Dulcian, Inc.
This document will discuss the procedure for uploading images
to a database using JDeveloper10g and
BC4J in the context of creating child records to hold these images. The development described below was done
using JDeveloper10g Version
10.1.2.0.0 (Build 1811).
Dulcian has a database containing a table named REQUEST and another table named REQUESTIMAGETWO which is defined as a child table of REQUEST.
The Primary Key of REQUEST is REQUEST_OID and this key is kept as a foreign key in REQUESTIMAGETWO along with the Primary key of REQUESTIMAGETWO which is REQUESTIMAGETWO_OID.
This document will briefly discuss the procedure used to set
up this parent-child relationship in JDeveloper10g. It includes a description of how to
upload images associated with “Requests” to the database and later display them
in conjunction with “Requests.”
Assuming that the REQUEST table already exists, the REQUESTIMAGETWO table must be created using a particular data type or domain to store the images as follows:
CREATE TABLE
REQUESTIMAGETWO
(
REQUESTIMAGETWO_OID
NUMBER,
REQUEST_OID
NUMBER,
THEFILETWO
ORDSYS.ORDIMAGE
)
The key values shown here are of type NUMBER but the column to store the image must be of type ORDSYS.ORDIMAGE. Using SQL Navigator, as shown in Figure 1, it is possible to confirm that the table has the desired domain types.

Figure 1:
REQUESTIMAGETWO Table information in SQL Navigator
Once the table has been created in the database, it is necessary to create an entity and view in JDeveloper to access this table. Once the entities and views for this table have been created in JDeveloper, create an association and a view link between these views as described in the next section.
Assuming that the RequestView1 view and the RequestImageTwoView view have been created for the underlying Request and RequestViewTwo entities, the views must be linked using the View Link Editor shown in Figure 2.

Figure 2: JDeveloper
View Link Editor
Create a view link by right clicking on the model node and selecting new. Once this is accomplished RequestView1 view and RequestImageTwoView view have been linked. This can be verified by expanding the AppModule node and examining the Data Model list in the Navigator shown in Figure 3.

Figure 3: JDeveloper
AppModule
The next step is to bind the image input in the JSP pages to the view.
The FSC 1867
specification for HTML provides client browser support for file uploads into
HTML forms. The client-side browsing is done automatically by the client’s
browser.
In JDeveloper the
view attribute must be bound as a File Input Field as shown in Figure 4. Drag this attribute onto the JSP
page. Note that the Data Control
Palette shows a selection from RequestImageTwoView2 which is linked to
its parent view RequestView1.

Figure 4: Data Control
Palette
Completing the drag
operation will produce the following binding (shown in red) on the JSP page.
<tr>
<td
colspan="8">
<table width="70%"
align="right">
<tr>
<td class="freetxt"> Choose image:  <html:fileproperty="Thefiletwo"
/>
Maximum 1MB image
</td>
</tr>
</table>
</td>
</tr>
This will also
display the field and button shown in Figure 5, allowing users to browse their
own local drives for the image file to upload.

Figure 5: Image selection
UI
This JSP page sends
a new request to the database using the RequestView1 in BC4J. Many of the data attributes of this view
are also bound to the same JSP page but the file binding is to the child RequestImageViewTwo2 linked to this
view.
In order to link the two records in the database, create a DataAction and an application module function. The struts-config.xml diagram in Figure 6 shows the DataActions associated with the AddRequest.jsp page.

Figure 6:
struts-config.xml diagram
The DataAction, startToCreateMgrRequest, has an associated AppModule function that contains the code for linking the two records. The parent row is created and inserted; then the child row is created, the parent’s foreign key is set in the child, and finally, the child row is inserted as shown in the code below.
public void
startToCreateMgrRequest()
{
try
{
// Log in.
this.getTransaction().executeCommand("begin
security.connecttosystem('"
+
this.getUserID() + "','" + this.getPassword() + "');
end;");
this.getRequestView1().setRangeSize(1);
this.getRequestView1().setIterMode(ViewObject.ITER_MODE_LAST_PAGE_PARTIAL);
// Create the parent 'request' row.
RequestViewRowImpl
new_RequestViewRowImpl =
(RequestViewRowImpl) getRequestView1().createRow();
// Insert the new row and make it the current one.
this.getRequestView1().insertRow(new_RequestViewRowImpl);
this.getRequestView1().setCurrentRow(new_RequestViewRowImpl);
// Create the child 'requestImage' row.
RequestImageTwoViewRowImpl new_RequestImageTwoViewRowImpl
=
(RequestImageTwoViewRowImpl)
this.getRequestImageTwoView2().createRow();
// Set the PK of the parent to the FK of this child
row.
new_RequestImageTwoViewRowImpl.setRequestOid(new_RequestViewRowImpl.getRequestOid());
// Insert the new row and make it the current one.
this.getRequestImageTwoView2().insertRow(new_RequestImageTwoViewRowImpl);
this.getRequestImageTwoView2().setCurrentRow(new_RequestImageTwoViewRowImpl);
}
catch (Exception e)
{
log.info("In startToCreateMgrRequest(), exception
caught.");
e.printStackTrace();
}
}
The subsequent DataAction “savemgrrequest” has an associated AppModule function containing the code for committing the transaction to the database as shown in the code below.
public void
commitNewMgrReq()
{
try
{
// Log in.
this.getTransaction().executeCommand("begin security.connecttosystem('" +
this.getUserID() + "','" +
this.getPassword() + "'); end;");
this.getRequestView1().setRangeSize(1);
this.getRequestView1().setIterMode(ViewObject.ITER_MODE_LAST_PAGE_PARTIAL);
this.getTransaction().commit();
}
catch(Exception e)
{
e.printStackTrace();
}
}
Once the images have been uploaded to the database in a manner that also established the parent-child relationship between a request and a request images, they can be rendered.
In this example, the MgrRequests.jsp page used the RequestView1 view to display many requests on a single page. When the images link associated with the subject request is selected, the user navigates to a JSP page displaying all of the image IDs for that request. This requires moving the iterator for the RequestView1 view to the correct row to access the images for this request.
Figure 7 shows another portion of the struts-config.xml diagram that includes the control flow for displaying images:

Figure 7: Control
flow for image display
The DataAction popImageList has an associated AppModule function that moves the RequestView1 iterator to the correct request as shown in the code below. Otherwise the images for the request that the iterator happened to be “sitting on” would be visible.
public void
popImagesList(String requestID)
{
try
{
if(requestID != null &&
!requestID.equalsIgnoreCase("null"))
{
// Get a key object.
Number rn = new Number(Long.parseLong(requestID));
Key k = new Key(new Object[]{rn, null});
// Find the row.
Row[] rowsFound = this.getRequestView1().findByKey(k,
1);
// We better have found one.
if(rowsFound.length == 0 )
{
log.info("In
populateImagesList(), No row found.");
}
else
{
// Get the row.
Row foundRow = rowsFound[0];
// Now set the current row.
this.getRequestView1().setCurrentRow(foundRow);
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
After displaying the list of image IDs on a separate JSP page for this request (not shown for brevity the uploaded image is displayed in another small JSP page.
In the following code, note that the the adf:render tag (shown in red) is needed to render the image. This is the binding for the image on the JSP page.
<html>
<head>
</head>
<body>
<html:errors
/>
<html:form
action="viewImages">
<table border="1" width="100%" cellpadding="1" cellspacing="0"
class="tablebg"
align="center">
<tr>
<td align="center">
<adf:render
model="bindings.Thefiletwo" />
</td>
</tr>
</br>
<tr>
<td align="center">
<input type="submit" value="Done"
align="middle"/>
</td>
</tr>
</table>
</html:form>
</body>
</html>
Unfortunately the method of uploading images described in this document does not permit uploading any metadata about the original file (such as the file name or original create date) on the client’s drive. Looking at the database using SQL Navigator as shown in Figure 8 demonstrates that all the metadata is lost. Only the raw file came through. It would be nice to store the original file names in the database but it is not possible with this method. What is stored is only a raw blob file.

Figure 8: SQL
Navigator information about REQUESTIMAGETWO
Table