Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Panel
borderStylesolid
titleTable of contents
Table of Contents
maxLevel2

Understanding errors

I get 'Internal error cloning object' errors

This is a debug feature to help find potential problems when the application runs clustered. It checks the component graphs to make sure everything is serializable (which is required for clustering).

If clustering support is not needed, these checks can be disabled by doing getDebugSettings().setSerializeSessionAttributes(false); in the application.init()

Also, if the configuration parameter in the web.xml is set to DEPLOYMENT, these checks are disabled.

Answer provided courtesy Igor Vaynberg

Wicket architecture

What about performance and scalability?

Wicket performance is actually quite good under stress. Remember though that in many real-world application your bottleneck will be in business or database layer.

Wicket benchmark can be found here: wicket-1.3.x-benchmark.

You should also search wicket-user mailing list for performance and scalability or simply use performance-scalability-tipsas your starting point.

Versioning

Wicket architecture

What about performance and scalability?

Wicket performance is actually quite good under stress. Remember though that in many real-world application your bottleneck will be in business or database layer.

Wicket benchmark can be found here: wicket-1.3.x-benchmark.

You should also search wicket-user mailing list for performance and scalability or simply use performance-scalability-tipsas your starting point.

Versioning

Wicket stores versions of pages to support the browser's back button. Because this concept is difficult Wicket stores versions of pages to support the browser's back button. Because this concept is difficult to understand, we'll present a simple use case that describes the problem and how versioning helps.

...

Igor Vaynberg in wicket-dev:

We are trying to consolidate the methods. We have a bunch of
internalOnAttach/internalAttach/attach/onattach methods. it's a big mess.
what this refactor does is give you one method you can override - onattach()
but forces the call to super.

Doing it like it has been done doesn't work. users assume onattach() is a
template method, they can override and not have to call super - but this
fails if you go more then one method deep!

if i create a custom component and do something in onattach(), then the user
subclasses it and they do something in onattach() and don't bother to call
super() they will break my functionality. My only choice of action is to
make onattach() final in my custom component and provide yet another
template for the user, onattach2() ? This just doesn't scale. Better to have
a simple and clear contract - onattach and ondetach always require the call
to super.

Unfortunately the only way to do that at this point and keep the same
method names is to do what i did.

OT there is a JSR for software defect annotations that includes something
like @MustCallSuper (forget what its called), that combined with an apt
builder in an ide will make these kinds of contracts very easy to enforce at
compile time. we are just not there just yet.

How can I use wicket to develop webapps that target mobile devices?

...

A "two-phase init" is a pattern that deals with this and other use cases. The big downside to that pattern is that you have to transfer all your constructor arguments into fields so they can be accessed by the second phase' init method, and for a framework concerned with size of the objects this does not mesh very well. It also adds a lot more code you have to write. so as far as making this change in Wicket we won't do that. Moreover, it is simple enough to add a private init() into your basepage and forward both constructors to it.

How do I add custom error pages

...

?

see Error Pages and Feedback Messages

How can I have images/files uploaded to and downloaded from my wicket app?

In short, use the wicket.markup.html.form.upload.FileUploadField component in your form (set as multiPart) in order to allow file uploads. Use an implementation of the wicket.markup.html.DynamicWebResource to provide downloads of the content. For a longer description with examples see Uploading and Downloading Files

What is the difference between setResponsePage(new MyWebPage()) and setResponsePage(MyWebPage.class)

setResponsePage(new MyWebPage()) (or setResponsePage(new MyWebPage(myPageParameters))) can be used if you want to have a bookmarkable url in the browser (your page must have default constructor or PageParameter constructor).
setResponsePage(MyWebPage.class) can be used if you want to pass information to pages on the serverside. This generates a session specific url (most of the time you can use hybrid url coding strategy).

In your application class that extends WebApplication, set the following in the init() method:

...


getApplicationSettings().setPageExpiredErrorPage(MyExpiredPage.class);
getApplicationSettings().setAccessDeniedPage(MyAccessDeniedPage.class);
getApplicationSettings().setInternalErrorPage(MyInternalErrorPage.class);

There are also some other neat settings you should check out in getApplicationSettings(), getDebugSettings(), getExceptionSettings(), getMarkupSettings(), getPageSettings(), getRequestCycleSettings(), getSecuritySettings and getSessionSettings(). See the javadoc for more information.

