Developing Great Software

Thursday, April 28, 2011

The NetBeans 7 Wicket Plugin

Geertjan Wielenga has released an updated version of the Wicket Plugin for NetBeans 7.  For us Wicket fanatics this is indeed great news. The plugin adds some really nice enhancements and productivity features to the NetBeans platform and, when taken in total, in my opinion makes NetBeans the undisputed best platform for Wicket development.

If you haven’t done so already I urge you to download this plugin from the NetBeans plugin portal and install it into NetBeans 7. For those of you not familiar with installing plugins from the NetBeans portal, here are the steps you should follow:

Installing The Wicket Plugin

1. Go to http://plugins.netbeans.org/plugin/3586/wicket-1-4-support and click the Download button to download the zip file to your computer. Once it is downloaded extract all the files. On Windows you can extract the files by right clicking the file with your mouse and selecting Extract All.

2. Start up NetBeans if it isn’t already and select Tools | Plugins from the main menu. This will open the Plugin window.

3. Select the Downloaded tab and then select the Add Plugins button.

4. Navigate to the folder where you the extracted files reside, select all 3 files and then select the Open button.

2011-04-28 19h44_53

5. Select the Install button and NetBeans will install the plugin modules after which you will be prompted to restart NetBeans. Please, restart NetBeans.

Create A Wicket Project

Lets explore some of the productivity enhancing features that the Wicket plugin provides. We’ll start first by creating a new Wicket project.

1. From the main menu select File | New Project. Then, select Java Web from the Categories panel and select Web Application from the Projects panel and then select Next.

2. Enter any name you like for the Project Name and select Next.

3. Select Apache Tomcat 7.0.11 for the Server (if you prefer, you can also select GlassFish 3.1) and Java EE 6 Web for the Java EE Version and select Next.

4. In the Frameworks step you can see that there is an option to select Wicket as the framework you want to use in your application. This is the 1st and most obvious contribution that the Wicket plugin provides, easy integration of Wicket into a NetBeans Java Web project. When you select Wicket the Plugin provides you with numerous configuration options such as the name of the Wicket filter and the URL pattern, for instance. For our run through we are going to accept all the defaults.

2011-04-28 20h01_37

5. Select Wicket and then select Finish. NetBeans will now generate a starter Wicket application.

Fully expand the newly created project in the Projects panel.

2011-04-28 20h13_02

As you can see from the above, the Wicket plugin created a complete Wicket starter project, libraries and all. It also created numerous Wicket components: BasePage, FooterPanel, HeaderPanel and HomePage as well as the required Application.java class. The plugin also configured web.xml according to the configuration parameters that we chose in the Frameworks step.

Run The New Wicket Application

Now, from the main menu select Run | Run Main Project to run the newly created application. As you can see from the rendered page in the browser, the starter project, though trivial, is rather nice - it has a header section, a middle section for content and a footer section, too.

 

2011-04-28 20h21_38

You will, of course, want to modify the starter project to match your own application’s requirement but because the starter project uses Wicket Markup Inheritance you will be able to do this rather easily.

The Starter Project

Lets explore the components that the plugin generated for us.

Open the BasePage component by double clicking on either BasePage.html or BasePage.java. When you click on either, both files will open. This behavior is contributed by the Wicket plugin and I find it extremely convenient.

Now, lets look at BasePage’s markup and java implementation.

<!DOCTYPE html> 
<html xmlns:wicket="http://wicket.apache.org"> 
    <head> 
        <meta charset="UTF-8"> 
        <meta name="description" content="Put your description here!" /> 
    <wicket:head> 
        <wicket:link> 
            <link rel="stylesheet" type="text/css" href="style.css"/> 
        </wicket:link> 
    </wicket:head> 
</head> 
<body> 
    <header wicket:id="headerpanel" />
    <section class="content_container"> 
        <wicket:child/> 
    </section> 
    <footer wicket:id="footerpanel" /> 
</body> 
</html>
package com.myapp.wicket;           

import org.apache.wicket.markup.html.WebPage;

/** 
 *
 * @author Jeff
 * @version 
 */

public abstract class BasePage extends WebPage {

    public BasePage() { 
        super(); 
        add(new HeaderPanel("headerpanel", "Welcome To Wicket")); 
        add(new FooterPanel("footerpanel", "Powered by Wicket and the NetBeans Wicket Plugin"));
    } 

}

