Browse DevX
Sign up for e-mail newsletters from DevX


Java Web Development the Wicket Way : Page 2

Wicket, a lightweight, component-oriented web application framework in plain Java and XHTML, stresses separation of concerns, testability, and good object-oriented design practices. Check out Wicket's approach to common implementation scenarios.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Step 1: Enforcing Page Authorization
Wicket's unique WicketTester class isolates applications in simulated servlet containers, and provides high-level methods for interacting with them. This enables test-driven design with functional tests such as the following, which specifies that anonymous users should be sent to the LoginPage:

@Test public void shouldAuthChallenge() { wicketTester.startPage(FileInfoPage.class); wicketTester.assertRenderedPage(LoginPage.class); }

(For an introduction to test-driven design, check out the DevX article, Efficient Test-Driven Design with Unitils.)

To establish authorization and authentication, the application class must extend AuthenticatedWebApplication, specify a login page, and use a WebSession derived from AuthenticatedWebSession as follows:

public class ExampleWicketApplication extends AuthenticatedWebApplication { @Override protected Class<? extends WebPage> getSignInPageClass() { return LoginPage.class; } @Override protected Class<? extends AuthenticatedWebSession> getWebSessionClass() { return ExampleWebSession.class; } ...

Sessions have many responsibilities in Wicket; they aren't simply generic containers for persistent variables as in other frameworks. In this case, ExampleWebSession implements the means of authentication (more on the role of sessions later). The following code adds authorization protection to the FileInfoPage:

@AuthorizeInstantiation("USER") public class FileInfoPage extends BasePage { ...

The shouldAuthChallenge test now passes, and you're ready to implement authentication.

Step 2: Enabling Authentication
Now that users are being sent to the LoginPage, you can test to assure that they are able to log in as a guest and get forwarded to the FileInfoPage:

@Test public void shouldAllowGuestAuth() { wicketTester.startPage(FileInfoPage.class); wicketTester.assertRenderedPage(LoginPage.class); FormTester formTester = wicketTester.newFormTester("signInPanel:signInForm"); formTester.setValue("username", "guest"); formTester.setValue("password", "guest"); formTester.submit(); wicketTester.assertRenderedPage(FileInfoPage.class); }

This test takes a bit of research. You need to look into the markup of the stock SignInPanel component to determine the ID of the form ("signInForm") and its input IDs ("username" and "password"). Luckily this is simple to do using your IDE's package explorer. You may have noticed that having markup in disparate locations like this could break separation of concerns (see Sidebar 2 for an explanation).

Wicket brings together LoginPage.java and LoginPage.html when rendering the LoginPage. One simple link exists between the two: the wicket:id HTML attribute, which anchors components at specific locations on the page:

public class LoginPage extends BasePage { public LoginPage() { add(new SignInPanel("signInPanel")); } } <body> <wicket:extend> <div wicket:id="signInPanel"/> </wicket:extend> </body>

The string signInPanel, which places the SignInPanel inside a div in the markup, is one of the only points where you lose type safety in Wicket applications. Luckily, WicketTester helps you catch typos in an automated fashion, and the framework provides detailed debugging output when components in the code don't match up to those specified in the markup.

Next, you implement authentication and authorization inside ExampleWebSession:

@Override public boolean authenticate(String userName, String password) { boolean success = userName.equals("guest") && password.equals("guest"); if ( success ) this.userName = userName; return success; } @Override public Roles getRoles() { Roles roles = new Roles(); if ( isSignedIn() ) roles.add("USER"); return roles; }

This example permits guests to authenticate, and it authorizes them to instantiate the FileInfo page via the USER role. Wicket automatically forwards guests to the original destination, and the "shouldAllowGuestAuth" test now passes.

Thanks for your registration, follow us on our social networks to keep up-to-date