今天我将具体的说明wicket到底是什么,以及自己的学习心得
1.官网
http://wicket.apache.org/
目前版本为1.5.3
2.Hello World 的例子:
我已经写过了wicket的HelloWorld,很简单,基本就是一个WebPage,一个WebApplication,还有一个Html
具体的下面链接:
HelloWorld:
http://wicket.apache.org/learn/examples/helloworld.html
Page to Page:
http://chenhailong.iteye.com/admin/blogs/1319936
这个比较复杂,但也看懂了就很简单了
Wicket MVC结构:
Model 数据层
View 默认为XHTML模板
Controller Application和Component类来处理
Wicket如何处理用户请求
入口:WebApplication
中间件:Session->RequestCycle->Request->ResponsePage
出口:Response
RequestCycle的处理过程:
Request->prepare->requestTargets.push(处理队列)->processEventAndResponse->Response(WebPage->renderPage)
WebPage处理过程:
WebPage->VisitChildren(Models)->inner Model->input render
wicket1.5.3基本组件:
Output:Label,MultiLineLabel,alternative markup
layout and grouping:
Panel,Border,Include,TabbedPanel,Fragment
Links:
Link,ExternalLink,PageLink,BookmarkablePageLink
Forms:
Form,Button,SubmitLink,TextField,TextArea,CheckBox,CheckGroup,
CheckBoxMultipleChoice,Palette,DropDownChoice,ListChoice,RadioChoice,
Radio,ListMultipleChoice,Select
细细分析
1.Label label = new Label("test", "<span>message</span>");
label.setEscapeModelStrings(false);
对应HTML:
<label wicket:id = "test" >I am a good man</label>
2.MultiLineLabel label = new MultiLineLabel("test");
对应HTML
<span wicket:id ="test"><p>用户名称<br/>生日为</p></span>
MultiLineLabel 控件并不是继承自Label 控件,而是直接继承自WebComponent。
3.<span wicket:id="panel">
<span wicket:id="birthday">在这里输出生日信息</span>
</span>
public class PanelPage extends WebPage {
public PanelPage() {
super();
Panel panel = new Panel("panel");
this.add(panel);
panel.add(new Label("birthday", "2006-09-09"));
}
}
4.<H1>这里是我的版权声明,请不要随便修改我的资料啊!</H1>
<html>
<body>
<span wicket:id="include"> 在这里放置通用的Html代码</span>
</body>
</html>
public class IncludePage extends WebPage {
public IncludePage() {
super();
this.add(new Include("include", "common.Html"));
}
}
1.如何避免将Wicket 标签输出到客户端?
protected void init() {
super.init();
this.getMarkupSettings().setStripWicketTags(true);
}
setOutputMarkupId(false)方法禁止输出wicket:id这个标识
2.如何转向一个非Wicket页面
// 通知Wicket将要进行页面转向
getRequestCycle().setRedirect(false);
// 通知Wicket页面转向,不需要向客户端输出信息
getRequestCycle().setRequestTarget(EmptyRequestTarget.getInstance());
// 设定一个路径,并进行页面转向
String contextPath = getApplication().getApplicationSettings().getContextPath();
getResponse().redirect(contextPath + "/path/to/legacyJspFile.jsp");
3.如何将字符串与URL 进行转换呢
Wicket 提供了灵活的数据转换功能,你只需要重载Component 的getConverter 方法就
可以在两种数据类型之间进行转换。这个方法是要返回一个IConvertor 的实现,用来实现
数据转换。
public Object convert(Object value, Class c) {
if (value == null) {
return null;
}
if (c == URL.class) {
(value.getClass() == URL.class) {
return value;
}
try {
return new URL(value.toString());
} catch (MalformedURLException e) {
throw new ConversionException("'" + value + "' is not a valid URL");
}
}
return value.toString();
}
我可以在Wicket使用Frame吗
在 Wicket 中使用Frame 其实是一个比较麻烦的问题,Tapestry 中也存在同样的问题,
经常出现"当前页面已经过期"。这是因为Wicket 是将所有的页面信息都保存在Session
中,默认保存5 个页面,如果客户端所请求的页已经不在Session 中,那么就会出现这样
一个错误。所以如果要使用Frame 的话,Wicket 建议通过参数方式来处理Frame,提供一
个pageMap 来指定Frame,还有就是尽量使用bookmarkablePage 参数来定义转向页面,也
建议多使用无状态页面,这样可以更加安全。
<Html>
<HEAD>
<TITLE>A simple frameset document</TITLE>
</HEAD>
<FRAMESET cols="20%, 80%">
<FRAMESET rows="100, 200">
<FRAME
src="myapp?pagemap=leftframe&bookmarkablePage=mypackage.MyNavigationPage">
<FRAME src="myapp?bookmarkablePage=mypackage.MyMainPage">
</FRAMESET>
<FRAME
src="myapp?pagemap=bottomframe&bookmarkablePage=mypackage.MyStatusBarPage">
</FRAMESET>
</Html>
我能够动态的指定Html 元素的某个属性值吗?
在做一个数据列表的时候,我希望根据奇偶行数显示不同的颜色,最好是通过样式表
来显示这一功能,即通过Html 属性class 来指定css 的名称。如何来动态的指定这个属性
值呢?
if (item.getIndex() % 2 == 1) {
item.add(new AttributeModifier("class", true, new Model("even")));
} else {
item.add(new AttributeModifier("class", true, new Model("odd")));
}
在前面基础控件介绍中,有一个增强的多选框控件,是否一定要提供一个
boolean 属性?
List list=(List)group.getModelObject();
//list中就是客户选择的数据记录
前一个例子中,使用了<wicket:remove>这个标签,编辑的时候,可以看到标签中的内
容,在输出的时候为什么没有了,它用来做什么啊?
<wicket:remove>并不是功能标签,它是一个声明标签,它是指Wicket 在输出Html
时,忽略其中的所有的内容。
Wicket 程序运行是动态的,所以运行一个列表的时候,通常只需要在一个表格行上加
上相应的wicket:id 就可以了,但是美工MM设计页面时是静态的,为了方便她们看到数
据,所以多写了一些表格行,但是这些内容在运行时并不需要,所以加上<wicket:remove>
标签声明,这样即方便了美工MM的工作,也不会对程序员开发Html 告成困扰。
我可以动态改变页面上的控件吗?
一、通过Wicket 提供的Panel 来解决问题:
首先准备两个Panel,一个是使用MultiRadioChoice 进行单选,还有一个则是使用
DropDownChoice 进行单选,可以在页面上声明一个Panel,然后根据可选项的情况来放置
不同的Panel。
if (jobs.size() > 5) {
this.add(new RadioChoicePanel("component", jobs));
} else {
this.add(new DropDownChoicePanel("component", jobs));
}
<wicket:panel>
<select wicket:id="jobs"></select>
</wicket:panel>
public class DropDownChoicePanel extends Panel {
public DropDownChoicePanel(String id,List jobs) {
super(id);
this.add(new DropDownChoice("jobs",jobs));
}
}
<wicket:panel>
<span wicket:id="jobs"></span>
</wicket:panel>
public class RadioChoicePanel extends Panel {
public RadioChoicePanel(String id, List jobs) {
super(id);
this.add(new RadioChoice ("jobs", jobs));
}
}
通过隐藏控件来解决这个功能:
public SingleComponentPage() {
super();
RadioChoice radioChoice = new RadioChoice("radioChoice", jobs);
DropDownChoice dropDownChoice = new DropDownChoice("dropDownChoice",
jobs);
this.add(radioChoice);
this.add(dropDownChoice);
if (jobs.size() > 5) {
dropDownChoice.setVisible(false);
} else {
radioChoice.setVisible(false);
}
}
我可以对数据验证时产生的错误进行排序吗?
你可以实现一个Comparator 接口,然后通过 setSortingComparator 方法设置这个
Comparator ,然后FeedbackPanel 可会通过这个Comparator 来对错误信息进行排序。
备注:传递给Comparator 的是FeedbackMessage,而不是String。
下面是一个简单的实例:
feedback.setSortingComparator(new Comparator() {
public int compare(Object o1, Object o2) {
FeedbackMessage m1 = (FeedbackMessage) o1;
FeedbackMessage m2 = (FeedbackMessage) o2;
return 1;
}
});
为什么我使用Tree 控件得到结果与书上写的不一样?
使用 extension 包中的Tree 控件,应该就不存在这个问题了,推荐方案!
WicketTester 进行单元测试
Application.getAjaxSettings().setAjaxDebugModeEnabled(false)关闭该调试功能
我一定要把Html 模板同Java 放置在一起吗?
不一定的,你可以将Html 模板放在任何一个目录下面,然后在Application 中配置相
应的文件路径,只要它的路径与Java 代码一致即可:
代码如下所示:
package org.wicket.demo.hello;
import wicket.protocol.http.WebApplication;
import wicket.util.file.Path;
public class HelloWorldApplication extends WebApplication {
protected void init() {
super.init();
this.getMarkupSettings().setStripWicketTags(true);
String path = "D:\\Program\\Eclipse\\Workspace\\Wicket\\Wicket\\src";
//这里放置Html模板的路径
Path resourcePath = new Path();
resourcePath.add(path);
this.getResourceSettings().setResourceFinder(resourcePath);
}
public Class getHomePage() {
return HelloWorldPage.class;
}
}
为什么会经常出现页面过期的问题?
void setMaxPageMaps(int maxPageMaps);