Andrej Koelewijn

3/25/2004

JSF: a regular expression validator

Filed under: — andrejk @ 11:30 pm

Continuing my example from a few days back, this example shows how to create a JSF validator tag which checks agains a regular expression.

Step 5: custom validator tag



  1. Add validator class

    package jsftest1;

    import javax.faces.application.FacesMessage;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.validator.Validator;
    import javax.faces.validator.ValidatorException;

    public class RegExValidator implements
    Validator {

    String regex;

    public void validate(
    FacesContext _context,
    UIComponent _component,
    Object _value)
    throws ValidatorException {

    String val = (String) _value;
    if (!val.matches(regex)) {
    throw new ValidatorException(
    new FacesMessage(
    "Incorrect value, does not match regular expression: "
    + regex)); }

    }

    public String getRegex() {
    return regex;
    }

    public void setRegex(String regex) {
    this.regex = regex;
    }
    }


  2. Add validator tag class

    package jsftest1;

    import javax.faces.validator.Validator;
    import javax.faces.webapp.ValidatorTag;
    import javax.servlet.jsp.JspException;

    public class RegExValidatorTag extends
    ValidatorTag {

    private String regex;

    public RegExValidatorTag(){
    super();
    super.setValidatorId("regexValidator");
    }

    protected Validator createValidator()
    throws JspException {
    RegExValidator result = null;
    result = (RegExValidator)super.createValidator();
    result.setRegex(regex);
    return result;
    }

    public String getRegex() {
    return regex;
    }

    public void setRegex(String regex) {
    this.regex = regex;
    }
    }


  3. Add tag lib descriptor file
    <PROJECT_HOME>/web/WEB-INF/jsftest1.tld

    <taglib>
    <tlibversion>0.1</tlibversion>
    <jspversion>2.0</jspversion>
    <shortname>JSF test 1 taglib</shortname>
    <tag>
    <name>regexValidator</name>
    <tagclass>jsftest1.RegExValidatorTag</tagclass>
    <attribute>
    <name>regex</name>
    <required>true</required>
    <rtexprvalue>false</rtexprvalue>
    </attribute>
    </tag>
    </taglib>


  4. Add validator to faces-config.xml

     <validator>
    <validator-id>regexValidator</validator-id>
    <validator-class>jsftest1.RegExValidator</validator-class>
    <attribute>
    <attribute-name>regex</attribute-name>
    <attribute-class>java.lang.String</attribute-class>
    </attribute>
    </validator>


  5. Modify jsp page

     
    <h:outputLabel for="firstName">
    <h:outputText value="#{bundle.firstName}"/>
    </h:outputLabel>
    <h:inputText id="firstName" value="#{registerBean.firstName}" >
    <f:validateLength minimum="1"/>
    style="font-weight: bold;"><j:regexValidator regex="[A-Z]+"/>
    <f:validator validatorId="registerValidator"/>
    </h:inputText>
    <h:message for="firstName"/>


3/24/2004

Web Developer plugin for mozilla

Filed under: — andrejk @ 4:05 pm

The Web Developer plugin is a really usefull extension for Mozilla and Firefox. It adds a toolbar with a lot of usefull tools for web developers. I installed it because i wanted an easy way to see the HTTP headers sent by my web server. Using the web developer pluging these are easily displayed by selecting “information | view response headers”. Also usefull is the “Validate Local HTML” function, which will validate a page, even if it’s only available on your intranet. Another function i’ve been using is “Display Form Details” which will show the source code for form tags in your page. You don’t need to search in your source code anymore, it’s simple displayed with the form element on your page. Great stuff!

3/22/2004

GZIPFilter and OC4J

Filed under: — andrejk @ 11:12 am

Filters seem to work different in OC4J than in Tomcat. I’m running OC4J version 9.0.3 and Tomcat 4.1.30, same J2EE version i think, so they should behave the same, but somehow they don’t.

The problems occur when one struts action forwards to another, instead of to a jsp page. For example, I have one action checkaccount, which validates the username and password entered by a user, and if it’s incorrect the login jsp is displayed. When the values entered by the user are correct i forward (by specifying another *.do page in the struts config) to another action, which fetches some data and then displays a table of contents jsp.

I’ve specified that the GZIPfilter should applied to every *.do url, so that the output generated by an action will be compressed. When logging in correctly the following happends in tomcat:


doFilter> /prismant/checkaccount.do
GZIP supported, compressing.
writing...
writing...
writing...
writing...

But in OC4J the following happends:


