Uploading Images Using JDeveloper 10g and BC4J

Dulcian, Inc.

August 2, 2005

 

Overview

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.”

 

I. Creating the REQUESTIMAGETWO Table

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.

 

Creating View Links

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

 

II. Binding the Image Input to the JSP Pages

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:&nbsp <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.

 

III. Linking Records

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();

         }

 }

 

IV. Rendering the Uploaded Images

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>

 

 

V. Available Metadata

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