I am happy to share my recent Open Source project ActFramework here.
So some events about ActFramework:
- Three years ago I was thinking of creating an new Java MVC framework.
- About one year ago I start working on ActFramework.
- Three months ago I start using ActFramework to rewrite a commercial project which was written in Jersey originally, and the result is great. We have reduced the lines of code from 8900 to 4500 while keeping the same feature set and functionality.
- Last Wednesday I presented ActFramework in the first Sydney JVM meetup at FinTech hub in 2016.
In this blog I will brief major features of ActFramework
Controller
@GetAction("/")
public void home() {
}
@PostAction("/customer")
public String createCustomer(Customer customer) {
customerDao.save(customer);
return customer.getId();
}
@PutAction("/customer/{id}/email")
public void updateCustomerEmail(String id, String email) {
Customer customer = customerDao.findById(id);
notFoundIfNull(customer);
customer.setEmail(email);
customerDao.save(customer);
}
See the documentation for more about controller and action methods
Routing
There are two ways to create routing table:
- Through
resources/routes
fileGET /customer/{id} any.pkg.CustomerController.get POST /customer any.pkg.CustomerController.create ...
- Through action method annoation as shown above
See the documentation for more about routing
Model and DAO
ActFramework support Morphia for MongoDB and Ebean for SQL. You can declare your Model class as a POJO with proper annotation.
MorphiaDao
and EbeanDao
are provided to support find/save/delete entities:@Entity
public class Customer {
@Id
private ObjectId id;
private String name;
public void setId(ObjectId id) {
this.id = id;
}
public ObjectId getId() {
return this.id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
public class CustomerController {
@Inject MorphiaDao<Customer> dao;
@GetAction("/customer")
public Iterable<Customer> list() {
return dao.findAll();
}
@GetAction("/customer/{id}")
public Customer get(String id) {
return dao.findById(new ObjectId(id));
}
@PostAction("/customer")
public String create(Customer customer) {
dao.save(customer);
return customer.getId().toString();
}
}
See the documentation on more about Model and DAO
Jobs and scheduler
public class MyClass {
@Every("2s")
public void jobA() {
...
}
@InvokedAfter("MyClass.jobA")
public void runAfterJobA() {
...
}
@OnAppStart
public void jobB() {
...
}
...
}
See the documentation for more about jobs and scheduling
Events
public class CustomerController {
@Inject
EbeanDao dao;
@Inject
EventBus eventBus;
public void create(Customer customer) {
dao.save(customer);
eventBus.trigger("new-customer", customer);
}
}
@Mailer
public class PostOffice extends Mailer.Util {
@On("new-customer")
@Async
public void sendWelcomeLetter(Customer customer) {
to(customer.getEmail());
from("noreply@mycom.com");
send(customer);
}
}
See the documentation for more about events
Interceptors
public class App {
@Before(except = "login,logout")
public void authenticate(ActionContext context) {
if (!context.session().contains("username")) {
if (context.isAjax()) {
throw new UnAuthorized();
} else {
redirect("/login");
}
}
}
@Action(value = "/login" methods = {H.Method.GET, H.Method.POST})
public void login() {
...
}
}
@With(App.class)
public class CustomerController() {
...
}
See the documentation for more about interceptors
More features
Comparing to PlayFramework v1.x
Project layout
- Play use specific project layout
- Act use standard maven project layout. See The anatomy of an Act application
Controller and action methods
- Play controller must extends
play.mvc.Controller
. Action method must bevoid
andstatic
- Act controller does not need to extend any class. However extending
act.controller.Controller.Util
makes it easy to userenderXxx
methods. Act action method does not need to bestatic
. Act action method can return object
Routing
- Play use routes file to define routing entry
- Act use routes file plus method annotation to define routing entry
Templates
- Play use groovy as default template engine
- Act use Rythm as default template engine
- Both framework support plugin different template engine
Models and DAO
- Play's DAO methods are built into
play.db.Model
. Sub class get the data access capablitity via byte code enhancement - Act framework does not require Model class to extend any class. ActFramework inject default DAO implemenation to host class (e.g. a Controller, or Mailer) to provide DAO capablity
SQL Database access
- Play use JPA/Hibernate to achieve SQL database access
- Act use Ebean to achieve SQL database access
MongoDB access
- Play use PlayMoprhia plugin (created by author of ActFramework) to access mongodb
- Act use Morphia plugin to access mongodb
Jobs
- Play job must be put into a class that extends
play.jobs.Job
. Each class implement one job logic - Act job is just a
public void
method without parameters. The class hosting job method does not require to extend any class
Events
- Play does not provide event mechanism
- Act provide very expressive and easy to use event binding and dispatching mechanism
Asynchronous http request handling
- Play can suspend http request handling and resume when async operation ended
- Act does not provide async http request handling at the moment (v0.1.1-SNAPSHOT)
i18n
- Play provides an easy to use i18n support
- Act support i18n through Rythm's
i18n()
extension. Act's i18n support needs to be refined and improved
Cache
- Play provides
Cache
utility class with static method. See document[https://www.playframework.com/documentation/1.4.x/cache] - Rythm use
org.osgl.cache.CacheService
to provide cache utilities
Sending email
- Play provides a controller style mailer utility
- Act also provides a very easy to use mailing solution
Testing
- Play provides a very descent testing facilities
- Act relies on standard junit to implement application testing. Act also provides a specific act-test to support application's Model test. At the moment Morphia support is provided.
Security
- Play provides limited security support. However there are some third party plugins like Deadbolt and play-aaa (created by author of ActFramework)
- Act provides authentication/role based authorization/accounting via act-aaa
Modules and depedencies
- Play applied it's specific way to manage modules and dependencies
- Act relies on maven to manage dependencies and modules
Database evolutions
- Play provides database evolution support
- Act does not provide specific support on database evolution.
logging
- Play provides a
Logger
class with static logging method. See document - Act does not have any specific class for logging. Developer could use any Logging solution (e.g. Log4J) in their application. However developer are also free to use
App.logger
to create log items.
Deployment
- Play can be deployed as a fullstack application or as a war file in JEE application servers
- Act support only fullstack application deployment at the moment (0.1.1-SNAPSHOT)