[
https://issues.apache.org/jira/browse/WICKET-6461?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Melissa Beldman updated WICKET-6461:
------------------------------------
Description:
>From the documentation here:
https://ci.apache.org/projects/wicket/guide/6.x/guide/urls.html
I'm following the section titled, "Using parameter placeholders with mounted
pages".
In the documentation from here:
https://cwiki.apache.org/confluence/display/WICKET/Request+mapping
{code}
Named parameters - /page/${named1}/${named2}
mountPage("/page/${named1}/${named2}", MyPage.class);
Now a request to "/page/a/b" will be handled by MyPage and the parameters can
be get with PageParameters.get(String) (e.g. parameters.get("named1") will
return "a")
Optional named parameters - /page/${named1}/#{named2\
mountPage("/page/${named1}/#{named2}", MyPage.class);
This means the second parameter is optional. Requests to "/page/a/b" ,
"/page/a/b/" and "/page/a/" will be handled by MyPage and the parameters can be
get with PageParameters.get(String) (e.g. parameters.get("named2") will return
"b" for the first case and null for the second).
The mapper is smart enough to handle optional named parameters in any segment,
not just the last one.
{code}
it states: "The mapper is smart enough to handle optional named parameters in
any segment, not just the last one."
I've found it does matter IF other segments in the url are also parameter
placeholders. The resulting behaviour is that if the optional parameter
placeholder isn't provided in the URL, the page's default constructor gets
called instead of the PageParameter constructor as expected (since there are
still additional PageParameter data that may need to be processed by the page).
Here is my example:
>From child class of AdtAuthenticatedWebApplication
{code}
@Override
protected void init()
{
super.init();
mountPage("/foo/#{optParam}/${otherParam}",
ca.example.for.testing.MyPage.class);
}
{code}
In child class of WebPage
{code}
public class MyPage extends WebPage
{
public MyPage(PageParameters parameters)
{
super(parameters);
StringValue optParam = parameters.get("optParam");
StringValue otherParam = parameters.get("otherParam");
//do something...
}
private MyPage()
{
throw new IllegalAccessError("The default constructor should not be
instantiated");
}
{code}
And in a different class:
{code}
public static BookmarkablePageLink getBookmarkableLink(String id, String
optParam, String otherParam)
{
PageParameters pageParam = new PageParameters();
pageParam.add("otherParam", otherParam);
if (optParam != null && !optParam.isEmpty())
{
pageParam.add("optParam", optParam);
}
return new BookmarkablePageLink(id, MyPage.class, pageParam);
}
{code}
Here are the result of clicking on the BookmarkablePageLinks created:
{code}
/foo/baz/bar -- calls MyPage(PageParameters parameters) constructor
/foo/bar -- attempts to call MyPage default constructor (exception thrown)
{code}
Exception thrown is:
{code}
Last cause: Class org.apache.wicket.session.DefaultPageFactory can not access a
member of class ca.example.for.testing.MyPage with modifiers "private"
WicketMessage: Can't instantiate page using constructor 'private
ca.example.for.testing.MyPage()'. This constructor is private!
{code}
was:
>From the documentation here:
https://ci.apache.org/projects/wicket/guide/6.x/guide/urls.html
I'm following the section titled, "Using parameter placeholders with mounted
pages".
In the documentation from here:
https://cwiki.apache.org/confluence/display/WICKET/Request+mapping
{code}
Named parameters - /page/${named1}/${named2}
mountPage("/page/${named1}/${named2}", MyPage.class);
Now a request to "/page/a/b" will be handled by MyPage and the parameters can
be get with PageParameters.get(String) (e.g. parameters.get("named1") will
return "a")
Optional named parameters - /page/${named1}/#{named2\
mountPage("/page/${named1}/#{named2}", MyPage.class);
This means the second parameter is optional. Requests to "/page/a/b" ,
"/page/a/b/" and "/page/a/" will be handled by MyPage and the parameters can be
get with PageParameters.get(String) (e.g. parameters.get("named2") will return
"b" for the first case and null for the second).
The mapper is smart enough to handle optional named parameters in any segment,
not just the last one.
{code}
it states: "The mapper is smart enough to handle optional named parameters in
any segment, not just the last one."
I've found it does matter IF other segments in the url are also parameter
placeholders. The resulting behaviour is that if the optional parameter
placeholder isn't provided in the URL, the page's default constructor gets
called instead of the PageParameter constructor as expected (since there are
still additional PageParameter data that may need to be processed by the page).
Here is my example:
>From child class of AdtAuthenticatedWebApplication
{code}
@Override
protected void init()
{
super.init();
mountPage("/foo/#{optParam}/${otherParam}",
ca.example.for.testing.MyPage.class);
}
{code}
In child class of WebPage
{code}
public class MyPage extends WebPage
{
public MyPage(PageParameters parameters)
{
super(parameters);
StringValue optParam = parameters.get("optParam");
StringValue otherParam = parameters.get("otherParam");
//do something...
}
private MyPage()
{
throw new IllegalAccessError("The default constructor should not be
instantiated");
}
{code}
And in a different class:
{code}
public static BookmarkablePageLink getBookmarkableLink(String id, String
optParam, String otherParam)
{
PageParameters pageParam = new PageParameters();
pageParam.add("otherParam", otherParam);
if (optParam != null && !optParam.isEmpty())
{
pageParam.add("optParam", optParam);
}
return new BookmarkablePageLink(id, MyPage.class, pageParam);
}
{code}
Here are the result of clicking on the BookmarkablePageLinks created:
{code}
/foo/baz/bar -- calls MyPage(PageParameters parameters) constructor
/foo/bar -- attempts to call MyPage default constructor (exception thrown)
{code}
Exception thrown is:
{code}
Last cause: Class org.apache.wicket.session.DefaultPageFactory can not access a
member of class ca.example.for.testing.MyPage with modifiers "private"
WicketMessage: Can't instantiate page using constructor 'private
ca.example.for.testing.MyPage()'. This constructor is private!
{code}
> Default constructor is incorrectly called if optional param is not provided
> in parameter placeholder URL with additional required parameter
> -------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: WICKET-6461
> URL: https://issues.apache.org/jira/browse/WICKET-6461
> Project: Wicket
> Issue Type: Bug
> Components: wicket
> Affects Versions: 6.22.0
> Reporter: Melissa Beldman
>
> From the documentation here:
> https://ci.apache.org/projects/wicket/guide/6.x/guide/urls.html
> I'm following the section titled, "Using parameter placeholders with mounted
> pages".
> In the documentation from here:
> https://cwiki.apache.org/confluence/display/WICKET/Request+mapping
> {code}
> Named parameters - /page/${named1}/${named2}
> mountPage("/page/${named1}/${named2}", MyPage.class);
> Now a request to "/page/a/b" will be handled by MyPage and the parameters can
> be get with PageParameters.get(String) (e.g. parameters.get("named1") will
> return "a")
> Optional named parameters - /page/${named1}/#{named2\
> mountPage("/page/${named1}/#{named2}", MyPage.class);
> This means the second parameter is optional. Requests to "/page/a/b" ,
> "/page/a/b/" and "/page/a/" will be handled by MyPage and the parameters can
> be get with PageParameters.get(String) (e.g. parameters.get("named2") will
> return "b" for the first case and null for the second).
> The mapper is smart enough to handle optional named parameters in any
> segment, not just the last one.
> {code}
> it states: "The mapper is smart enough to handle optional named parameters in
> any segment, not just the last one."
> I've found it does matter IF other segments in the url are also parameter
> placeholders. The resulting behaviour is that if the optional parameter
> placeholder isn't provided in the URL, the page's default constructor gets
> called instead of the PageParameter constructor as expected (since there are
> still additional PageParameter data that may need to be processed by the
> page).
> Here is my example:
> From child class of AdtAuthenticatedWebApplication
> {code}
> @Override
> protected void init()
> {
> super.init();
> mountPage("/foo/#{optParam}/${otherParam}",
> ca.example.for.testing.MyPage.class);
> }
> {code}
> In child class of WebPage
> {code}
> public class MyPage extends WebPage
> {
> public MyPage(PageParameters parameters)
> {
> super(parameters);
> StringValue optParam = parameters.get("optParam");
> StringValue otherParam = parameters.get("otherParam");
> //do something...
> }
> private MyPage()
> {
> throw new IllegalAccessError("The default constructor should not be
> instantiated");
> }
> {code}
> And in a different class:
> {code}
> public static BookmarkablePageLink getBookmarkableLink(String id, String
> optParam, String otherParam)
> {
> PageParameters pageParam = new PageParameters();
>
> pageParam.add("otherParam", otherParam);
> if (optParam != null && !optParam.isEmpty())
> {
> pageParam.add("optParam", optParam);
> }
>
> return new BookmarkablePageLink(id, MyPage.class, pageParam);
>
> }
> {code}
> Here are the result of clicking on the BookmarkablePageLinks created:
> {code}
> /foo/baz/bar -- calls MyPage(PageParameters parameters) constructor
> /foo/bar -- attempts to call MyPage default constructor (exception thrown)
> {code}
> Exception thrown is:
> {code}
> Last cause: Class org.apache.wicket.session.DefaultPageFactory can not access
> a member of class ca.example.for.testing.MyPage with modifiers "private"
> WicketMessage: Can't instantiate page using constructor 'private
> ca.example.for.testing.MyPage()'. This constructor is private!
> {code}
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)