If calling setInternalErrorPage, make sure to also call:
getExceptionSettings().setUnexpectedExceptionDisplay(IExceptionSettings.SHOW_INTERNAL_ERROR_PAGE);

How can I have images/files uploaded to and downloaded from my wicket app?

In short, use the wicket.markup.html.form.upload.FileUploadField component in your form (set as multiPart) in order to allow file uploads. Use an implementation of the wicket.markup.html.DynamicWebResource to provide downloads of the content. For a longer description with examples see UploadDownload

The view layer, markup etc.

...

Wicket reads the html template from the same location as the Page class (java class name + ".html"). Can this be changed?the same location as the Page class (java class name + ".html"). Can this be changed?

Yes. See Control where HTML files are loaded from

How can I render my templates to a String?

Code Block

public class PageRenderer extends BaseWicketTester
{
	private final Locale locale;

	public PageRenderer(Locale locale)
	{
		this.locale = locale;
	}

	public PageRenderer()
	{
		this.locale = null;
	}

	private String renderStartPage()
	{
		if (this.locale != null)
		{
			getWicketSession().setLocale(locale);
		}

		return getServletResponse().getDocument();
	}

	public synchronized String render(Class<? extends WebPage> pageClass)
	{
		startPage(pageClass);
		return renderStartPage();
	}

	public synchronized String render(Class<? extends WebPage> pageClass, PageParameters parameters)
	{
		startPage(pageClass, parameters);
		return renderStartPage();
	}

	public synchronized String render(WebPage page)
	{
		startPage(page);
		return renderStartPage();
	}

}

For different approach please check Use wicket as template engine.

How to add #-anchor (opaque) to page url?

I don't know universal solution, but for mounted pages you can override particular url coding strategy to encode a parameter in special way. Say, I named parameter "#" and my strategy:

Code Block

public CharSequence encode(IRequestTarget requestTarget) {
		if (!(requestTarget instanceof IBookmarkablePageRequestTarget))
		{
			throw new IllegalArgumentException("this encoder can only be used with instances of " +
					IBookmarkablePageRequestTarget.class.getName());
		}
		IBookmarkablePageRequestTarget target = (IBookmarkablePageRequestTarget)requestTarget;

		AppendingStringBuffer url = new AppendingStringBuffer(40);
		url.append(getMountPath());
		final String className = target.getPageClass().getSimpleName();
		PageParameters pageParameters = target.getPageParameters();
		if (target.getPageMapName() != null)
		{
			pageParameters.put(WebRequestCodingStrategy.PAGEMAP, WebRequestCodingStrategy
					.encodePageMapName(target.getPageMapName()));
		}
		final String fragment = pageParameters.getString("#");
		if(fragment != null)
			pageParameters.remove("#");

		url.append("/");
		url.append(className);

		if(!pageParameters.isEmpty())
		{
			url.append("?");
			appendParameters(url, pageParameters);
		}
		if(fragment != null)
			url.append("#").append(urlEncodePathComponent(fragment));
		return url;
	}

Now you can add parameter named "#" in PageParameters bookmarkable page link or so and it will be rendered as anchor.Yes. See Control where HTML files are loaded from

More on the view: AJAX

I get errors when I use Ajax in Opera Browser (before Version Beta 9 of Opera)

...

Which browsers have been tested with Wicket AJAX?

To test it use the AJAX examples and the AJAX request header test.

  • Internet Explorer 6 and 7
  • Firefox 1.5
  • Firefox 2.0
  • Safari 2.0.1 - 2.0.4
  • Opera 8.54 (linux)
  • Opera 9 (linux)
  • Konqueror 3.5.2 (most of the examples works, but the Todo list example makes the browser crash)

.

  • Google Chrome - latest two stable versions
  • Firefox - latest two stable versions
  • Safari 5.x and 6.x
  • Opera 12.x and 15.x
  • Internet Explorer 8+

Wicket.replaceOuterHtml gives weird result on Firefox

...

Add the following to your web.xml, inside your <servlet> mapping definition (or <filter> mapping definition if you're using 1.3.x):

Code Block
xml
xml
<init-param>
            <param-name>configuration</param-name>
            <param-value>deployment</param-value>
</init-param>

...