BasePage.html’s header contributes style.css, which is a packaged resource that resides in the same package as the BasePage component. By using wicket:head and wicket:link tags, Wicket will be able to resolve the reference to style.css and include it in the rendered page.

In the body of the page there are place holders for the header and footer panels. There’s also a wicket:child tag declared which will allow any page that inherits from BasePage to contribute its content to the page. This is what Wicket calls ‘Markup Inheritance’. I’ll show you how this is used when we look at the HomePage component later in the article.

BasePage.java’s implementation is what you would expect to find considering the markup we just explored. BasePage derives from WebPage and after calling into its super class BasePage’s contrcutor adds the HeaderPanel and FooterPanel components to the page. The constructors for both of these components allows you to add the text that will be displayed for each as their second parameters.

Now, lets look at HomePage’s markup and java implementation.

<!DOCTYPE html> 
<html xmlns:wicket="http://wicket.apache.org"> 
    <head> 
        <meta charset="UTF-8"> 
    <wicket:head> 
        <title>Wicket Example</title> 
    </wicket:head> 
</head> 
<body> 
    <wicket:extend> 
       <h1 wicket:id="message">This gets replaced</h1>
    </wicket:extend> 
</body> 
</html>
package com.myapp.wicket;           

import org.apache.wicket.markup.html.basic.Label;

public class HomePage extends BasePage {

    public HomePage() {
        add(new Label("message", "Hello, World!"));
    }

}

Again, there are no surprises here but one item needs to be elaborated on. HomePage derives from BasePage and as I had mentioned, HomePage uses Markup Inheritance to contribute its markup to the page. It will attach its markup to the h1 tag which is sandwiched between the opening and closing wicket:extend tags. This is how Wicket Markup Inheritance works and it is a very powerful technique to use when you want to compose pages that have the same layout and appearance.

I’ll let you explore HeaderPanel and FooterPanel on your own though these also will be what you would expect as both implementations are derived from Panel.

Now lets explore some of the other productivity enhancements that the Wicket plugin provides.

Creating A New Page And A New Panel

To create a new Page, right click the package which currently contains our project’s components and select New | Wicket Page. Enter any name for the Page and select Finish. Two files, one html and one Java, will open in the browser.

Creating a new Panel is much like creating a new Page. Right click the package which currently contains our project’s components and select New | Wicket Panel. Enter any name for the Panel and select Finish. Two files, one html and one Java, will open in the browser.

Exploring Components With Navigator

The plugin adds what I call ‘Wicket Sense’ (my term for a lack of a better one) to the NetBeans Navigator. To see this in action, in the editor select the BasePage.html file and if it isn’t already, open the Navigator and select Wicket Tags from its list of views.

As you can see, the Navigator displays all the elements that include wicket:id attributes in their tags. Now switch editor views to BasePage.java and again, notice how the Navigator has identified all the Wicket components in the Java code.

Your will really appreciate Navigator’s Wicket Sense when you are dealing with large Java and markup files.

Jump To Implementation

Another nice feature that the plugin adds is the ability to jump to the Java implementation from within the markup file. In HomePage.html, hold down the control key and hover the mouse over the ‘message’ wicket:id value. An underline will appear and if you now click on ‘message’ the editor will switch views to the Java implementation, opening the file if it isn’t currently open in the editor.

The plugin doesn’t currently support jumping to the markup page from the implementation file but maybe a future release of the plugin will provide this feature.

Much Thanks And Appreciation

Geertjan deserves our thanks and he earns our appreciation for all the effort he has put into this plugin. In my opinion, the plugin empowers NetBeans to provide a level of support for Wicket development that no other IDE can currently match.

Geertjan, great job and thank you!

Well, that’s it for now but remember, busy hands are happy hands, so get going and explore this fabulous plugin and all its great features. Happy coding!

Wicket, Web Services, NetBeans And GlassFish

A reader recently emailed me and wanted to know about implementing a Wicket application within a Web Service environment.

I have not come across any reference where Wicket has been implemented
within a web service environment. None of the books I have read on
Wicket have addressed this area to my knowledge. I am wondering if you
have any insight as to how this would work.