doFilter> /prismant_dev/checkaccount.do
GZIP supported, compressing.
doFilter> /prismant_dev/overzicht.do
GZIP supported, compressing.
writing...
writing...
writing...
writing...
writing...
writing...

As you can see, tomcat executes the filter only once, whereas OC4J executes it twice. In the browser, the html generated by tomcat displays correctly, but when using oc4j the browser displays a lot of nonsense. Maybe because the html page is compressed twice, and the browser only decompresses it once?

Update Setting the redirect attribute of the action forward in the struts config to true seemed to solve the issues, but caused another one. Action chaining doesn’t work anymore, as some of the url parameters are no longer valid. The struts documentation recommends that action chaining should not be used, but I don’t really agree. Using action chaining i can change the pageflow of the application by just altering the struts configuration. No code changes are required. If i don’t just action chaining i have to modify to code everytime the page flow needs to change.

3/21/2004

Getting started with JSF (on oc4j)

Filed under: — andrejk @ 2:54 pm

Step 1: Hello World!



  1. Download and unzip oc4j 10.0.3 release 2. Install oc4j as
    described in
    the readme.

  2. Download and unzip JSF 1.0.

  3. Create new java project called jsf-test-1. I used eclipse. In the
    project properties i specified that i wanted the java sources under src
    and the compiled classes in web/WEB-INF/classes.

  4. Create <PROJECT_HOME>web/WEB-INF/web.xml

    <web-app>
    <display-name>JSF test 1</display-name>

    <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup> 1 </load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
    </web-app>


  5. Add the project path to
    <OC4J_HOME>/config/application.xml (replace the value for path
    with something relevant)

    <web-module id="jsf-test-1" path="../../../../../projects/jsf-test-1/web"/>


  6. Define the web application in
    <OC4J_HOME>/config/http-web-site.xml

      <web-app application="default" name="jsf-test-1" root="/jsf-test-1" development="true"/>


  7. Copy jsf libraries from <JSF_HOME>/lib into
    <PROJECT_HOME>/web/WEB-INF/lib


    1. jsf-api.jar

    2. jsf-impl.jar

    3. commons-beanutils.jar

    4. commons-collections.jar

    5. commons-digester.jar

    6. commons-logging.jar


  8. Create <PROJECT_HOME>/web/WEB-INF/faces-config.xml


  9. <faces-config>

    <application>
    <message-bundle>jsftest1.Messages</message-bundle>
    <locale-config>
    <default-locale>en</default-locale>
    </locale-config>
    </application>

    </faces-config>

  10. Create <PROJECT_HOME>/src/jsftest1/Messages.properties

    helloWorld=Hello World!


  11. Create <PROJECT_HOME>/web/index.jsp

  12. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" >
    <
    @ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

    <html>
    <body>

    <f:loadBundle basename="jsftest1.Messages" var="bundle"/>

    <f:view>

    <h:outputText value="#{bundle.helloWorld}" />

    </f:view>
    </body>
    </html>


