javalightning
This is an experimental web framework by me, the documentation for my own use.
Hello World
create a bundle with the following Activator for hello world.
public class Activator extends LightningActivator {
public Activator() {
// all routes for this bundle are accessible under /hello
super("hello");
}
@Override
protected void init(BundleContext context) throws Exception {
addPageService(builder -> {
// return a simple String result on requests for /hello
builder.newIdentityRouteGet("", () -> new PageController() {
@Override
public void invoke(ResponseBuilder response) throws Exception {
response.setRenderer(new StringRenderer("hello world! " + new Date()));
}
});
// allow access (true) regardless of context (e.g. ip, sessionId) on all routes
builder.setSecurity(new PageSecurity((route, ctx) -> true));
});
}
}
mapping HTTP requests to controllers
routes
mapping a HTTP method to a relative path under bundle root
builder.newRoute(routeId).map(path, RouteType.GET, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.POST, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.HEAD, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.PUT, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.DELETE, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.TRACE, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.OPTIONS, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.CONNECT, () -> new PageController() { ... });
mapping with wildcard in path (run PageController for all pages starting with [bundle-name]/foo/)
builder.newRoute(routeId).mapGet("foo/*", () -> new PageController() {
shorthand: map GET:/[bundle-name]/[path] to controller
builder.newIdentityRouteGet(path, () -> new PageController() { ... }
shorthand: map POST:/[bundle-name] to controller
builder.newIdentityRoutePost(path, () -> new PageController() { ... }
shorthand: map both GET and POST requests to the same controller
builder.newIdentityRouteGetAndPost(path, () -> new PageController() { ... }
associated controller
public class StringRendererController implements PageController {
@Override
public void invoke(ResponseBuilder builder) {
builder.setRenderer(new StringRenderer("Hello world!<br/>" + new Date()));
}
}
dependency injection
public class BeanController implements PageController {
@Bean
private HttpServletRequest request;
@Bean
private HttpServletResponse response;
@Bean
private HttpSession session;
@Bean
private RequestContext context;
@Bean
private Parameters parameters;
@Bean
private BeanInjector injector;
@Bean
private ServiceCollection<MyServiceType> osgiService;
@Override
public void invoke(ResponseBuilder rb) {
....
basic renderers
render a simple String in the response
new StringRenderer("...")
render a (freemarker) template as response
new TemplateRenderer(template)
create file download response (renderer)
new DownloadRenderer(new File("/path/to/file.txt"))
new DownloadRenderer(new FileDownload("download-name.txt", new File("/path/to/file.txt")))
new InputStreamRenderer(new FileInputStream("/path/to/file.txt"))
redirects
performing an internal redirect from PageController
public void invoke(ResponseBuilder builder) {
throw new InternalRedirectException(new UrlMapping("internal", "/mvc/prefix/example"));
}
performing an external redirect from PageController
public void invoke(ResponseBuilder builder) {
throw new ExternalRedirectException(new UrlMapping("github", "http://www.github.com"));
}
template engine (freemarker)
template hello world
public class Activator extends LightningActivator {
public Activator() {
super("hello");
}
@Override
protected void init(BundleContext context) throws Exception {
addTemplateSource();
addPageService(builder -> {
builder.newIdentityRouteGet("template", () -> new AbstractTemplateController() {
@Override
public void invoke() throws Exception {
model.put("key", "value");
// template will be loaded from this bundles classpath /hello/template.ftlh
setTemplate("/hello/template.ftlh");
}
});
builder.setSecurity(new PageSecurity((route, ctx) -> true));
});
}
}
making (freemarker) templates available in the activator
addTemplateSource();
exposing a global variable to all templates
addTemplateSource(new TemplateGlobal() {
@Override
public String getName() {
return "key";
}
@Override
public Object getObject() {
return "global";
}
});
referencing the global in the (freemarker) template
${globals.get("date")?time}
referencing a HTTP parameter in the template
${parameter.get('key')}
${parameter.get('key', 'default')}
getting the remote url of a route
${lightning.getRemotePath('service', 'id')}
rules file syntax
blocking (rules processed in order of occurence)
block requests matching a path pattern
block
pattern=robots.txt
allow all requests
allow
remapping external paths to internal paths
map favicon to /web/favicon.ico internally
map
path=favicon.ico
to=/web/favicon.ico
regex search and replace
map
pattern=/replaceme~
regex=^/replaceme
to=/newpath
patterns
specific path
pattern=robots.txt
separate multiple patterns with commas
pattern=*.php, *.gch
block admin and admin/*
pattern=admin~
osgi properties for configuring the framework (defaults after '=')
remote URL (used in redirects)
com.eriklievaart.javalightning.bundle.host=localhost:8000
com.eriklievaart.javalightning.bundle.https=false
a rules file can be used to block urls and to redirect requested paths (e.g. favicon) to different internal paths
com.eriklievaart.javalightning.bundle.rules=[defaults to preset rules]
redirect incoming requests on root to home path
com.eriklievaart.javalightning.bundle.servlet_prefix=
hide stack traces and render a custom error page instead, takes a redirect path (e.g. /oops)
com.eriklievaart.javalightning.bundle.exception.redirect=
specify directory containing freemarker templates (for real time editing during development)
com.eriklievaart.javalightning.freemarker.path=/home/eazy/Development/git/hufront/main/resources
com.eriklievaart.javalightning.freemarker.timeout=60000
email propertiescom.eriklievaart.javalightning.email.host=localhost
logging propertiescom.eriklievaart.osgi.logging.console=true
com.eriklievaart.osgi.logging.file=
com.eriklievaart.osgi.logging.file.level=TRACE
log to an osgi service
com.eriklievaart.osgi.logging.service=true
com.eriklievaart.osgi.logging.date=
example logging format
com.eriklievaart.osgi.logging.date=yyyy-MM-dd HH:mm:ss
antastic config
src/main/config/antastic.properties
src/main/config/dependencies.txt
javalightning-bundle @local @snapshot
javalightning-email @local @snapshot
javalightning-freemarker @local @snapshot
osgi-status @local @snapshot
osgi-toolkit @local @snapshot
toolkit-ant @local @snapshot
toolkit-bean @local @snapshot
toolkit-convert @local @snapshot
toolkit-io @local @snapshot
toolkit-lang @local @snapshot
toolkit-logging @local @snapshot
toolkit-reflect @local @snapshot
toolkit-vfs @local @snapshot
freemarker org.freemarker 2.3.28
org.apache.felix.http.api org.apache.felix 3.0.0
org.apache.felix.http.jetty org.apache.felix 4.0.6
org.apache.felix.http.servlet-api org.apache.felix 1.1.2