The reader is expressing a very common misconception that a lot of developers have and that misconception is that you somehow have to integrate your Web Services into your Web application. Part of my response to the reader was:

“How you expose your web services has nothing to do with Wicket meaning you don't integrate your web services with wicket.”

Additionally, I went on to say:

“All you need is to create web services on glassfish (it has built in support for web services and Netbeans tooling makes this just so simple). If a client, whether your Wicket application or a paid subscriber for instance, needs to consume your web services it will consume the wsdl files produced when you created the web services.”

What I was trying to express to the reader is that Wicket is just a Web framework and not a Web Services provider. Wicket writes HTML to the browser and that’s about it. Wicket Web applications, however, can consume Web services, either those on the same server the Web application is running on or located on different servers. But Wicket itself doesn’t provide any means to consuming Web services - for that you use Java API for XML Web Services (JAX-WS).

I promised the reader that if I had the time I would write an article demonstrating how this is done which is the purpose of this article. So lets get started.

The remainder of this article assumes you have installed NetBeans 7 as well as the NetBeans Wicket plugin. If you haven’t, please do so now.

NetBeans, GlassFish v3.1 and JAX-WS

NetBeans 7 comes bundled with GlassFish v3.1 and GlassFish comes with Metro 2.1 as its SOAP Web Services provider. Metro 2.1 implements the JAX-WS specification. The synergy between Web Services, NetBeans and GlassFish is provided by the tooling built into NetBeans, which makes authoring and deploying your Web Services on GlassFish very easy, as we shall see later in this article.

When you create a Web Service you first have to decide how you want to package it (what type of application you will use to host your Web Service). You have 2 options:

1. JavaEE EJB Module project – this option should be used if your Web Services require access to EE containers. Web Services in this context are generated as Stateless SessionBeans. If your Web Service needs access to your database, for instance, you can achieve this using the @PersistenceContext annotation within your Web Service which will allow you to access your database via JPA.

2. Package in Web container – this option should be used if your Web Service doesn’t require access to other EE containers.

In this article I won’t actually cover accessing a database because I want to keep it simple but I will use a JavaEE EJB Module project and you can, if you chose, explore this later on your own by creating a Web Service method to access your own database.

Create A Web Service Project

1. If you haven’t already, fire up NetBeans and select File | New Project which will open the New Project window.

2. Select Java EE from the Categories panel and select EJB Module from the Projects panel and select Next.

3. Enter any valid project name you like in the Project Name text box. I am naming mine ‘EJBWebServicesAndWicketTutorial’. Select Next.

4. Select GlassFish Server 3.1 from the Server drop down list and make sure that Java EE 6 is selected in the Java EE Version drop down list. Select Finish to generate the project.

Create A Web Service

1. Right click the project node for the EJB project in the Projects window and select New | Web Service. This will open the New Web Service window.

2. Enter CalculatorWebService for the Web Service Name. Make sure that the Create Web Service from Scratch option is selected. Note that because our project is an EJB the Implement Web Service as Stateless Session Bean option is automatically selected for us and cannot be changed. Enter WebServices as the Package name and select Finish. NetBeans will generate your Web Service Java class in the WebServices package.

3. I will use a simple method for our Web Service that returns the sum of two integers. Replace the content of CalculatorWebService.java with the following:

package WebServices;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.ejb.Stateless;

/**
 *
 * @author Jeff
 */
@WebService(serviceName = "CalculatorWebService")
@Stateless()
public class CalculatorWebService {

    /**
     * Web service operation
     * @param i int
     * @param j int
     * @return  the sum of i + j as int
     */
    @WebMethod(operationName = "add")
    public int add(@WebParam(name = "i") final int i, 
    @WebParam(name = "j") final int j) {
        return i + j;
    }
}

From the above code you can see that the CalculatorWebService class is decorated with both @WebService and @Stateless attributes which is what you would expect. Also note that the add method is decorated with the @WebMethod attribute and that each of its parameters, i and j, are decorated with the @WebParam attribute.

I didn’t hand-code this though I could have. NetBeans can generate a Web method with all the correct attributes for you. If you select Design View and click the Add Operation button, NetBeans will present you with its Add Operation window that allows you to add a new Web Service method with all the proper attributes. I’ll leave this as an exercise that you can explore later on your own.

