You need JDK and Maven to create Act application. An internet connection should be ready for downloading libraries from maven central repository
- JDK (Java Development Kit), version 1.7 and above
- Maven (Project Management Tool), version 3.5 and above
If you already have the JDK and Maven installed you can safely skip the following sections.
You can download JDK from Java official web site
You can download maven from Maven official web site. Follow the instructions to install maven on your operating system
Act use maven to build project. The easiest way to start your Act application is to get a copy of the sample pom file and use it to create the application.
mvn archetype:generate -DgroupId=com.mycom.helloworld -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
After running the above command, your project directory should look like:
.
└── helloworld
├── pom.xml
└── src
├── main
│ └── java
│ └── com
│ └── mycom
│ └── helloworld
│ └── App.java
└── test
└── java
└── com
└── mycom
└── helloworld
└── AppTest.java
Now get a copy of the sample pom file and replace the pom.xml file generated.
Then create a resources dir src/main/resources and put the logback.xml file into the folder.
Note you need to update the pom.xml file and the logback.xml file and ensure the package name inside both file corresponding to your project.
All major IDEs support importing maven project. Here we will use IntelliJ IDEA as an example.
Select File/New/Project from Existing Sources... to launch the import wizard as shown below:
Select the pom.xml file in your generated project and press OK button, then keep clicking on "Next" button till the end of the wizard.
Once the maven project has been imported, you can open it in Intelli IDEA:
Update your App.java
- Provide handler to incoming request by sending back "Hello World!"
- Update
mainmethod to have Act to run this application
package com.mycom.helloworld;
import act.Act;
import org.osgl.mvc.annotation.GetAction;
/**
* Hello world!
*/
public class App {
@GetAction
public String sayHello() {
return "Hello World!";
}
public static void main(String[] args) throws Exception {
Act.start();
}
}Tips to avoid name collision with act.app.App, it's better to refactory your App class and name it to AppEntry. In IDEA, you can press shift-F6 when your cursor in on the App class name to triger the rename refactory process.
Now press ctrl-shift-F10 to run App in intelliJ IDEA:
Go to your browser and open http://localhost:5460
Congratulations! you have created your first Actframework application and view it's effect. Easy, isn't it? But it's not the end of our journey, let's keep moving...
There is no web application that is created to just handle request send to one endpoint. Let's add another action handler in our App.java so it able to handle request sent to /bye endpoint. Here is the code of the new action handler that needs to be added into App.java
@GetAction("/bye")
public String sayBye() {
return "Bye!";
}Once you've done the work, switch to your browser and navigate to http://localhost:5460/bye, you should be able to get:
Tips You do NOT need to restart the application if you need to check the effect of your code changes. ActFramework can sense the source code change and rebuild the application in memory
In a real project, there is just no way for you to return a simple string to the response. In most cases you end up with applying a templating system to render your html response. Act has build in the Rythm support. Now let's enhance our application by creating a template for hello world response.
First update the App.java and change the sayHello method to:
@GetAction
public void sayHello() {
}Then add a rythm template file named sayHello.html for the method. The file needs to be put under /src/main/resources/rythm/com/mycom/helloworld/App directory:
The rule of template locating is:
/src/main/resources/rythm/com/mycom/helloworld/App
-------------------
resource root
rythm
------
Template
engine
id
com/mycom/helloworld/App
---------------------------
Controller class full name
And the file name sayHello.html is the action method name, in our case, the sayHello plus the suffix represent the response format, which in our case, the .html
To make it easier for you to follow up, here is the content of the template file:
<!DOCTYPE html>
<html>
<head>
<title>Hello World App</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>Once you've done the changes, switch back to your browser and navigate to http://localhost:5460, you get the new hello world page:
As an exercise, please apply the same change to the sayBye method.
Now let's add some dynamic to our hello world app. We want to make it able to say hello to anyone by sending request to /?who=anyone, where who is the request parameter name.
Here is the changed sayHello method:
@GetAction
public void sayHello(@DefaultValue("World") String who) {
Controller.Util.render(who);
}Note you need to import Result and Controller to make it compilable:
import act.controller.Controller;
import org.osgl.mvc.result.Result;And the changed sayHello.html file:
<!DOCTYPE html>
@args String who
<html>
<head>
<title>Hello World App</title>
</head>
<body>
<h1>Hello @who!</h1>
</body>
</html>Once you've done the change, go to your browser and navigate to http://localhost:5460?who=Act, you should get the result:
If you were a minimalist like me, you might feel things like Controller.Util.render a little bit annoying, there are two ways to simplify it:
-
Make your controller extend
act.controller.Controller.Utilclass, which is my favorite way to get things done:import act.controller.Controller; ... public class AppEntry extends Controller.Util { @GetAction public void sayHello(@DefaultValue("World") String who) { render(who); } public static void main(String[] args) throws Exception { Act.start("Hello World"); } }
-
In some rare cases your controller may be already extended from other class, then static import is your friend:
import static act.controller.Controller.Util.*; ... public class AppEntry { @GetAction public void sayHello(@DefaultValue("World") String who) { render(who); } public static void main(String[] args) throws Exception { Act.start("Hello World"); } }
In either case, you can write in a more expressive way to render the result.
Act use the standard maven layout to organize the project with a few specific rules. After the first compile, an Act application looks like this:
.
├── pom.xml
├── src
│ ├── main
│ │ ├── java -> Java sources
│ │ │ └── com
│ │ │ └── mycom
│ │ │ └── myprj
│ │ │ ├── Application.java -> application entry
│ │ │ ├── conf -> source code built-in configuration
│ │ │ ├── controller -> controllers
│ │ │ ├── event -> events and event listeners
│ │ │ ├── mail -> mailers
│ │ │ ├── model -> models and data access objects
│ │ │ ├── sys -> system level utilities
│ │ │ └── util -> general utilities
│ │ └── resources -> resource files
│ │ ├── asset -> public assets, can be accessed via "/asset"
│ │ │ ├── css -> CSS files
│ │ │ ├── img -> Image files
│ │ │ └── js -> Javascript files
│ │ ├── conf -> configuration file root
│ │ │ ├── common -> common configurations applied to all profiles
│ │ │ ├── sit -> "sit" profile configurations that overwrite common configurations
│ │ │ └── dev -> "dev" profile configurations that overwrite common configurations
│ │ ├── messages.properties -> message resource files
│ │ ├── routes -> route table file
│ │ └── rythm -> RythmEngine template root
│ │ ├── com
│ │ │ └── mycomp
│ │ │ └── myprj
│ │ │ ├── controller -> templates for controller actions
│ │ │ └── mail -> templates for mailer actions
│ │ └── __global.rythm -> global template utilities
│ └── test
│ ├── java -> unit test java sources
│ │ └── com
│ │ └── mycom
│ │ └── myprj
│ └── resources -> unit test resources
└── target -> maven build target root
├── dist -> where the build dist package stored
└── tmp
└── uploads -> the temporary dir to store the uploaded files
Note, your application might look different from above in that
- the package structure is totally project specific. For example, you might not have a
controllerfolder, instead you haveservicefolder to put in all the RESTful service classes. And your business logic layer might not be organized in onemodelfolder, instead in a different set of packages. In general Act does not define how you organize your java source package, you have complete freedom to do that based on your project needs. - The
commonconfiguration folder is a convention used by Act to look for default configurations. However thesitanddevare the profiles defined by yourself, you are free to give them a different name or add other profiles likeuatandprodetc. It is totally okay if you decide not to define a profile and just usecommonconfiguration. - The
routefile is optional. You can just rely on the annotation based route. However ifroutetable is provided it allows to overwrite the annotation based route definition
In this section you have learned:
- Getting Prerequisites ready
- Generating project skeleton using maven and the sample pom file
- Creating Act application by using
RunApp.startin themainmethod - Adding action handlers
- Using template to render complex response
- Handling request parameter
- The anatomy of an Act application







