В данной статье приведен классический пример приложения Hello World!, в котором используются технологии Apache Wicket и Spring Framework. На Apache Wicket реализуется уроверь представления, а Spring Framework используется для реализации уровня бизнес-логики.

Так же для управления зависимостями в данном примере будем использовать Apache Maven 2, а для сборки будет использоваться Apache Ant, из которого будет вызываться Maven.

К вачестве среды разработки используется Eclipse 3.4 с установленным плагином m2eclipse для работы с Maven и управления зависимостями.

Итак, приступим!

Создаем Java-проект в Eclipse. Поскольку я для сборки проекта использую Ant, то я не использую архетипы Maven для создания структуры проекта.

Я использую следующую структуру проекта:

build
src
tools
- build.xml
webapp
- spring
- – spring-context.xml
- WEB-INF
- – web.xml

Для проекта вам понадобятся следующие библиотеки:

  1. cglib-nodep-2.1_3.jar
  2. commons-logging-1.1.1.jar
  3. log4j-1.2.13.jar
  4. slf4j-api-1.4.2.jar
  5. slf4j-log4j12-1.4.2.jar
  6. spring-2.5.6.jar
  7. wicket-1.4-rc2.jar
  8. wicket-ioc-1.4-rc2.jar
  9. wicket-spring-1.4-rc2.jar

Ниже представлен pom.xml, в котором прописаны необходимые зависимости:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>ru.nikisoft.samples</groupId>
 <artifactId>HelloSpringWicket</artifactId>

<packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <dependencies>
 <dependency>
 <groupId>org.apache.wicket</groupId>
 <artifactId>wicket</artifactId>
 <version>1.4-rc2</version>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring</artifactId>
 <version>2.5.6</version>
 </dependency>
 <dependency>
 <groupId>org.apache.wicket</groupId>
 <artifactId>wicket-spring</artifactId>
 <version>1.4-rc2</version>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.4.2</version>
 </dependency>
 </dependencies>
</project>

Cоздадим реализацию сервиса, который будем вызывать из Apache Wicket:


package ru.nikisoft.samples.spring;

import org.springframework.stereotype.Service;

@Service(value="helloService")
public class HelloService
{
 public String getMessage()
 {
 return "Hello from Spring Framework!";
 }
}

Вместо описания данного бина в дескрипторе Spring-контекста я использовал аннотацию @Service, а дескриптор контекста в этом случае принимает следующий вид:


<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-2.5.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"

 default-autowire="byName">

 <context:component-scan base-package="ru.nikisoft.samples">
 <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
 </context:component-scan>
</beans>

Любое приложение на Wicket начинается с класса WebApplication:


package ru.nikisoft.samples.wicket;
import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;

public class WicketApplication extends WebApplication
{
 @Override
 protected void init() {
 super.init();
 addComponentInstantiationListener(new SpringComponentInjector(this));  }

 public Class getHomePage()
 {
 return HelloPage.class;
 }
}

Самое интересно заключается в строке addComponentInstantiationListener(new SpringComponentInjector(this)), без которой Spring-бины не будут инжектироваться в классы Wicket.

Ниже приведен код класса для простой страницы, которая будет выводить сообщение полученное из Spring-бина и соответствующая ему HTML страница:


package ru.nikisoft.samples.wicket;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.spring.injection.annot.SpringBean;

import ru.nikisoft.samples.spring.HelloService;

public class HelloPage extends WebPage
{
 @SpringBean(name="helloService")
 private HelloService helloService;

 public HelloPage()
 {
 add(new Label("message", helloService.getMessage()));
 }
}

HTML-страница:


<html>
<body>
<label wicket:id="message"></label>
</body>
</html>

Ant скрипт сборки проекта:


<?xml version="1.0" encoding="utf-8" ?>
<project name="build" default="all" basedir="..">
 <description>Library build file.  This is used to package up project as a jar, if you want to distribute it.</description>

<property name="project.name" value="hello-spring-wicket"/>

<property name="project.lib" value="lib"/>

<property name="project.src" value="src"/>

