Reading from an External HTML form.

July 29, 2008

One of our clients had an external contacts form on their website that they wanted to populate the database with. So Here’s the code. FIrst of all I created a nice JSF page then in the INIT code I called an enterprise Java bean with the save routine.

Since this is not straightforwards I though I’d share it…

In the init() phase of the Java server page.

 

HttpServletRequest request = (HttpServletRequest)
                   FacesContext.getCurrentInstance().
                   getExternalContext().getRequest();
            String sResult="";
            Map MapToSend=request.getParameterMap();
           
          
            sResult=pHJBean.saveContactMap(MapToSend);
           
            msgRESULT.setText(sResult);
            if (!sResult.equals("Save Complete")) {
                hypRETURN.setText("Click Here to go back and try again");
                hypRETURN.setUrl("javascript:history.back()");
               
            }

 

SOme notes here:-

I had a static text box called msgRESULT which displays the result of calling the “saveContactMap” routine in the bean.

Also I wanted to make sure that if there was a problem I would change a Hyperlink to return the user to the completed page so they could fix it before hitting send again…don’t worry it will make sense below.

In the bean first a simple bit of code to get the Field & Value of a key from one that has been submitted, note that the first element is of a string.

The second bit of code actually does some comparing and saves the contact to the database, but only if it’s passed the verification (since thier web designer didn’t do any!).

  /**
      * Get a field from a request
      * @param request
      * @param sField
      * @return the value as a string
      */
    private String sGetField(Map<String,String[]> request, String sField) {
        for(String key: request.keySet()) {
            if (key.equals(sField)) return request.get(key)[0];
        }
        return "";
    }     
    
     /**
     * Saves a contact detail from a web form to the database
     * @param Params the Map <String,String[]> of the request
     * @return a string result
     */
    public String saveContactMap(Map Params) {
            String sResult="Save Complete";
           
           
       
       
       
            String firstname = sGetField(Params,"firstname");
            String lastname = sGetField(Params,"lastname");
            String email = sGetField(Params,"email");
           String telephone = sGetField(Params,"bro_telephone");
            String address1=sGetField(Params,"ADDRESS 1");
            String address2=sGetField(Params,"ADDRESS 2");
            String town=sGetField(Params,"TOWN");
            String county=sGetField(Params,"COUNTY");
            String postcode=sGetField(Params,"POSTCODE");
           
           
            if (firstname.equals("")) {
                return "Please enter your first name";
            }
           
            if (lastname.equals("")) {
                return "Please enter your surname";
              
            }
            if (address1.equals("") ||
                    county.equals("") ||
                    town.equals("") ||
                    postcode.equals("")) {
                return "Please enter your full address";
            }
            if (telephone.equals("")) {
                return "Please enter your phone number";
            }
            Contacts thisContact = new PHJ.Contacts();
                thisContact.setForename(firstname);
                thisContact.setSurname(lastname);
                thisContact.setEmail(email);
                thisContact.setTelno(telephone);
                thisContact.setEnquiryorstudent("web enquiry");
                thisContact.setAddress1(address1);
                thisContact.setAddress2(address2);
                thisContact.setTown(town);
                thisContact.setCounty(county);
                thisContact.setPostcode(postcode);
                thisContact.setLastcontact(new Date());
                thisContact.setLastenquirydate(new Date());
                thisContact.setBeautytherapyqualificationsheld("");
                em.persist(thisContact);
                em.flush();
       
       
       
        return sResult;
    }

Writing out from a Java Server Faces table to a CSV….

July 25, 2008

Imagine if you will that you have a Java Server Faces table and you want to write it out to a CSV file.

1. Put The following code in your application bean.

