This application demonstrate how to generate response in different content type using ActFramework including
- JSON
- XML
- YAML
- csv
- excel file types (xls, xlsx)
To start in dev mode:
cd /path/to/a/app
mvn clean compile act:run
To start in prod mode:
cd /path/to/a/app
mvn clean package
cd target/dist
tar xzf *.tgz
./run
Once you started you can navigate browser to http://localhost:5460
, there
you should be able to see the home page of the application:
What this app trying to demonstrate is to show how to create an Excel sheet of a list of model entities, specifically in this demo, a list of employees.
@Data
public class Employee {
enum Grade {
E06, E07, E08, E09, E10, E11
}
@Label("工号")
public String id;
@Label("名")
public String firstName;
@Label("姓")
public String lastName;
@Label("级别")
public Grade grade;
}
Note:
-
There is a
@Label
annotation on top of properties ofEmployee
, they will be used to render the column header ofcsv
and excel files; Note that JSON, XML and YAML file does not favor@Label
annotation. -
In the app there is a TestDataGenerator class which is used to generate a random list of Employee records.
// By using `@TemplateContext` we make it easy to specify where to locate
// the template file to render the response.
// If the template context is not specified, then the default template dir
// will be <package-names>/<ClassName>, e.g. for this specific `EmployeeService`
// class, the default template context is
// `{template-root}/demo/resp_type/EmployeeService`, where the `{template-root}`
// is the template engine id, e.g. `rythm`, `excel` which is used in this
// application.
@TemplateContext("/")
public class EmployeeService {
@LoadCollection(TestDataGenerator.class)
private List<Employee> employees;
@GetAction("template")
public List<Employee> template(ActionContext context) {
// we need to manually set the download file name here
// otherwise it will be default to `template.xxx`
context.downloadFileName("employees");
return employees;
}
@GetAction
@PropertySpec(cli = "id, firstName, lastName, grade")
@Command(value = "employees", help = "list all employees")
public List<Employee> employees() {
return employees;
}
}
In this service there is an employee list injected with annotation
@LoadCollection
, which get fed with random employee list generated by
TestDataGenerator
class.
There are two request handler methods (endpoints) defined in the service class:
- employees() - returns the employee list on
GET /
request - template() - returns the employee list on
GET /template
request
The HTML template resources/rythm/employees.html
is used
to render response for request with Accept=text/html
header, which is the
home page when we navigate browser to http://localhost:5460
.
In the page we have 2 major parts:
- A group of links
- Employee list table
The employee table renders all employees in the employees
list injected
into EmployeeService
instance
The links are for getting employee list in different data presentation:
/?_accept=json
- view employee list in JSON/?_accept=xml
- view employee list in XML/?_accept=yaml
- view employee list in YAML/?_accept=htmltable
- view employee list in built-in HTML table/?_accept=csv
- download employee list in CSV file/?_accept=xls
- download employee list in xls file/?_accept=xlsx
- download employee list in xlsx file/template?_accept=xls
- download employee list in xls file - rendered with predefined template/template?_accept=xlsx
- download employee list in xlsx file - rendered with predefined template
It is quite obvious that we are using _accept
query parameter to specify the expected
content type, which overwrite the Accept
HTTP header. While ActFramework detect the
specified Accept
content-type, it generate the corresponding response accordingly.
There are two excel templates defined in resources/excel/
folder:
- template.xls - for xls file generation
- template.xlsx - for xlsx file generation
Both of them are defined using JXLS templating engine:
These templates will be used to service request sent to /template
an it
could easily see the rendered excel file are different from request sent to
/
which is rendered directly into excel file without template.
The direct rendered excel file
The template rendered excel file
This demo app shows
- How to generate response in different content types
- How to generate excel file directly
- How to generate excel file via JXLS template
- How to use
_accept
query parameter to overwriteAccept
header of incoming request