Step 2: a registration form



  1. Add a link to a registration page in
    <PROJECT_HOME>/web/index.jsp

    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" >
    <
    @ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

    <html>
    <body>

    <f:loadBundle basename="jsftest1.Messages" var="bundle"/>

    <f:view>

    <h1><h:outputText value="#{bundle.helloWorld}" /></h1>

    Welcome: <h:outputText value="#{registerBean.firstName}"/> <h:outputText value="#{registerBean.lastName}"/>
    <br/>
    <h:form id="indexForm">
    <h:commandLink id="link1" action="register">
    <h:outputText value="#{bundle.register}"/>
    </h:commandLink>
    </h:form>
    </f:view>
    </body>
    </html>


  2. Modify <PROJECT_HOME>/web/WEB-INF/faces-config.xml
    <faces-config>

    <application>
    <message-bundle>jsftest1.Messages</message-bundle>
    <locale-config>
    <default-locale>en</default-locale>
    </locale-config>
    </application>

    <managed-bean>
    <managed-bean-name>registerBean</managed-bean-name>
    <managed-bean-class>jsftest1.RegisterBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    </managed-bean>

    <navigation-rule>
    <from-view-id>/register.jsp</from-view-id>
    <navigation-case>
    <from-outcome>success</from-outcome>
    <to-view-id>/index.jsp</to-view-id>
    </navigation-case>
    <navigation-case>
    <from-outcome>failure</from-outcome>
    <to-view-id>/register.jsp</to-view-id>
    </navigation-case>
    </navigation-rule>

    <navigation-rule>
    <from-view-id>/index.jsp</from-view-id>
    <navigation-case>
    <from-outcome>register</from-outcome>
    <to-view-id>/register.jsp</to-view-id>
    </navigation-case>
    </navigation-rule>

    </faces-config>


  3. Modify <PROJECT_HOME>/src/jsftest1/Messages.properties

    helloWorld=Hello World!
    register=Register
    firstName=First Name
    lastName=Last Name style="font-family: sans-serif;">


  4. Create
    <PROJECT_HOME>/web/register.jsp

    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" >
    <
    @ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

    <html>
    <body>
    <f:loadBundle basename="jsftest1.Messages" var="bundle"/>

    <f:view>

    <h1><h:outputText value="#{bundle.register}" /></h1>
    <h:form id="registrationForm">
    <h:panelGrid columns="2">
    <h:outputLabel for="firstName">
    <h:outputText value="#{bundle.firstName}"/>
    </h:outputLabel>
    <h:inputText id="firstName" value="#{registerBean.firstName}" />

    <h:outputLabel for="lastName">
    <h:outputText value="#{bundle.lastName}"/>
    </h:outputLabel>
    <h:inputText id="lastName" value="#{registerBean.lastName}" />

    <h:commandButton action="#{registerBean.registerAction}" value="#{bundle.register}"/>
    </h:panelGrid>
    </h:form>
    </f:view>
    </body>
    </html>

    Note: due to a bug in JSF, we need to add the panelGrid tag, otherwise
    the
    outputLabel tag does not work.


  5. Create class RegisterBean:

    package jsftest1;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    /**
    * @author akoelewijn
    */
    public class RegisterBean {
    protected static final Log log = LogFactory.getLog(RegisterBean.class);
    String firstName = null;
    String lastName = null;
    /**
    * @return Returns the firstName.
    */
    public String getFirstName() {
    return firstName;
    }
    /**
    * @param firstName
    * The firstName to set.
    */
    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }
    /**
    * @return Returns the lastName.
    */
    public String getLastName() {
    return lastName;
    }
    /**
    * @param lastName
    * The lastName to set.
    */
    public void setLastName(String lastName) {
    this.lastName = lastName;
    }
    public String registerAction() {
    log.info("registerAction");
    if (firstName != null && !firstName.equals("") && lastName != null
    && !lastName.equals("") ) {
    return "success";
    } else {
    return "failure";
    }
    }
    }



Step 3: simple validation



  1. JSF has some predefined tags to do simple validations. Modify
    register.jsp
     <h:form id="registrationForm">

    <h:panelGrid columns="3">
    <h:outputLabel for="firstName">
    <h:outputText value="#{bundle.firstName}"/>
    </h:outputLabel>
    <h:inputText id="firstName" value="#{registerBean.firstName}" >
    <f:validateLength minimum="1"/>
    </h:inputText>
    <h:message for="firstName"/>

    <h:outputLabel for="lastName">
    <h:outputText value="#{bundle.lastName}"/>
    </h:outputLabel>
    <h:inputText id="lastName" value="#{registerBean.lastName}" >
    <f:validateLength minimum="1"/>
    </h:inputText>
    <h:message for="lastName"/>

    <h:commandButton action="#{registerBean.registerAction}" value="#{bundle.register}"/>

    </h:panelGrid>
    </h:form>