public String OutputFromTableToCSV(
String sFilename,
TableRowGroup tableRowGroup1,
CachedRowSetDataProvider tblzonesDataProvider) {
// Create an ooutput text file
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object

try {
out = new FileOutputStream(sFilename
+".txt");

p=new PrintStream(out);
} catch (Exception e) {
return "Error, could not write to "+sFilename+".txt";
}

String sFields = "";
String sColumnTitle = "";
String sThisFieldName="";
List theseColumns = tableRowGroup1.getChildren();
// Columns
for (int i = 0; i < tableRowGroup1.getColumnCount(); ++i) {
sColumnTitle = sColumnTitle.concat(sColumnTitle);
sColumnTitle = sColumnTitle.concat(",");

// Get the SQL mapped fields
TableColumn thisComponant = (TableColumn) theseColumns.get(i);
try {
sColumnTitle = sColumnTitle.concat(
thisComponant.getHeaderText());
} catch (Exception e) {
}
}
if (!sColumnTitle.equals("")) {
sColumnTitle=sColumnTitle.substring(1); // Chop off initial ,
}
// Write it out
p.println(sColumnTitle);

RowKey[] TheseRows = tblzonesDataProvider.getAllRows();
for (int rowCount = 0; rowCount < TheseRows.length; ++rowCount) {
// Now do the rows
tblzonesDataProvider.setCursorRow(TheseRows[rowCount]);
for (int i = 0; i < tableRowGroup1.getColumnCount(); ++i) {
sFields = sFields.concat(sFields);
sFields = sFields.concat(",");
// Get the SQL mapped fields
TableColumn thisColumn = (TableColumn) theseColumns.get(i);
UIComponent thisChild=(UIComponent) thisColumn.getChildren().get(0);
// ",[#{currentRow.value['ZoneDescription']}]"
try {
sThisFieldName = thisChild.getValueExpression("text").toString();
sThisFieldName = sThisFieldName.substring(
sThisFieldName.indexOf("['") + 2);
sThisFieldName = sThisFieldName.substring(0,
sThisFieldName.indexOf("']"));

} catch (Exception e) {
}

// Add the field to the string to write out

sFields = sFields.concat(
tblzonesDataProvider.getValue(sThisFieldName).toString()
);

}
if (!sFields.equals("")) {
sFields = sFields.substring(1); // Chop off initial ,
}
p.println(sFields);

sFields="";
} // Next Row
// At this point we have to csv strings
// sfields and column title

// Now we have a comma delimited string called sresult in theory

p.close();
return "OK";
}

2. On the form with the JSF page.
a. Add the binding attribute to the tableRowGroup (in the left hand bottom pane).

Create an “Export to CSV file” button and in the event when clicked add this code:-

thefilename - the filename you want to write to
tableRowGroup1 - The table row group from your JSF page table
yourdataprovider - The data provider that feeds the JSF table

getApplicationBean1().OutputFromTableToCSV("thefilename", tableRowGroup1, yourDataProvider);

I think I’m in love….and not just with my wife

July 22, 2008

We’ve got a new member of our programming team, Uthay, I can’t even say or spell his full name, but anyway, he came along and showed me this tool called SQLyog.

Although we only had the community edition after some coaxing we managed to get the boss to shell out for the full version, enterprise edition.

This is absolutely superb, it is WELL WORTH upgrading the full enterprise version has some amazing tools that make database development MUCH easier. Especially when like us we have to modify and change databases then roll out the changes to another server. For example when we have 5 or 6 versions of our application out there and want to roll out the new application, that’s easy enough, but remembering the differences between the two versions is a bit of a pain, with this tool we can just syncronize them and it will modify the destination tables (and data if we want) to match the source.

I particularly like the Query development tool, one of the good things about good old Microsoft Access was how easy it was to build complex queries, in this software it is just as easy, particularly useful when building large scale data structures.

It’s such a shame it doesn’t support anything else apart from MYSQL. However I will be transmographying a database from a SQL server over to MYSQL JUST TO USE IT!

http://www.webyog.com/en/

There is a community version but the full version is only like £50 so it’s well worth purchasing.


Popup Windows Javaserver faces.

July 17, 2008

I wanted to build a popup window that I could use to bring up a print dialog in a web page. It’s no use using the JAVA print dialog because it would appear on the web server.

So:-

FORM WITH DATA —> CLICK PRINT —> Bring up Popup Print Window —> CLOSE WINDOW –> RETURN TO FORM