<property name="project.build" value="build"/> 

<property name="project.target" value="${project.build}/target"/>  

<property name="project.deploy" value="${project.build}/deploy"/>

<property name="project.target.bin" value="${project.target}/bin"/>

<property name="project.target.build" value="${project.target}/build"/>

<property name="project.target.exploded" value="${project.target}/exploded"/>

 <target name="mvn-init" unless="compile.classpath" xmlns:artifact="urn:maven-artifact-ant">
 <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant"
 classpath="maven-ant-tasks-2.0.9.jar"/>
 <condition property="maven.repo.local" value="${maven.repo.local}" else="${user.home}/.m2/repository">
 <isset property="maven.repo.local"/>
 </condition>
 <echo>maven.repo.local=${maven.repo.local}</echo>
 <artifact:localRepository id="local.repository" path="${maven.repo.local}"/>
 <artifact:pom file="pom.xml" id="maven.project"/>
 <artifact:dependencies pathId="compile.classpath" filesetId="compile.fileset" useScope="compile"> 

<pom refid="maven.project"/>
 <localRepository refid="local.repository"/>
 </artifact:dependencies>
 <artifact:dependencies pathId="test.classpath" filesetId="test.fileset" useScope="test"> 

<pom refid="maven.project"/>
 <localRepository refid="local.repository"/>
 </artifact:dependencies>
 <artifact:dependencies pathId="runtime.classpath" filesetId="runtime.fileset" useScope="runtime"> 

<pom refid="maven.project"/>
 <localRepository refid="local.repository"/>
 </artifact:dependencies>
 </target>

 <target name="clean" description="Remove temporary files of previous builds" depends="mvn-init">
 <delete dir="${project.target}"/>
 </target>

 <target name="compile" depends="clean" description="Compile src to bin">
 <mkdir dir="${project.target.bin}" />
 <javac srcdir="${project.src}" destdir="${project.target.bin}" includes="**" debug="on" debuglevel="lines,vars,source" source="1.5">
 <classpath refid="compile.classpath" />
 </javac>
 </target>

 <target name="package" depends="compile" description="Package up the project as a jar">
 <mkdir dir="${project.target}"/>
 <mkdir dir="${project.target.build}"/>

 <jar destfile="${project.target.build}/${project.name}.jar">
 <fileset dir="${project.target.bin}">
 <include name="**/*.*" />
 </fileset>
 <fileset dir="${project.src}">
 <exclude name="**/*.java" />
 </fileset>
 </jar>
 </target>

 <target name="build" depends="package" description="Build all">
 <mkdir dir="${project.target}"/>
 <mkdir dir="${project.target.build}"/>
 <mkdir dir="${project.target.exploded}"/>  

 <copy todir="${project.target.exploded}">
 <fileset dir="webapp" includes="**/*"/>
 </copy>

 <copy todir="${project.target.exploded}/WEB-INF/lib" file="${project.target.build}/${project.name}.jar"/>    

 <copy todir="${project.target.exploded}/WEB-INF/lib" flatten="true">

<path refid="compile.classpath"/>
 </copy>    

 <war destfile="${project.target.build}/${project.name}.war" basedir="${project.target.exploded}"/>
 </target>

 <target name="deploy" depends="build" description="Deploy WAR">
 <mkdir dir="${project.deploy}"/>
 <copy todir="${project.deploy}" file="${project.target.build}/${project.name}.war"/>
 </target>

 <target name="all" depends="deploy" />
</project>

web.xml:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="HelloSpringWicket" version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <display-name>HelloSpringWicket</display-name>

 <listener>

 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

 <context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/spring/spring-context.xml</param-value>
 </context-param>

 <filter>
 <filter-name>HelloWorldApplication</filter-name>
 <filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
 <init-param>

<param-name>applicationClassName</param-name>

<param-value>ru.nikisoft.samples.wicket.WicketApplication</param-value>
 </init-param>
 </filter>
 <filter-mapping>
 <filter-name>HelloWorldApplication</filter-name>
 <url-pattern>/*</url-pattern>
 </filter-mapping>
</web-app>