Testing The CalculatorWebService add Method

NetBeans tooling makes testing Web Services a snap so lets do that now to insure that our add service works as expected:

1. In the Project panel right click the Web Services node (not the WebServices package) and select Test Web Service which will open your browser and display the following

2011-04-28 10h23_51

2. Click the WSDL File link and save the URL somewhere (like Windows NotePad, for instance) and then page back to the above. We will use the URL in our Web Services client application, which we will build later on in the article.

3. Enter 4 in the first input field and enter 5 in the second input field and then click add. Your browser will then display the following

2011-04-28 10h30_27

As you can see from the above, the method correctly calculated and returned the sum of our two numbers. If you scroll down the browser page you can see the packaging for both the SOAP request and the SOAP response. Repeat this a few time with different sets of numbers.

We now have a working Web Service that can be consumed by any client that can consume a Web Service. Note how the Web Service we just built has no connection at all with Wicket – our project doesn’t even include the Wicket framework. Remember, Web Services provide a service whereas Wicket applications render HTML to the browser.

Now we know that our method works so lets create a Wicket application that will consume the Web Service. I’ll keep this simple and I assume that you have already installed the latest release of the Wicket plugin for NetBeans 7.

Create a Wicket Application

1. In NetBeans select File | New Project and select Java Web from the Categories panel and Web Application from the Projects panel. Enter any name you like for the Project Name, select Set As Main Project and select Next.

2. For Server select GlassFish Server 3.1 and for Java EE Version select Java EE 6 Web and select Next.

3. For Frameworks select Wicket and select Finish. NetBeans along with the Wicket plugin will generate a Wicket starter application project that includes the Wicket libraries. Also generated by the Wicket plugin are Wicket components for HomePage, BasePage, HeaderPanel, FooterPanel as well as the required Application.java and configuration files.

Now that we have a Wicket application we will use NetBeans to easily configure it to consume the Web Service we created previously.

Consuming Our Web Service

1. In the Projects panel right click the Web applications project node and select New | Web Service Client. This will open the New Web Service Client window.

2. Select WSDL URL and enter the URL that you saved previously when you tested the Web Service.

3. Enter a package name and make sure that JAX-WS Style is the selected option for Client Style. Select Finish. NetBeans will generate a Web Service Reference for us in the Web Service References folder.

Our Web application is now configured to consume the Web Service we previously created. Notice that in the above we configured our Web application using the URL that points to the Web Service’s WSDL. We could have used a project reference instead but I used the URL to emphasize that you can consume any Web Service running on any server, yours or some other, as long as you have access to its WSDL URL.

Now lets actually use the Web Service in our Wicket application.

1. In the Projects panel double click on the HomePage.html file. Notice how NetBeans opens it as well as the HomePage.java file. This behavior, among others such as generating a starter project, is a contribution of the NetBeans Wicket plugin.

2. Replace all the content in HomePage.html with the following:

<!DOCTYPE html> 
<html xmlns:wicket="http://wicket.apache.org"> 
    <head> 
        <meta charset="UTF-8"> 
    <wicket:head> 
        <title>Wicket Example</title> 
    </wicket:head> 
</head> 
<body> 
    <wicket:extend> 
       <h1 wicket:id="message">This gets replaced</h1>
       <form wicket:id="form" >
           <div wicket:id="feedbackpanel" />
           <input type="text" wicket:id="input1" /> + <input type="text" wicket:id="input2" /> = <span wicket:id="result" /><br/>
           <input type="submit" />
       </form>
    </wicket:extend> 
</body> 
</html>

From the above you can see that our markup is quite simple - we create a simple form with two text fields and a submit button.

Now, lets consume the add Web Service method.

1. Select the HomePage.java file and from the Projects panel and fully expand the Web Service References folder. Drag and drop the add method anywhere into the HomePage.java file and NetBeans will generate the call to our Web Service method for us. Rather than implement the rest of the code yourself you can replace the code in HomePage.java with the following

/*
 * HomePage.java
 *
 * Created on April 28, 2011, 6:30 AM
 */

package com.myapp.wicket;           

import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;

public class HomePage extends BasePage {
    
    private int input1 = 0;
    private int input2 = 0;
    private int result = 0;