The Popup JSF page

1. Create the Popup window java server faces page. (just a normal jsf page)
2. Add a Button to the page to close it
3. Add a static text box, rename it to txtJAVASCRIPT, set the escape checkbox to off, add a binding attribute
4. Now, on the Popup I have a close button and the code in the close button simply sets the static text box’s javascript:

public String cmdClOSE_action() {
getSessionBean1().sPrintReportRequest="";
        txtJAVASCRIPT.setText("<script language='javascript'>window.close();</script>");
        txtJAVASCRIPT.setVisible(true); 
        return null;
}

The calling JSF page

1. Create your page that you want to call the popup box.
2. Add the popup code into the JSF for the page calling the popup (I put it into a page fragement that appears on every page):-

<script LANGUAGE="JavaScript">
       
            function popUp(URL) {
            day = new Date();
            id = day.getTime();
            eval("page" + id + " = window.open(URL, '" + id + "',
'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=382,height=286,left = 529,top = 307');");
            }
       
        </script>

Ofcourse you can change the settings as you wish (i.e. popup window size)

3. Making the popup appear.

a. Add a static text box, rename it to txtJAVASCRIPT, set the escape checkbox to off, add a binding attribute (this stores the javascript when i want the box to appear).

b. Add a button to the form you want the popup to appear on, in the button java put :-

  public String cmdPRINT_action() {
      // in this case i am printing a report so i set the session variable to tell the server the popup needs to be displayed
         getSessionBean1().sPrintReportRequest="rptzones";
// now set the txt of the static text box I set up on the same page, note its normally not visible or rendered
// in this case the popup is a jsf page called frmPRINTREPORTS.jsp
         txtJAVASCRIPT.setRendered(true);
         txtJAVASCRIPT.setText("<script language='javascript'>popUp('frmPRINTREPORTS.jsp');</script>" );
        txtJAVASCRIPT.setVisible(true);
       
       
        return null;
    }
 

 

