之前写的文章
Wicket如何通过OSGi框架注入Jetty 中关于wicket如何在OSGi下工作比较繁琐,经过不断摸索,发现一种简化的方式,而且可以在wicket的程序类修改时不重新启动整个OSGi框架,只通过update就可以更新wicket程序,很方便。
首先看一下jetty如何整合到OSGi中,建一个Bundle(wanged_core_jetty)写一个Jetty的类:
java 代码
- package wanged.core.jetty;
-
- import java.util.List;
-
- import org.mortbay.jetty.Handler;
- import org.mortbay.jetty.Server;
- import org.mortbay.jetty.handler.HandlerCollection;
-
- public class Jetty {
-
- private Server server = new Server(8080);
-
- private HandlerCollection handlerCollection;
-
- private List<Handler> handlers;
-
- public void start() {
-
- if (handlers != null && handlers.size() > 0) {
- this.handlerCollection.setHandlers(handlers.toArray(new Handler[handlers.size()]));
- }
-
- this.server.setHandler(handlerCollection);
- try {
- this.server.start();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void stop() {
- try {
- this.server.stop();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public void setHandlerCollection(HandlerCollection handlerCollection) {
- this.handlerCollection = handlerCollection;
- }
-
-
-
-
-
-
- public void setHandlers(List<Handler> handlers) {
- this.handlers = handlers;
- }
-
- }
这个Bundle中就一个类,下面看配置文件:
xml 代码
- <osgi:service interface="org.mortbay.jetty.HandlerContainer" ref="handlerCollection" />
-
-
- <bean name="requestLog" class="org.mortbay.jetty.NCSARequestLog">
- <property name="filename" value="F:/TMP/yyyy_mm_dd.request.log" />
- <property name="filenameDateFormat" value="yyyy_MM_dd" />
- <property name="logDateFormat" value="yyyy-MM-dd HH:mm:ss" />
- <property name="logLatency" value="true" />
- <property name="extended" value="false" />
- </bean>
-
-
- <bean name="requestLogHandler" class="org.mortbay.jetty.handler.RequestLogHandler">
- <property name="requestLog" ref="requestLog" />
- </bean>
-
-
- <bean name="handlerCollection" class="org.mortbay.jetty.handler.HandlerCollection" />
-
-
- <bean name="jettyServer" class="wanged.core.jetty.Jetty" init-method="start" destroy-method="stop">
- <property name="handlerCollection" ref="handlerCollection" />
- <property name="handlers">
- <list>
- <ref bean="requestLogHandler" />
- </list>
- </property>
- </bean>
好了,这个已经搞定,目前Jetty可以单独启动了。
下面来看wicket的bundle,中间涉及到4个主要类:
java 代码
- package wanged.web.wicket;
-
- import org.mortbay.jetty.HandlerContainer;
- import org.mortbay.jetty.webapp.WebAppContext;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
-
- public class WicketApplication implements ApplicationContextAware {
-
- private WebAppContext ctx;
-
- public WicketApplication(String webApp, String contextPath) {
- ctx = new WebAppContext(webApp, contextPath);
- }
-
- public void start() throws Exception {
- ctx.start();
- }
-
- public void stop() throws Exception {
- ctx.stop();
- }
-
-
-
-
-
-
- public void setHandlerContainer(HandlerContainer handlerContainer) {
- handlerContainer.addHandler(ctx);
- }
-
- public void setApplicationContext(ApplicationContext context) throws BeansException {
-
- ctx.setAttribute(ApplicationContext.class.getName(), context);
- }
- }
这个用来启动wicket的web应用,具体配置请看后面的配置文件。
Wicket本身和Spring的整合很简单,这里借鉴了官方实现写了两个简单的类来处理:
java 代码
- package wanged.web.wicket;
-
- import java.lang.annotation.ElementType;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target( { ElementType.FIELD })
- public @interface SpringBean {
-
-
-
-
-
-
- String name() default "";
- }
这个声明了一个原数据,你的Wicket组件中使用方法如下:
java 代码
- private static final class LoginForm extends Form {
- @SpringBean
- private transient RoleService roleService;
- ......
- }
这样就可以通过下面这个类,自动将Bean注入。
java 代码
- package wanged.web.wicket;
-
- import java.lang.reflect.Field;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Map;
-
- import org.apache.wicket.Component;
- import org.apache.wicket.application.IComponentInstantiationListener;
- import org.springframework.context.ApplicationContext;
-
- public class SpringComponentInjector implements IComponentInstantiationListener {
-
- public final static String WICKET_PACKAGE = "org.apache.wicket";
-
- private HashMap<Class<Component>, Map<Field, SpringBean>> AnnotationCacheMap = new HashMap<Class<Component>, Map<Field, SpringBean>>();
-
- private ApplicationContext context;
-
-
-
-
-
-
- public SpringComponentInjector(ApplicationContext context) {
- this.context = context;
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void onInstantiation(Component component) {
- Map<Field, SpringBean> fieldMap = getFieldMap((Class<Component>) component.getClass());
- if (fieldMap != null) {
-
- for (Map.Entry<Field, SpringBean> entry : fieldMap.entrySet()) {
- this.inject(entry.getKey(), component, entry.getValue());
- }
- }
- }
-
-
-
-
-
-
- private final Map<Field, SpringBean> getFieldMap(Class<Component> clazz) {
-
-
- if (clazz.getName().startsWith(WICKET_PACKAGE)) {
- return null;
- }
-
-
- synchronized (AnnotationCacheMap) {
- Map<Field, SpringBean> map = AnnotationCacheMap.get(clazz);
-
- if (map == null) {
- map = createFieldMap(clazz);
- AnnotationCacheMap.put(clazz, map);
- }
- return map;
- }
-
- }
-
- private Map<Field, SpringBean> createFieldMap(Class<Component> clazz) {
- Map<Field, SpringBean> map = new HashMap<Field, SpringBean>();
-
- for (Field field : clazz.getDeclaredFields()) {
- SpringBean beanAnon = field.getAnnotation(SpringBean.class);
- if (beanAnon != null) {
- map.put(field, beanAnon);
- }
- }
-
-
- if (map.size() == 0) {
- return null;
- }
-
-
- return Collections.unmodifiableMap(map);
- }
-
- private final void inject(Field field, Object instance, SpringBean beanAnon) {
- Object o = this.getBean(field, beanAnon);
- if (o != null) {
- try {
- if (field.isAccessible()) {
- field.set(instance, o);
- } else {
- field.setAccessible(true);
- field.set(instance, o);
- field.setAccessible(false);
- }
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
- }
-
- private final Object getBean(Field field, SpringBean beanAnon) {
- String beanName = beanAnon.name();
-
- if ("".equals(beanName)) {
- beanName = field.getName();
- }
- return this.context.getBean(beanName);
- }
-
- }
主要的类都已经有了,现在就缺每个wicket都需要的WebApplication类的子类了:
java 代码
- package wanged.web.wicket;
-
- import java.io.File;
-
- import org.apache.wicket.protocol.http.WebApplication;
- import org.apache.wicket.session.ISessionStore;
- import org.apache.wicket.util.lang.PackageName;
- import org.springframework.context.ApplicationContext;
-
- import wanged.web.wicket.page.help.ErrorPage;
- import wanged.web.wicket.page.login.Login;
-
- public class DefaultApplication extends WebApplication {
-
- public static final String DISK_STORE_PATH = "DISK_STORE_PATH";
-
- @SuppressWarnings("unchecked")
- @Override
- public Class getHomePage() {
- return Login.class;
- }
-
- @Override
- protected void init() {
- ApplicationContext ac = (ApplicationContext) getServletContext().getAttribute(ApplicationContext.class.getName());
- this.addComponentInstantiationListener(new SpringComponentInjector(ac));
- this.mount("/login", PackageName.forClass(Login.class));
- this.mount("/help", PackageName.forClass(ErrorPage.class));
- }
-
- @Override
- protected ISessionStore newSessionStore() {
- getServletContext().setAttribute("javax.servlet.context.tempdir", new File(getInitParameter("pageStorePath")));
- return super.newSessionStore();
- }
-
- }
有了这些类,还需要配置文件将他们组合起来才能使用:
xml 代码
- <osgi:reference interface="org.mortbay.jetty.HandlerContainer" id="handlerContainer" />
-
- <bean id="wicketApp" class="wanged.web.wicket.WicketApplication" init-method="start" destroy-method="stop">
- <constructor-arg value="d:/Workspace/wanged_wicket_app/webapp" />
- <constructor-arg value="/" />
- <property name="handlerContainer" ref="handlerContainer" />
- </bean>
有了上面的配置还需要一点,就是我们的web应用的根目录
d:/Workspace/wanged_wicket_app/webapp,在这里我们放置静态文件和web.xml:
xml 代码
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- version="2.5">
-
- <filter>
- <filter-name>gzipFilter</filter-name>
- <filter-class>org.mortbay.servlet.GzipFilter</filter-class>
- </filter>
-
- <filter>
- <filter-name>wicketFilter</filter-name>
- <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
- <init-param>
- <param-name>applicationClassName</param-name>
- <param-value>wanged.web.wicket.DefaultApplication</param-value>
- </init-param>
- <init-param>
- <param-name>pageStorePath</param-name>
- <param-value>F:/TMP</param-value>
- </init-param>
- <init-param>
- <param-name>configuration</param-name>
- <param-value>development</param-value>
- </init-param>
- </filter>
-
- <filter-mapping>
- <filter-name>gzipFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <filter-mapping>
- <filter-name>wicketFilter</filter-name>
- <url-pattern>/wkt/*</url-pattern>
- </filter-mapping>
-
- </web-app>
好了,现在就自己写一个Wicket页面尝试一下吧^_^
分享到:
- 2007-09-08 14:16
- 浏览 3597
- 评论(0)
- 论坛回复 / 浏览 (0 / 3623)
- 查看更多
相关推荐
Wicket 作为一种先进的 Java Web 开发框架,不仅提供了丰富的功能和组件库,而且拥有较低的学习曲线,非常适合希望快速构建高质量 Web 应用的开发者。无论是对于初学者还是经验丰富的开发人员来说,掌握 Wicket 都将...
总之,Wicket是一个强大的Web开发框架,它提供了组件化的编程模型和优秀的Ajax支持,适合构建交互性强、易于维护的Web应用。对于想要深入理解J2EE开发的开发者来说,学习Wicket是一个不错的选择。《Wicket开发指南》...
**Wicket 开发指南** ...综上所述,"Wicket开发指南"涵盖了Wicket框架的各个方面,从基础概念到高级特性,为开发者提供了全面的指导。通过学习和实践,你可以掌握使用Wicket构建高效、可维护的Web应用的技能。
Wicket是一个开源的Java Web应用程序框架,它提供了一种组件化的开发方式,...通过阅读开发指南并亲手运行这些示例,你将能够深入理解Wicket的工作原理,熟练掌握其开发技巧,从而在实际项目中更高效地使用Wicket框架。
3. **灵活性**:开发框架应该提供足够的灵活性,允许开发者根据具体需求调整框架行为,而不是仅仅局限于特定的模式或方法。 4. **高性能**:支持高性能的应用开发,包括对SQL查询的优化和支持大数据量的应用场景。...
面向组件的Web开发框架的优点 3.4。Wicket与其他面向组件的框架相比 威克特说“你好世界!” 4.1。Wicket分发和模块 4.2。Wicket应用程序的配置 4.3。HomePage类 4.4。Wicket链接 4.5。摘要 5. Wicket作为页面布局...
Wicket 1.4.0是该框架的一个版本,提供了丰富的功能和改进,使得Web开发更为简便。在本篇文章中,我们将深入探讨Wicket 1.4.0的核心特性以及如何使用它来构建Web应用。 **Wicket 1.4.0 特性** 1. **组件模型**:...
- **Wicket概述**:Wicket是一个轻量级框架,其设计旨在降低开发门槛,并通过一系列特性提升开发体验。 **1.4 Wicket的主要特性** - **更加纯粹的Java和面向对象**:Wicket的设计遵循Java的最佳实践,使得开发者...
Wicket 是一个开源的Java Web应用程序框架,它提供了一种模型-视图-控制器(MVC)的编程模式,让开发者能够编写出更加清晰、易于维护的Web应用。本开发指南将带你深入了解Wicket的核心概念、架构以及如何有效地使用...
在Wicket问世之初,市场上已经存在多种成熟的Java Web框架,如Struts、WebWork等。对于Wicket是否属于“重新发明轮子”的讨论一直存在。然而,Wicket通过其独特的组件化设计和易于使用的特性,在众多框架中脱颖而出...
**Wicket 开发指南** Wicket 是一个开源的Java Web应用程序框架,以其组件化和模型-视图-控制器(MVC...在实际开发中,结合最佳实践和不断积累的经验,你将能更好地发挥Wicket的优势,构建出满足需求的高质量Web应用。
Apache Wicket 是一款开源的 Java Web 开发框架,它的设计目标是使 Java 开发者能够像编写桌面应用程序一样编写 Web 应用。Wicket 强调简洁性、灵活性和可扩展性,它采用了组件化的设计思路,允许开发者使用类来表示...
Wicket是一款开源的Java Web应用程序框架,它强调组件化和声明式编程模型,使得开发人员可以构建出用户界面更加灵活且易于维护的Web应用。本教程将深入探讨Wicket的核心概念、特性以及如何利用它进行实际开发。 1. ...