В данной статье приведен классический пример приложения 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
Для проекта вам понадобятся следующие библиотеки:
- cglib-nodep-2.1_3.jar
- commons-logging-1.1.1.jar
- log4j-1.2.13.jar
- slf4j-api-1.4.2.jar
- slf4j-log4j12-1.4.2.jar
- spring-2.5.6.jar
- wicket-1.4-rc2.jar
- wicket-ioc-1.4-rc2.jar
- 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>