wicket-spring-boot
wicket-spring-boot copied to clipboard
Spring Boot starter for Apache Wicket
= Wicket autoconfiguration with Spring Boot
Current release version:
- 3.1.x - http://wicket.apache.org/[Wicket 9.x] with Spring Boot 2.6.1 - Branch master
- 3.0.x - http://wicket.apache.org/[Wicket 9.x] with Spring Boot 2.1 - Branch master (deprecated)
- 2.1.x - http://wicket.apache.org/[Wicket 8.x] with Spring Boot 2 - Branch wicket-8
- 2.0.x - http://wicket.apache.org/[Wicket 8.x] with Spring Boot 1 - Branch wicket-8
- 1.x.x - http://wicket.apache.org/[Wicket 7.x] with Spring Boot 1 - Branch wicket-7
NOTE: http://search.maven.org/#search|ga|1|com.giffing.wicket.spring.boot
NOTE: Example projects: https://github.com/MarcGiffing/wicket-spring-boot-examples
- <
> - <<getting_started>>
- <<how_does_it_work>>
- <<spring_profile_dev_configuration>>
- <
> - <
> - <<war_deployment>>
[[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.
- Core Features
** 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.
[source,xml]
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
[source,java]
@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
[source,java]
@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
- WicketBootStandardWebApplication - Without Security
- WicketBootSecuredWebApplication - With Security - You'll need a security provider like <
>
[source,java]
@Component public class WicketWebApplication extends WicketBootSecuredWebApplication { @Override protected void init() { super.init(); } }
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.
[source,xml]
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:
[source,xml]
[[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:
[source,java]
@ConfigurationProperties(prefix = AnnotatedMountScannerProperties.PROPERTY_PREFIX) public class AnnotatedMountScannerProperties { public static final String PROPERTY_PREFIX = "wicket.stuff.annotationscan"; /** * @see AnnotatedMountScannerConfig */ private boolean enabled = true;
/**
* An alternative package name for scanning for mount path if the
* WicketApplication should not used as the root scan package
*/
private String packagename;
This property file can be imported in the configuration class AnnotatedMountScannerConfig.
[source,java]
/**
- Auto configuration for the {@link AnnotatedMountScanner}.
- It uses the user defined {@link WebApplication} as the default package scan
- root directory.
- Enables annotate mount scanner if the following two condition matches:
-
- The {@link AnnotatedMountScanner} is in the classpath.
-
- The property {@link AnnotatedMountScannerProperties#PROPERTY_PREFIX}
- .enabled is true (default = true)
- @author Marc Giffing
*/ @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;
@Override
public void init(WebApplication webApplication) {
String packagename = webApplication.getClass().getPackage().getName();
if (prop.getPackagename() != null) {
packagename = prop.getPackagename();
}
new AnnotatedMountScanner().scanPackage(packagename).mount(webApplication);
}
}
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.
[source,java]
public class WicketBootWebApplication extends AuthenticatedWebApplication { @Autowired(required = false) private List<WicketApplicationInitConfiguration> configurations = new ArrayList<>(); @Override protected void init() { super.init(); for (WicketApplicationInitConfiguration configuration : configurations) { configuration.init(this); } } }
[[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].
include::wicket-spring-boot-starter/src/main/resources/application-development.yml[] [source,yml]
wicket: core: settings: general: configuration-type: development debug: enabled: true component-use-check: true development-utilities-enabled: true stuff: htmlcompressor: enabled: false features: removeComments: false removeMultiSpaces: false removeIntertagSpaces: false removeQuotes: false compressJavaScript: false compressCss: false simpleDoctype: false removeScriptAttributes: false removeStyleAttributes: false removeLinkAttributes: false removeFormAttributes: false removeInputAttributes: false simpleBooleanAttributes: false removeJavaScriptProtocol: false removeHttpProtocol: false removeHttpsProtocol: false preserveLineBreaks: false external: development: devutils: statelesschecker: enabled: true interceptor: enable-live-sessions-page: true diskstorebrowser: enabled: true wicketsource: enabled: true
[[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.
[source,java]
@ApplicationInitExtension @ConditionalOnWicket(value=7, range=Range.EQUALS_OR_HIGHER) public ConditionalConfig implements WicketApplicationInitConfiguration{ @Override public void init(WebApplication webApplication) { // configuration option which only apply to Wickets major version 7 or higher } }
[[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 <<how_does_it_work>> to get a deeper knowledge.
- <
> ** DEPLOYMENT-CONFIGURATIONS *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < > *** < >
** 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.
[source,properties]
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
#exception settings 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
#Markup - Settings 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
#RequestLogger - Settings 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
- @WicketHomePage ** A Page marked with this annotation will be configured as the default home page. If multiple WicketHomePage annotation found an exception is thrown.
- @WicketSignInPage ** A Page marked with this annotation will be configured as the default login page. A security provider like Spring Security is needed. If multiple annotations found an exception is thrown.
- @WicketAccessDeniedPage ** A Page marked with this annotation will be configured as the default access denied page.
- @WicketInternalErrorPage ** A Page marked with this annotation will be configured as the default internal error page.
- @WicketExpiredPage
** A Page marked with this annotation will be configured as the default expired page.
[[extension-spring-security]] === Spring Security
To use Spring Security you have to extend WicketBootSecuredWebApplication instead of WicketBootWebApplication.
[source,properties]
wicket.external.spring.security=true #
[source,xml]
[[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.
[source,properties]
wicket.external.websocket=true # enables WebSocket support - dependency required (move documentation to seperated section)
[source,xml]
[[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.
[source,properties]
wicket.external.beanvalidation.enabled=true # enabled by default if bean validation project is present
[source,xml]
[[extension-core-csrf-prevention]] === Core - Prevention of CSRF Attacks
[source,properties]
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
#TODO: There are some configuration options which should be added
[[extension-webjars]] === Webjars
https://github.com/l0rdn1kk0n/wicket-webjars
[source,properties]
wicket.external.webjars.enabled=true
[source,xml]
[[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]
[source,xml]
[source,properties]
wicket.stuff.annotationscan.enabled=true wicket.stuff.annotationscan.packagename=
[[extension-wicketstuff-htmlcompressor]] === Wicketstuff - htmlcompressor
See https://github.com/wicketstuff/core/wiki/Htmlcompressor[documentation]
[source,xml]
[source,properties]
wicket.stuff.htmlcompressor.enabled=true wicket.stuff.htmlcompressor.features.*=
[[extension-core-serializer-deflated]] === Core - serializer-deflated
[source,properties]
wicket.core.serializer.deflated.enabled=false # has to be explicit enabled. deflates the outputstream, reducing page store size by up to a factor 8 at a price of about 2-20ms
[[extension-wicketstuff-serializer-fast2]] === Wicketstuff - serializer-fast2
See https://github.com/wicketstuff/core/wiki/FastSerializer2[documentation]
[source,xml]
[source,properties]
wicket.stuff.serializer.fast2.enabled=true
[[extension-wicketstuff-serializer-kryo2]] === Wicketstuff - serializer-kryo2
See https://github.com/wicketstuff/core/wiki/Kryo-Serializer[documentation]
[source,xml]
[source,properties]
wicket.stuff.serializer.fast2.enabled=true
[[extension-wicketstuff-restannotations]] === Wicketstuff - restannotations
See https://github.com/wicketstuff/core/tree/master/wicketstuff-restannotations-parent[documentation]
[source,xml]
[source,properties]
wicket.stuff.restannotations.enabled=true wicket.stuff.restannotations.packagename= # the package name to scan for project specific annotations
[[extension-general-debugsettings]] === General - debugsettings
Wicket provides some debug settings which could be
[source,properties]
wicket.core.settings.debug.enabled=false wicket.core.settings.debug.developmentUtilitiesEnabled=true # Enables all of the panels and pages, etc, from wicket-devutils package. wicket.core.settings.debug.ajaxDebugModeEnabled=true # if true: wicket-ajax-debug.js is added to header wicket.core.settings.debug.componentUseCheck=true wicket.core.settings.debug.outputMarkupContainerClassName=false wicket.core.settings.debug.componentPathAttributeName=
[[extension-datastore]] == Datastore
[[extension-datastore-httpsession]] === Datastore HttpSession
[source,properties]
wicket.core.datastore.httpsession.enabled=false wicket.core.datastore.httpsession.pagesNumber=20 # the maximum number of pages the data store can hold
[[extension-datastore-cassandra]] === Datastore cassandra
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[source,properties]
wicket.stuff.datastore.cassandra.enabled=true wicket.stuff.datastore.cassandra.contact-points= #comma-separated list wicket.stuff.datastore.cassandra.table-name=pagestore wicket.stuff.datastore.cassandra.keyspace-name=wicket wicket.stuff.datastore.cassandra.record-ttl=30 wicket.stuff.datastore.cassandra.record-ttl-unit=minutes wicket.stuff.datastore.cassandra.session-size=2 wicket.stuff.datastore.cassandra.session-unit=megabytes
[source,xml]
[[extension-datastore-hazelcast]] === Datastore hazelcast
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[source,properties]
wicket.stuff.datastore.hazelcast.enabled=true wicket.stuff.datastore.hazelcast.session-size=2L wicket.stuff.datastore.hazelcast.session-unit=megabytes
[source,xml]
[[extension-datastore-memcached]] === Datastore memcached
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[source,properties]
wicket.stuff.datastore.memcached.enabled=true wicket.stuff.datastore.memcached.session-size=2L wicket.stuff.datastore.memcached.session-unit=megabytes wicket.stuff.datastore.memcached.expiration-time=30 wicket.stuff.datastore.memcached.port=11211 wicket.stuff.datastore.memcached.server-names= wicket.stuff.datastore.memcached.shutdown-timeout=30 wicket.stuff.datastore.memcached.shutdown-timeout-unit=minutes
[source,xml]
[[extension-datastore-redis]] === Datastore redis
See https://github.com/wicketstuff/core/wiki/DataStores[Documentation]
[source,properties]
wicket.stuff.datastore.redis.enabled=true wicket.stuff.datastore.redis.session-size=2L wicket.stuff.datastore.redis.session-unit=megabytes wicket.stuff.datastore.redis.expiration-time=30 wicket.stuff.datastore.redis.port=11211 wicket.stuff.datastore.redis.server-names= wicket.stuff.datastore.redis.shutdown-timeout=30 wicket.stuff.datastore.redis.shutdown-timeout-unit=minutes
[source,xml]
[[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]
[source,properties]
wicket.stuff.monitoring.jamon.enabled=true wicket.stuff.monitoring.jamon.include-source-name-in-monitor-label=true wicket.stuff.monitoring.jamon.mountPage=/monitoring/jamon # the url to which the statistic page is mounted
[source,xml]
NOTE: JAMon includes hazelcast to gather statistics. You may need to disable the datastore hazelcast support: <
[[extension-devutils]] === Devutils
[source,xml]
[[extension-devutils-diskstorebrowser]] ==== Devutils - diskstorebrowser
[source,properties]
wicket.external.development.devutils.diskstorebrowser.enabled=false wicket.external.development.devutils.diskstorebrowser.mountPage=devutils/diskstore/browser
[[extension-devutils-inspector]] ==== Devutils - inspector
[source,properties]
wicket.external.development.devutils.diskstorebrowser.enabled=false wicket.external.development.devutils.diskstorebrowser.mountPage=devutils/diskstore/browser
[[extension-devutils-statelesschecker]] ==== Devutils - statelesschecker
[source,properties]
wicket.external.development.devutils.interceptor.enableLiveSessionsPage=false wicket.external.development.devutils.interceptor.liveSessionPageMount=devutils/inspector/live-session-page
[[extension-wicketsource]] === Wicket-Source
See https://github.com/jennybrown8/wicket-source/wiki[documentation]
[source,xml]
[source,properties]
wicket.external.development.wicketsource.enabled=false
[[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.
[source,xml]
[[war_deployment]] == Configure as WAR for deploy on Servlet Container
#115
To run the application as a war file in the Servlet Container like Tomcat you have to do the following steps.
- Set the packaging to war in your build system (maven, gradle)
- Mark the spring-boot-starter-tomcat dependency as provided
- Use the Spring provided plugins to repackage the project
- Extend from SpringBootServletInitializer
** Here you can optionally set configurations which only apply when deployed as a war in a Servlet Container
** http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-maven-packaging[maven] ** http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#build-tool-plugins-gradle-repackage-configuration[gradle]
[source,java]
@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).