Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Java Web Development the Wicket Way : Page 4

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.


advertisement
Wicket's Event-Driven Model and PageMap
In keeping with the use case, it's time to move on to FileUploadPage. Override the default onSubmit method in Form:

@Override protected void onSubmit() { super.onSubmit(); FileUploadPage fileUploadPage = new FileUploadPage(getModel()); setResponsePage(fileUploadPage); }

Wicket's event-driven, unmanaged nature is clear here; whatever page you add a FileInfoForm to, submitting that instance of FileInfoForm executes the event handler and sends the user to a newly constructed FileUploadPage. The model object is already populated with validated values at this point, and you pass it to the next page's constructor. This is a departure from other frameworks, which often use the session to marshal objects from one page to the next.



Wicket maintains a server-side cache of the object graphs that represent each page rendered to the user. This makes your application a true state machine, and effectively solves the classic back button problem. For example, after advancing to the FileUploadPage, the user can hit the back button and Wicket will deserialize and render a copy of the object that represents the FileInfoPage the user was just on. The FileInfoForm's model is part of the object graph of the page, and so Wicket deserializes it and binds it to the form with all the values last submitted by the user intact. This is a much more effective way to manage moving back and forth in multipage workflows than juggling session variables. (If this raises any red flags for scalability, read Sidebar 3.)

Wicket caches the object graph that backs each page rendered in a PageMap attached to the user's session (see Figure 3). These previously visited pages are eventually garbage collected, but in the meantime the user can access them with the back button, or by utilizing the workflow code to repeat previous steps.

Click to enlarge

Figure 3. The Wicket PageMap:
Wicket caches the object graph that backs each page rendered in a PageMap attached to the user's session.

File Upload with AJAX Progress Feedback
The "shouldAcceptInfoAndAdvance" test now passes, and users can get as far as the FileUploadPage. The last step is for them to be able to upload their files, which you specify with the following test:

@Test public void shouldAcceptFileUpload() { shouldAcceptMetaAndAdvance(); FormTester formTester = wicketTester.newFormTester("fileUploadForm"); formTester.setFile("fileInput", TEST_UPLOAD_FILE, "image/jpeg"); formTester.submit(); // for simplicity we store the previously collected meta information in // the file name. String uploadedFilePath = TEST_UPLOAD_FOLDER.getAbsolutePath() .concat( File.separator ) .concat("guest-Alpine Lakes Trail-hike+forest+alpine lakes.jpg"); java.io.File uploadedFile = new java.io.File(uploadedFilePath); Assert.assertTrue ("File not deposited in upload folder or incorrectly named.", uploadedFile.exists()); uploadedFile.delete(); } }

Now you implement your second Form component: FileUploadForm. You can read the onSubmit event handler later, but for now take a closer look at the constructor and Wicket's AJAX support:

public class FileUploadPage extends BasePage { private class FileUploadForm extends Form { private FileUploadField fileUploadField; public FileUploadForm(String id) { super(id); setOutputMarkupId(true); setMultiPart(true); setMaxSize(Bytes.megabytes(3)); add(fileUploadField = new FileUploadField("fileInput")); add(new UploadProgressBar("progress", this)); } ...

Wicket implements AJAX in a manner consistent with the rest of its design (see Figure 4). By maintaining the full object graph of each page on the server side, the browser can easily communicate with individual components after a page is rendered. Each component on the client side can communicate with its server-side counterpart. Responses can update the state of existing components on the page, or add entirely new ones. Components are addressed using special strings that path into the object graph. Wicket communicates state changes, which can include updates to or additions of one or more components, back to the browser DOM using a thin JavaScript library.

Click to enlarge

Figure 4. AJAX the Wicket Way:
Here is a rough overview of how Wicket implements AJAX.

The UploadProgressBar component in this example works in a somewhat involved manner, but it's still a good example of how Wicket can be extended to accommodate complex AJAX functionality without breaking encapsulation. Simply add the progress bar component to your form and configure the application to use UploadWebRequests in ExampleWicketApplication with this override:

@Override protected WebRequest newWebRequest(HttpServletRequest servletRequest) { return new UploadWebRequest(servletRequest); } ...



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap