The following steps need to be performed to get yourself a project
ready to play around with. We will go here with the classic
approach of creating a war packaged maven project that is
configured via a web.xml and gets tested via the tomcat7-maven-plugin.
Even though we explain this here step by step, if you want to just
get something to start with, just copy and modify the invesdwin-nowicket-examples-war
project. As an alternative invesdwin-nowicket-examples-guide
is also worth a look since it contains the code for this
documentation website and is using spring-boot. Next we are going
through how invesdwin-nowicket-examples-war
was created. All in all you will notice that this is not much
different from setting up a pure Wicket project.
The image below shows what the
final directory layout looks like so you can compare while setting
everything up.
Final Directory Layout
4.1) Maven Setup
First install a current version of Maven and create a pom.xml
to get the required dependencies and to be able to package and run
the war project. Read the comments that are included for
explanations.
4.2) Servlet Setup
Next create a web.xml in
src/main/webapp/WEB-INF/
to register your implementation of the NoWicket servlet filter and
map the error pages to nice looking ones provided by the framework
(which you can customize or replace later).
The NoWicket servlet filter implementation is very simple.
It just needs a reference to your NoWicket application config for
providing the ignorePaths feature that is needed when integrating
tools like Guacamole
which do not play well behind a Wicket filter.
package de.invesdwin.nowicket.examples.war;
import de.invesdwin.nowicket.application.IWebApplicationConfig;
import de.invesdwin.nowicket.application.filter.AWicketFilter;
public class ExampleWicketFilter extends AWicketFilter {
@Override
protected IWebApplicationConfig newConfig() {
return new ExampleWebApplicationConfig();
}
}
The NoWicket web application implementation ia similarly
simple. It also only needs a reference to the NoWicket application
config and a set of base packages for which the @MountPath
annotation should be scanned for.
package de.invesdwin.nowicket.examples.war;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import de.invesdwin.nowicket.application.IWebApplicationConfig;
import de.invesdwin.nowicket.application.filter.AWebApplication;
public class ExampleWebApplication extends AWebApplication {
// also referenced in ExampleMarkupGenerator
public static final Set<String> BASE_PACKAGE = Collections
.unmodifiableSet(new HashSet<String>(Arrays.asList("de.invesdwin.nowicket.examples.war")));
@Override
protected IWebApplicationConfig newConfig() {
return new ExampleWebApplicationConfig();
}
@Override
public Set<String> getClasspathBasePackages() {
return BASE_PACKAGE;
}
}
The NoWicket application config implementation only has to
specify the home page. You can optionally override more methods to
do all the customizations discussed in the previous chapters.
package de.invesdwin.nowicket.examples.war;
import org.apache.wicket.markup.html.WebPage;
import de.invesdwin.nowicket.application.WebApplicationConfigSupport;
import de.invesdwin.nowicket.examples.war.page.HomePage;
public class ExampleWebApplicationConfig extends WebApplicationConfigSupport {
@Override
public Class<? extends WebPage> getHomePage() {
return HomePage.class;
}
}
4.3) Markup Generator Setup
The NoWicket markup generator implementation just needs a
reference to the base packages to know where to scan for the
@GeneratedMarkup annotation. You could also override more methods
to change the input/output folders.
package de.invesdwin.nowicket.examples.war;
import java.util.Set;
import de.invesdwin.nowicket.generated.markup.AAnnotatedGeneratedMarkup;
public class ExampleMarkupGenerator extends AAnnotatedGeneratedMarkup {
public static void main(final String[] args) {
new ExampleMarkupGenerator().generate();
}
@Override
protected Set<String> getClasspathBasePackages() {
return ExampleWebApplication.BASE_PACKAGE;
}
}
4.4) Home Page Setup
The home page will be demonstrated as a hello world example. For
this you will need a model implementation for which the
markup should be generated. Here we implement Serializable since it
is the minimum required for Wicket, otherwise it is recommended to
extend AValueObject.
package de.invesdwin.nowicket.examples.war.page;
import java.io.Serializable;
import de.invesdwin.nowicket.generated.markup.annotation.GeneratedMarkup;
@GeneratedMarkup
public class Home implements Serializable {
public String getHello() {
return "NoWicket!";
}
}
Next we tell the markup generator to generate markup for a page
implementation by writing a class for it. Here we provide our
standard two constructors. We could also customize the navbar and
other things that were discussed in the previous chapters, but this
should better be done in an application specific base page that
extends AWebPage. To keep this example as minimal as possible, we
omit that here.
package de.invesdwin.nowicket.examples.war.page;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.wicketstuff.annotation.mount.MountPath;
import de.invesdwin.nowicket.application.AWebPage;
import de.invesdwin.nowicket.generated.binding.GeneratedBinding;
@MountPath("home")
public class HomePage extends AWebPage {
// constructor for bookmarkable link
public HomePage() {
this(Model.of(new Home()));
}
// constructor for model redirects
public HomePage(final IModel<Home> model) {
super(model);
new GeneratedBinding(this).bind();
}
}
4.5) Running It
Now you can run your ExampleMarkupGenerator. It will produce a HomePage.html
file like this:
And it will also generate a HomePage.properties file like
this:
hello=Hello
With everything in place now, you could run your project via Maven
with
mvn tomcat7:run
and access the website at http://localhost:8080.
4.6) Apache Server Reverse Proxy Configuration
If you want to embed/deploy your Wicket application behind an Apache Server
as a Reverse
Proxy (under the same context path between the java web server and
apache2), you can use the following server configuration:
# enable required modules with: "a2enmod proxy proxy_html proxy_http proxy_connect substitute headers rewrite"
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPreserveHost On
RewriteEngine On
<Location /app/>
Order allow,deny
Allow from all
ProxyPass http://example.com:8080/app/ flushpackets=on
ProxyPassReverse http://example.com:8080/app/
RewriteCond %{REQUEST_URI} ^/app/wicket/websocket [NC,OR]
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://example.com:8080%{REQUEST_URI} [P,QSA,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule .* http://example.com:8080%{REQUEST_URI} [P,QSA,L]
SetOutputFilter proxy-html
ProxyHTMLDoctype "<!DOCTYPE HTML>"
ProxyHTMLURLMap http://example.com:8080/app/ /app/
AddOutputFilterByType SUBSTITUTE text/html
AddOutputFilterByType SUBSTITUTE text/css
AddOutputFilterByType SUBSTITUTE text/js
Substitute "s|http://example.com:8080/app/|https://example.com/app/|ni"
RequestHeader unset Accept-Encoding
</Location>
#also put this into the default site for port 80:
RewriteEngine On
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
4.7) Nginx Server Reverse Proxy Configuration
If you want to embed/deploy your Wicket application behind an Nginx as a Reverse
Proxy (under the same context path between the java web server and
apache2), you can use the following server configuration:
location /app/ {
proxy_pass http://example.com:8080/app/;
proxy_redirect http://example.com:8080/app/ https://example.com/app/;
proxy_redirect http:// https://;
sub_filter "http://example.com:8080/app/" "https://example.com/app/";
sub_filter_once off;
sub_filter_types text/html;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Host $host;
}
Replace
example.com
with your domain,
8080
with the port of your Wicket application is running on and
app
with the path you want to make the application available under.
With this you can make the application available in a web presence
at port
80
which is more firewall friendly. Also you can reuse the SSL
configuration of the Apache Server without having to configure it
in Java (if not, just replace https above with http). The
application can then be accessed at http://example.com/app/ (or
what you changed it to).