4. Lastly in the form that called the popup I want to stop it from appearing so I have to kill the javascript.

    public void preprocess() {
       
        String sReportRequest=getSessionBean1().sPrintReportRequest;
        if (sReportRequest.equals("")) {
            txtJAVASCRIPT.setVisible(false);
            txtJAVASCRIPT.setText("");
           
        }
       
       
   

Note that the code has to run in the preprocess stage of the page, this simply makes sure that the javascript won’t run when it’s not wanted.

There you go!


Speeding up glassfish on Windows

July 12, 2008

Okay okay, WHY? would one want to run Glassfish on Windows????

Well sometimes we have to, I do a lot of building applications that need to run on existing servers because the customer doesn’t want to buy a new server. However given the choice I would always run Glassfish on Solaris on a Sun box (one of the small ones is fine).

So being tied down to a Windows server there are two things I do to make the server run faster that are basic but useful to know.

1. Control Panel, System, Performance, Give Priority to Background Applications

2. Make sure the Glassfish server is set up as a SERVICE (otherwise if you are remote desktoping in to start the server when you quit the session your server will stop).

3. Set the application server to PRECOMPILE JSPs, check out the Application Server tab in the Glassfish admin console.

That should put the wind up your server quite nicely.


Strange problem with cacheddataprovider.

July 10, 2008

One of the projects I’m working on is huge.

The java server faces I have are multiple tabs, tabs within tabs (oh it goes on) and I came accross a strange problem where although I had made sure the cacheddataprovider was pointing to the right place it seemed to just go to the first record.

        String sMyAccountNo=getSessionBean1().sAccountNo;
        RowKey ask=cachedRowSetDataProvider1.findFirst("Accountno",sMyAccountNo);
        cachedRowSetDataProvider1.setCursorRow(ask);

This code looks up the selected customer and is run in the init() phase of the faces class. However, click more than 3 tabs and the findFirst stops working.

The fix which I’m not too happy about because it creates more overhead is to add a:-

cachedRowSetDataProvider1.refresh();
       

Before we do the findFirst.

Thus the code is

        String sMyAccountNo=getSessionBean1().sAccountNo;
        cachedRowSetDataProvider1.refresh();
        RowKey ask=cachedRowSetDataProvider1.findFirst("Accountno",sMyAccountNo);
        cachedRowSetDataProvider1.setCursorRow(ask);

Ok just a note here before some clever person decides to have a go at me for using text as a primary key - I didn’t build the database and I’d *NEVER* do that. I’ve inherited what is in my opinion one of the worst examples of database structures I’ve ever seen, but the problem is that the organisation that uses it is running 24/7 so I can’t really make the massive changes I would if I had the chance.

Now that refresh thing REALLY bothered me so I changed the code like this:-

        RowKey ask=cachedRowSetDataProvider1.findFirst("Accountno",sMyAccountNo);
        cachedRowSetDataProvider1.setCursorRow(ask);
        if (!cachedRowSetDataProvider1.getValue("AccountNo").equals(sMyAccountNo)) {
            cachedRowSetDataProvider1.refresh();
            ask=cachedRowSetDataProvider1.findFirst("Accountno",sMyAccountNo);
            cachedRowSetDataProvider1.setCursorRow(ask);
           
        }
       

So here we see that I try the find first, if it works - cool - onwards we go, if not then we do the refresh to make sure I do have the right record. Slightly more elegant.


Formatting Currency with Java Server Faces

July 4, 2008

This is simple but VERY neat.

ok

1. Create a textbox, bind it to a numeric field
2. Create a NUMBERCONVERTER by selecting it for the field

Converter:numberConverter1

3. In your Java init code for your server faces web page…

numberConverter1.setMaxFractionDigits(2);
numberConverter1.setMinFractionDigits(2);
numberConverter1.setPattern("£#.00");

(UK)

        numberConverter1.setMaxFractionDigits(2);
        numberConverter1.setMinFractionDigits(2);
        numberConverter1.setPattern("$#.00");

(USA)

Then any boxes you assign that number converter are auto formatted as currency!


Master / Detail Pages with Netbeans 6.1 and Java Server Faces

July 4, 2008

A lot of times you will want to create a page that has a header and a table that is a child, such as a purchase order where you have a “Purchase order header” and “Purchase Order Lines”

In this case I have a master detail form here as you can see. Now. To make sure the detail form only has the data in from THAT purchase order I insert some code into the init() function of the page.

 try {
            String sSQL="SELECT ALL polines.id, polines.poid, polines.description, polines.qty, polines.price, polines.total  FROM polines WHERE poid=" + cachedRowSetDataProvider1.getValue("id");
            polinesDataProvider.getCachedRowSet().setCommand(sSQL);
            polinesDataProvider.getCachedRowSet().execute();
            polinesDataProvider.refresh();
              } catch (Exception e) {
                 
              }

(polinesDataProvider is the rows of the table, the “detail part” if you like, cachedDataProvider1 is the header)

Now here’s the tricky part. Normally I would do an ADDNEW and just do:-

 RowKey newRow = polinesDataProvider.appendRow();
        polinesDataProvider.setCursorRow(newRow);
        polinesDataProvider.setValue("poid", cachedRowSetDataProvider1.getValue("id"));
        return null;

But I discovered that when you do the “CommitChanges()” command the new row is not saved because there is a WHERE in the command query I set earlier. This is a bug (http://www.netbeans.org/issues/show_bug.cgi?id=139024), in fact the software just ignores the command (I got my MYSQL server to log the queiries and nothing happens).

So the workaround code for the New Item (new detail line) button is:-

        RowKey newRow = polinesDataProvider.appendRow();
        polinesDataProvider.setCursorRow(newRow);
        polinesDataProvider.setValue("poid", cachedRowSetDataProvider1.getValue("id"));
        polinesDataProvider.commitChanges();
        polinesDataProvider.refresh();
        return null;

Note that I set the poid field to the header’s PrimaryKey otherwise it will not look up correctly.

Strangely If you edit a record it works absolutely fine with the default just “commitingchanges” when someone clicks save.