= Wicket autoconfiguration with Spring Boot
Current release version:
NOTE: http://search.maven.org/#search|ga|1|com.giffing.wicket.spring.boot
NOTE: Example projects: https://github.com/MarcGiffing/wicket-spring-boot-examples
[[introduction]] == Introduction
https://dzone.com/articles/enhance-wicket-with-spring-boot by Andrea Del Bene
This project makes it easy to create a new Wicket projects with a minimum of configuration effort. It uses Spring Boot to autoconfigure Wickets core and its extension (related projects like wicketstuff, beanvalidation...) with an reasonable default value which can be overridden over property files.
Configures an embedded Servlet Container by default (Spring Boot Feature).
Autoconfiguration of the needed link:wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/web/WicketWebInitializer.java[Wicket Servlet filters].
Autoconfiguration for Spring/Spring-Security and dependency injection support with @SpringBean.
Autoconfiguration of Wicket <
[[getting_started]] == Getting started
To get started you have to create a new Maven Project (or another preferred dependency/build-management tool) and add the wicket-spring-boot-starter dependency to your configuration.
Beside the Maven dependency configuration we need the following steps to do
. Create a class which is marked with @SpringBootApplication - see http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-using-springbootapplication-annotation[Springs documentation] . Create your HomePage class (with HTML) which will me marked with @WicketHomePage
@SpringBootApplication public class WicketApplication { public static void main(String[] args) throws Exception { new SpringApplicationBuilder() .sources(WicketApplication.class) .run(args); }
}
@WicketHomePage public class HomePage extends WebPage { }
You contentThats all! When you execute the main method you will get a fully working and configured Wicket application. An embedded Tomcat is automatically started.
In a usal Wicket application you would like to provide custom configuration in Wickets WebApplication init() method. You could create your own 'extension' by creating a bean which implements WicketApplicationInitConfiguration
@ApplicationInitExtension public class YouExtensionConif implements WicketApplicationInitConfiguration {
@Override public void init(WebApplication webApplication) { // your custom configuration }
If this configuration is not enough and you want to override special methods of Wickets WebApplication class you have to create a bean which extends one of the following two classes
The custom WicketWebApplication is automatically picked up instead of the default provided one. You can also override the getHomePage method() if you don't want to use the special @WicketHomePage annotations to mark the home page.
To package the application as an executable jar you have to add the spring-boot-maven-plugin.
Resource files (html, css, js, ...) are not copied to the target folder if placed in the src/main/java folder. You have to tell Maven to copy these files:
[[how_does_it_work]] == How does it work?
To fully understand how http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-developing-auto-configuration[Spring Boots autconfiguration] and in general Spring Boot works you should read the excellent http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/[documentation] from this fantastic http://projects.spring.io/spring-boot/[project].
As an an example we will look to the AnnotatedMountScanner configuration. The https://github.com/wicketstuff/core/wiki/Annotation[annotated mount scanner] is an project which supports bookmarkable URLs configured by annotations on WebPage classes. If you have this '@MountPath("login")' annotation on a WebPage then the Page is mounted to 'http://localhost/login'.
In this project each configuration is separated in two classes to configure this particular feature/extension. The extension consists of a property and a configuration class.
The property class holds properties to configure the specific feature. In the AnnotatedMountScannerProperties class we found two properties:
@ConfigurationProperties(prefix = AnnotatedMountScannerProperties.PROPERTY_PREFIX) public class AnnotatedMountScannerProperties { public static final String PROPERTY_PREFIX = "wicket.stuff.annotationscan"; /**
@see AnnotatedMountScannerConfig */ private boolean enabled = true;
/**
This property file can be imported in the configuration class AnnotatedMountScannerConfig.
/**
*/ @ApplicationInitExtension @ConditionalOnProperty(prefix = AnnotatedMountScannerProperties.PROPERTY_PREFIX, value = "enabled", matchIfMissing = true) @ConditionalOnClass(value = org.wicketstuff.annotation.scan.AnnotatedMountScanner.class) @EnableConfigurationProperties({ AnnotatedMountScannerProperties.class }) public class AnnotatedMountScannerConfig implements WicketApplicationInitConfiguration {
@Autowired private AnnotatedMountScannerProperties prop;
If all conditions on the AnnotatedMountScannerConfig matches the configuration class is configured as a spring bean. All Spring beans which implements the interface WicketApplicationInitConfiguration will be injected as a list in the default WicketBootWebApplication class.
In the WicketBootWebApplication class we iterate in Wickets init method over the list and call on each the init method to configure the application.
[[spring_profile_dev_configuration]] === Spring profile configuration
The Wicket Spring Boot Starter project ships with a default development configuration. It can be activated by activating the 'development' Spring profile in the main class or over external JVM/Maven arguments.
The default configuration can be overridden with a custom property file. See Spring Boots reference documentation http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config[here].
[[custom-conditions]] == Custom conditions
This section lists custom conditional configuration like Spring Boot ones.
=== @ConditionalOnWicket
With the ConditionOnWicket annotation you can check that configuration classes only apply on a specific Wicket major version. If some functionality is only available on Wicket 7 you can use this annotation.
[[extension]] == Extensions
The following section describes the current extensions and the
required dependencies. An extension is a custom labeling in this project
which is used to auto-configure a specific part of an Wicket application. An extension
may require an external dependency or is using Wickets core features. See section
<
DEVELOPMENT-CONFIGURATIONS
** <
[[extension-general]] === General
Wicket can be started in DEVELOPMENT and DEPLOYMENT mode. You can change the configuration type over the following property configuration. The given property is automatically mapped to Wickets ConfigurationType enumeration.
wicket.core.settings.general.configuration-type=development # development/deployment(default)
wicket.web.servlet.filter-mapping-param=/ wicket.web.servlet.dispatcher-types=request, error, async # request, error, async, include, forward wicket.web.servlet.init-parameters.= # map<string,string> - configuration support for additional servlet init parameters
wicket.core.settings.exceptions.thread-dump-strategy=thread_holding_lock wicket.core.settings.exceptions.error-handling-strategy-during-ajax-requests=redirect_to_error_page
wicket.core.settings.requestcycle.render-strategy=redirect-to-buffer # redirect-to-buffer / one-pass-render / redirect-to-render wicket.core.settings.requestcycle.buffer-response=true wicket.core.settings.requestcycle.gather-extended-browser-info=false wicket.core.settings.requestcycle.response-request-encoding=UTF-8 wicket.core.settings.requestcycle.timeout-size=1 wicket.core.settings.requestcycle.timeout-unit=minutes wicket.core.settings.requestcycle.exception-retry-count=10
wicket.core.settings.markup.default-markup-encoding=UTF-8 # if null it uses the system default wicket.core.settings.markup.automatic-linking=false wicket.core.settings.markup.compress-whitespace=false wicket.core.settings.markup.strip-comments=false wicket.core.settings.markup.strip-wicket-tags=true wicket.core.settings.markup.throw-exception-on-missing-xml-declaration=false
wicket.core.settings.requestlogger.enabled=false wicket.core.settings.requestlogger.record-session-size wicket.core.settings.requestlogger.requests-window-size
wicket.core.requestmapper.cryptmapper.enabled=false # URL encryption support
wicket.core.settings.pagestore.enabled=false # enables custom store settings wicket.core.settings.pagestore.session-size=2 wicket.core.settings.pagestore.session-unit=megabytes wicket.core.settings.pagestore.asynchronous= # overrides wickets default value only when set wicket.core.settings.pagestore.asynchronous-queue-capacity= # overrides wickets default value only when set wicket.core.settings.pagestore.file-store-folder= # overrides wickets default value only when set wicket.core.settings.pagestore.inmemory-cache-size= # overrides wickets default value only when set
If you insert e.g. developmentx you will get a startup error: [listing] Field error in object 'wicket' on field 'configurationType': rejected value [developmentx]; codes [typeMismatch.wicket.configurationType
==== Special Annotations
[[extension-spring-security]] === Spring Security
This starter detects automatically Spring Security if the Spring Boot Starter Security dependency is added. Internally the WicketBootSecuredWebApplication is used instead of the WicketBootStandardWebApplication class.
If you wan't to disable the Spring Security configuration for Wicket use the following property.
[[extension-wicket-websocket]] === Wicket Native WebSockets
https://ci.apache.org/projects/wicket/guide/7.x/guide/single.html#nativewebsockets[Documentation]
This project provides an auto configuration support for native WebSockets. If the required dependencies are in the classpath a JavaxWebSocketFilter servlet filter is configured instead of the default WicketFilter.
To simplify the usage of sending WebSocket messages a class named WebSocketMessageBroadcaster is automatically registered as a spring bean. You can inject the class anywhere with @SpringBean and use the 'send' method to send WebSocket messages.
[[extension-beanvalidation]] === Bean validation
Wicket support for JSR 303 Bean validation. See Wickets user guide https://ci.apache.org/projects/wicket/guide/7.x/guide/single.html[Validation with JSR 303]
To enable Wickets bean validation you have to add the wicket-bean-validation dependency to your project. It will automatically configured and can be used in the project.
[[extension-core-csrf-prevention]] === Core - Prevention of CSRF Attacks
wicket.core.csrf.enabled=true wicket.core.csrf.no-origin-action=allow wicket.core.csrf.conflicting-origin-action=abort wicket.core.csrf.error-code=400 wicket.core.csrf.error-message=Origin does not correspond to request wicket.core.csrf.accepted-origins[0]=domain.name.tld # Just the domain name, no protocol wicket.core.csrf.accepted-origins[1]=other-domain.name.tld # Add more origins by increasing the index
[[extension-webjars]] === Webjars
https://github.com/l0rdn1kk0n/wicket-webjars
[[extension-wicketstuff-annotationscan]] === Wicketstuff - annotationscan
Use wicketstuff-annotation to use Java Annotations and class path searching to mount your Wicket pages.
See https://github.com/wicketstuff/core/wiki/Annotation[documentation]
[[extension-wicketstuff-htmlcompressor]] === Wicketstuff - htmlcompressor
See https://github.com/wicketstuff/core/wiki/Htmlcompressor[documentation]
[[extension-core-serializer-deflated]] === Core - serializer-deflated
[[extension-wicketstuff-serializer-fast2]] === Wicketstuff - serializer-fast2
See https://github.com/wicketstuff/core/wiki/FastSerializer2[documentation]
[[extension-wicketstuff-serializer-kryo2]] === Wicketstuff - serializer-kryo2
See https://github.com/wicketstuff/core/wiki/Kryo-Serializer[documentation]
[[extension-wicketstuff-restannotations]] === Wicketstuff - restannotations
See https://github.com/wicketstuff/core/tree/master/wicketstuff-restannotations-parent[documentation]
[[extension-general-debugsettings]] === General - debugsettings
Wicket provides some debug settings which could be
[[extension-datastore]] == Datastore
[[extension-datastore-httpsession]] === Datastore HttpSession
[[extension-datastore-cassandra]] === Datastore cassandra
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[[extension-datastore-hazelcast]] === Datastore hazelcast
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[[extension-datastore-memcached]] === Datastore memcached
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[[extension-datastore-redis]] === Datastore redis
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[[extension-wicketstuff-jamon]] === Wicketstuff - JAMon
Used to monitor page requests. Provides a statistic page.
See https://github.com/wicketstuff/core/blob/master/jamon-parent/[Github]
NOTE: JAMon includes hazelcast to gather statistics. You may need to disable the datastore hazelcast support: <
[[extension-devutils]] === Devutils
[[extension-devutils-diskstorebrowser]] ==== Devutils - diskstorebrowser
[[extension-devutils-inspector]] ==== Devutils - inspector
[[extension-devutils-statelesschecker]] ==== Devutils - statelesschecker
[[extension-wicketsource]] === Wicket-Source
See https://github.com/jennybrown8/wicket-source/wiki[documentation]
[[extension-springboot-devtools]] ==== Spring Boot - DevTools
See https://spring.io/blog/2015/06/17/devtools-in-spring-boot-1-3[Spring Boot DevTools]
The project tries to improve the development-time experience when working with Spring Boot. There is a problem with Wickets default and other serializer (fast2, kryo2...). See https://github.com/MarcGiffing/wicket-spring-boot/issues/29[Issue 29] If the spring-boot-devtools dependency is in the classpath a link:/wicket-spring-boot-starter/src/main/java/com/giffing/wicket/spring/boot/starter/configuration/extensions/external/development/springboot/devtools/SpringDevToolsSerializer.java[special Spring serializer] will be activated.
All other serializer will only be activated if the Spring Boot DevTools dependency is not in the classpath.
[[war_deployment]] == Configure as WAR for deploy on Servlet Container
To run the application as a war file in the Servlet Container like Tomcat you have to do the following steps.
@SpringBootApplication public class WicketApplication extends SpringBootServletInitializer {
//Can be used while developing public static void main(String[] args) throws Exception { new SpringApplicationBuilder() .sources(WicketApplication.class) .run(args); }
//Executed when deployed as a WAR in a Servlet container. @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { builder.properties( WebSocketWicketWebInitializerAutoConfiguration.REGISTER_SERVER_ENDPOINT_ENABLED + "=false" ); return super.configure( builder ); }
If you already extend from a Wicket specific class you can create a separated class which extends from SpringBootServletInitializer (https://github.com/MarcGiffing/wicket-spring-boot/issues/115#issuecomment-311712298).