#{extends '../main.html'/}# #{set title:'Webpieces QuickStart'/}# #{set tab:'management'/}# #{renderTagArgs 'docHome.html'/}# #{renderTagArgs 'quickStartList.html'/}#
Last updated: May 13th, 2020
A very simple tutorial, that will just help you to learn the Webpieces library with the famous ‘Hello World’ example.
We have split the tutorial into several parts. Each part will introduce more complex features, and provide everything that a real project needs: validation, error handling, an automated test suite.
Webpieces requires that you have a working installation of jdk11 or greater. We do not require intellij or eclipse but highly recommend one of those as your editors.
We will assume you already have knowledge of Java and Web development(especially HTML, CSS). However, you don't need to have any knowledge of JEE components except a little knowledge in JPA can help. Webpieces is a 'full stack' Java framework.
A solid understanding of one of these two things can help
Hah!!! Since Webpieces webserver is a library, there is no installation as you just depend on it like a normal maven artifact! However, because we don't want everyone that uses webpieces to have to create all the build files that builds a production server, we supply a createProject script that can be run. It generates a project with gradle build files that work out of the box along with a main Server class that you can modify to your heart's desire. Obviously, you could completely swap out the build system if you desire. I will warn you however though, some systems like maven are rigid and you may start pulling your hair out
To start, download the zip that can create a shell project for you that uses the webpieces library following these steps
At this point, your build should have been successful and all tests are passing as we provide some example tests. Next, we want to create a production release in the form of a zip file with the logging config, html files, and jar files.
Here, you will hit the main webpieces webpage with examples that you can click through and use tweak/copy, etc. Eventually, you will just delete all the example code. Next, when you unzipped the zip file, you may have seen 4 directories. Now, if you look there are 6 directories which are
Next, view the section in the README on github on Eclipse Setup or Intellij Setup.
We mine as well do all the examples while the development server is running so shutdown the previous production server (ctrl-C). Follow the instructions for your IDE setup above. Then start the DevelopmentServer.java and keep it running. Also, while it's running, you can view these instructions at http://localhost:8080/@documentation
There is built in documentation at http://localhost:8080/@documentation when running the development server. The production server above does not have this so you will want to run the development server in intellij or eclipse. This is because the documentation plugin is only installed on the development server. You could install it on the production server if you really wanted to(and just make sure to uninstall from the dev server so there is not a conflict of both installing the same plugin)
Now, that you have the beginnings of a webpieces webapp, let's add a new RouteModule. In the project helloworld-all/helloworld/src/main/java/org.webpieces.helloworld/web, create a package called "myapp" where we will put all the helloworld code. In that package, create a java file called MyRouteId.java like so:
package org.webpieces.helloworld.web.myapp;
import org.webpieces.router.api.routes.RouteId;
public enum MyRouteId implements RouteId {
HELLO_WORLD
}
This is where we will put all the RouteIds for this package and for this RouteModule. Notice that the enum must extend RouteId as webpieces only knows about RouteId and not your specific enum. Next, let's use the RouteId and create a RouteModule class in the same myapp package called "MyMainRoutes" with a single route to our new webpage.
package org.webpieces.helloworld.web.myapp;
import org.webpieces.ctx.api.HttpMethod;
import org.webpieces.router.api.routes.Port;
import org.webpieces.router.api.routes.Routes;
import org.webpieces.router.api.routebldr.DomainRouteBuilder;
import org.webpieces.router.api.routebldr.RouteBuilder;
public class MyMainRoutes implements Routes {
@Override
public void configure(DomainRouteBuilder bldr) {
RouteBuilder b = bldr.getAllDomainsRouteBuilder();
b.addRoute(Port.BOTH, HttpMethod.GET, "/helloworld", "MyMainController.helloWorld", MyRouteId.HELLO_WORLD);
}
}
Here, we are saying when the browser calls any of these urls that end up on our server, webpieces will invoke MyMainController.helloWorld. This won't work just YET!. We need to implement controller first
Notice we used the getAllDomainsRouteBuilder which means these routes apply to all domains EXCEPT domains created with bldr.getDomainScopedRouteBuilder(String domain) which is a more advanced topic. If you have DNS domainX.com and domainY.com all pointing to your ip with this server, then domainX.com/hello and domainY.com/hello end up calling the same controller. Now that we defined a route and a Controller and method to invoke, we should create the Controller and name it "MyMainController."
package org.webpieces.helloworld.web.myapp;
import javax.inject.Singleton;
import org.webpieces.router.api.controller.actions.Action;
import org.webpieces.router.api.controller.actions.Actions;
@Singleton
public class MyMainController {
public Action helloWorld() {
return Actions.renderThis();
}
}
Lastly, Actions.renderThis() informs webpieces to render the html file with the same name as the method helloWorld so next create a file called helloWorld.html in the same myapp directory as the Controller
*[
Hello World
]*
Finally, the one last step is we need to tell webpieces about this RouteModule that we created. Inside the class ProdServerMeta.java (org.webpieces.helloworld.base), modify it to ADD the line "new MyMainRoutes()" to the list of RouteModules already defined. Your new getRouteModules method should look like so (the addition in bold):
*[@Override
public List getRouteModules() {
return Lists.newArrayList(
new LoginRoutes("/org/webpieces/helloworld/web/login/AppLoginController", "/secure/.*", "password"),
new CrudRoutes(),
new AjaxCrudRoutes(),
new JsonRoutes(),
new MyMainRoutes()
);
}]*
A big note is that all the modules here should be deleted except for LoginRoutes in your production application as they are all examples. While LoginRoutes is an example as well, you most likely want a way to login so you would keep the LoginRoutes module.
Finally, boot up your DevelopmentServer.java main class and open a browser and go to http://localhost:8080/helloworld or go to https://localhost:8443/helloworld to showcase both http and https traffic.
Congratulations on your first webpieces page -- next we will make our html a bit more dynamic.
Next Dynamic Helloworld *{When you start up DevelopmentServer.java, most changes to your web application will not require a restart. Because webpieces is a library, however, changes to the 3 classes that startup webpieces would require a restart and they are
YOU own these classes now to modify to your heart's content. Any changes to these classes or classes that these depend on would require a development server restart to see the changes. Luckily, these classes pretty much do not really need to ever be touched.
Looking closer at Server.java, you will notice 3 different configurations
Each config object configures that piece of the webserver making it easier to trace what different configurations do as well as keep each piece separate from each other.
We have a firm belief that nearly all properties should be in the database and not on the filesystem including configuration properties. We generate Server.java such that you could modify it and put any properties you like on the filesystem but we advise against 99% of properties there as typically you want property file changes to go through your test team rather than someone getting on a production server and tweaking a property. Of course, the 1 property that must be a command line argument or a property is the database connection such that your server can exist in multiple environments like development, staging, and production with different database connections.
To make it simpler for all components/plugins to read/write properties into a database, an interface SimpleStorage.java is provided. The generated application implements this interface connecting it to hibernate but you could change it to connect to some noSQL database or whatever else you would like.
NOTE: In the future, we want to add a bean plugin that exposes MBeans to a web gui for you and also saves changes to the database thereby eliminating the need for property files for basically everything. It would do the following for you...
This automatically managed way of doing properties is preferred over using property files
The main bootstrap file that webpieces webserver reads in is {yourproject}-all/{yourproject}/src/main/resources/appmeta.txt for production mode and {yourproject}-all/{yourproject}/src/main/resources/appmeta-dev.txt for Development mode. This file boostraps your web application by telling us your meta file.
If you look closely, you will notice the appmeta-dev.txt contains DeveloperMeta.java and in that file, he just re-uses all the production meta stuff as well as adding 2 plugins that are only in the development server. After all, we don't want to expose a SQL GUI nor webpieces documentation on our production website.
Next, looking at {yourproject}Meta.java file, you will notice it is broken down into 3 main components
I won't go in depth on plugins at this point but just note that plugins can be another fully contained web application with it's own guice modules, route modules, controllers, and html pages. This allows you to plugin full webapplications into your webapplication. It's what we use for all the backend plugins that could be removed if you desire a really thin lightweight server
}*