Step 4:  custom validation



  1. Modify  <PROJECT_HOME>/web/WEB-INF/faces-config.xml

    ... 
    </application>

    <validator>
    <validator-id>registerValidator</validator-id>
    <validator-class>jsftest1.RegisterValidator</validator-class>
    </validator>

    <managed-bean>
    ...


  2. Add class RegisterValidation

    package jsftest1;
    import javax.faces.application.FacesMessage;
    import javax.faces.component.UIComponent;
    import javax.faces.context.FacesContext;
    import javax.faces.validator.Validator;
    import javax.faces.validator.ValidatorException;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    /**
    * @author akoelewijn
    */
    public class RegisterValidator implements Validator {
    protected static final Log log = LogFactory.getLog(RegisterValidator.class);
    public void validate(FacesContext _context, UIComponent _component,
    Object _value) throws ValidatorException {
    log.info("validate: " + _component.getId() + ", " + _value);
    if (_component.getId().equals("firstName")) {
    if (!_value.equals("andrej")) {
    throw new ValidatorException(new FacesMessage(
    "Incorrect value for first name"));
    }
    } else if (_component.getId().equals("lastName")) {
    if (!_value.equals("koelewijn")) {
    throw new ValidatorException(new FacesMessage(
    "Incorrect value for last name"));
    }
    }
    }
    }


  3. Modify <PROJECT_HOME>/web/register.jsp

    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" >
    <
    @ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>

    <html>
    <body>
    <f:loadBundle basename="jsftest1.Messages" var="bundle"/>

    <f:view>

    <h1><h:outputText value="#{bundle.register}" /></h1>
    <h:form id="registrationForm">

    <h:panelGrid columns="3">
    <h:outputLabel for="firstName">
    <h:outputText value="#{bundle.firstName}"/>
    </h:outputLabel>
    <h:inputText id="firstName" value="#{registerBean.firstName}" >
    <f:validateLength minimum="1"/>
    <f:validator validatorId="registerValidator"/>
    </h:inputText>
    <h:message for="firstName"/>

    <h:outputLabel for="lastName">
    <h:outputText value="#{bundle.lastName}"/>
    </h:outputLabel>
    <h:inputText id="lastName" value="#{registerBean.lastName}" >
    <f:validateLength minimum="1"/>
    <f:validator validatorId="registerValidator"/>
    </h:inputText>
    <h:message for="lastName"/>

    <h:commandButton action="#{registerBean.registerAction}" value="#{bundle.register}"/>

    </h:panelGrid>
    </h:form>
    </f:view>
    </body>
    </html>






3/20/2004

OC4J is officially J2EE 1.4 compatible

Filed under: — andrejk @ 1:11 pm

Oracle reports that OC4J’s preview release has passed the J2EE 1.4 compatibility test suite. J2EE version 1.4 has some nice new features that i’m looking forward to using: 1) tag files, and 2) a new expression language.

Job opening for a senior J2EE consultant

Filed under: — andrejk @ 12:50 pm

We’re looking for a senior J2EE Consultant in the Netherlands. If you’re interested, more information can be found on the IT-eye website.

Oracle RDBMS 10G available for Windows

Filed under: — andrejk @ 12:16 pm

Mark Rittman reports that Oracle has released version 10G of it’s database for Windows.

I am currently finishing a project using fairly new Oracle products, RDBMS 9.2 and 9iAS relesae (OC4J 9.0.3). Wonder when we’ll do our first projects for customers with this new version.

3/19/2004

Some links on JSF

Filed under: — andrejk @ 1:57 pm


Some usefull links on Java Server Faces:
Facing forward with JSF,
Java Server Faces – part 1,
Java Server Faces – part 2,
ADF UIX roadmap,

Using Java Server Faces
,
Java server faces FAQ,
Using JSF,
Introducing JavaServer Faces.

Generate css multicolumn layouts

Filed under: — andrejk @ 9:43 am

Found this usefull multicolumn layout generator through a list apart. Getting it right can be a pain, especially in netscape 4, which is why i usually don’t bother.

3/16/2004

Sun releases Java Studio Creator beta

Filed under: — andrejk @ 12:47 pm

According to the Inquirer, sun has just released a beta version of it’s Java Studio Creator. I can’t find a download link at sun’s site though.

It’ll be interesting to see how it stacks up against jdeveloper and ADF.

3/11/2004

Using ant to deploy to OC4J

Filed under: — andrejk @ 12:13 pm

I found the following usefull information in the OTN forums. You can use this example to deploy a war archive to a remote OC4J server in an Ant build file. I noticed that oc4j_remote_deploy.jar is not part of the jdeveloper 9.0.3 installation i have here, and it’s also not part of the standalone oc4j installation i’m using.


<java jar="${jdev.dir}/jdev/lib/oc4j_remote_deploy.jar" fork="yes">
<jvmarg value="-Djava.protocol.handler.pkgs=HTTPClient" />
<arg value="http://remote_server:1810/Oc4jDcmServletAPI/" />
<arg value="username" />
<arg value="password" />
<arg value="redeploy" />
<arg value="E:ora9ias" />
<arg value="${build.dir}/${name}.ear" />
<arg value="${name}" />
<arg value="OC4J_PORTAL" />
</java>

3/9/2004

New JCP seems to be an improvement

Filed under: — andrejk @ 6:56 pm

The serverside reports on the new version of the Java Community Process, version 2.6. It seems to be an improvement over version 2.5. Currently, for most JSR’s which haven’t released a community draft yet, you have no idea what’s going on. This will be improved through more transparancy and public early access drafts.

Powered by WordPress