    public int getInput1() {
        return input1;
    }

    public void setInput1(int input1) {
        this.input1 = input1;
    }

    public int getInput2() {
        return input2;
    }

    public void setInput2(int input2) {
        this.input2 = input2;
    }

    public int getResult() {
        return result;
    }

    public void setResult(int result) {
        this.result = result;
    }
    
    public HomePage() {
        add(new Label("message", "Enter 2 ints!"));

        Form<HomePage> form = new Form<HomePage>("form", new CompoundPropertyModel<HomePage>(HomePage.this)){

            @Override
            protected void onSubmit() {
                super.onSubmit();
                // Call the add web service method to calculate the result
                result = add(input1, input2);
            }
            
        };
        
        form.add(new FeedbackPanel("feedbackpanel"));
        form.add(new TextField<String>("input1"));
        form.add(new TextField<String>("input2"));
        form.add(new Label("result"));
        add(form);
    }

    private static int add(int i, int j) {
        webservices.CalculatorWebService_Service service = new webservices.CalculatorWebService_Service();
        webservices.CalculatorWebService port = service.getCalculatorWebServicePort();
        return port.add(i, j);
    }

}

In our java implementation we add the two text  fields to the form and the the form to the page. We override the form’s onSubmit method in which we call our Web Service method and assign its return value to result. When Wicket renders the page the page will display the result. Lets try it. Run the Web application and you should see the following

2011-04-28 11h32_22

Enter a valid numeric/integer value for both input fields and select Submit. The page will render with the result.

2011-04-28 11h34_05

Here is the result I get when I enter 10 and 14. The result, 24, is rendered back to the page. If you enter a non numeric value you will get an error message.

What We’ve Learned

As the examples here have demonstrated, an application that publishes Web Services is totally disconnected from any application that consumes its services. In our case, the consumer is a Wicket application. Wicket renders HTML and in our case it renders the result of calling our Web Service.

Our Web Service implementation knows nothing about any client application that may use its services. The client application consumes the Web Service via the WSDL.

In addition, NetBeans and its GlassFish tooling really makes both publishing and consuming Web Services ridiculously easy and the NetBeans Wicket plugin, with its ability to create a starter project as well as Wicket Pages and Panels is a great productivity booster.

I hope you have enjoyed this little walk-through of publishing and consuming Web Services with NetBeans, GlassFish, Wicket and the NetBeans Wicket plugin. Please feel free to leave a comment or a question.

Friday, April 22, 2011

Proposed Changes To The Netbeans Wicket Plugin’s Generated Starter Project

Currently, BasePage adds its markup to HomePage’s markup which is a subclass & that isn't a good practice. Just 1 file needs to be added, BasePage.html & it should include markup for the header panel. Then BasePage.java should be modified to add the header panel component to that.

I recommend that BasePage.html be implemented as follows:

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
    <head>
        <meta charset="UTF-8">
        <meta name="description" content="Put your description here!" />
    <wicket:head>
        <wicket:link>
            <link rel="stylesheet" type="text/css" href="style.css"/>
        </wicket:link>
    </wicket:head>
</head>
<body>
<section class="container" wicket:id="headerpanel">
</section>
<section class="content_container">
    <wicket:child/>
</section>
<footer>
    <span>Put your footer here</span>
</footer>
</body>
</html>

and that BasePage.java be implemented as:

import org.apache.wicket.markup.html.WebPage;

public abstract class BasePage extends WebPage {

    public BasePage() {
        super();
        add(new HeaderPanel("headerpanel"));
    }
   
}

and that HomePage.html be implemented as:

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
    <head>
        <meta charset="UTF-8">
    <wicket:head>
        <title>Title goes here!</title>
    </wicket:head>
</head>
<body>
<wicket:extend>
    <!-- Page specific markup goes here -->
</wicket:extend>
</body>
</html>

and that HomePage.java be implemented as:


package com.buzzwords.wicket;

import org.apache.wicket.markup.html.link.Link;

public class HomePage extends BasePage {
   
    public HomePage() {

    }
}

Now BasePage remains blissfully ignorant of HomePage and its markup hierarchy.

My example is using the new html5 doctype and character encoding specifications as well as some html5 tag candy.

About Me

My photo
New York, NY, United States
Software Developer