An open API service indexing awesome lists of open source software.

https://github.com/wizzardo/webery


https://github.com/wizzardo/webery

Last synced: 21 days ago
JSON representation

Awesome Lists containing this project

README

          

[![CircleCI](https://circleci.com/gh/wizzardo/webery.svg?style=svg)](https://circleci.com/gh/wizzardo/webery)
[![codecov](https://codecov.io/gh/wizzardo/webery/branch/master/graph/badge.svg)](https://codecov.io/gh/wizzardo/webery)

Java HTTP-server
=========

server based on my [epoll](https://github.com/wizzardo/epoll)

```java
HttpServer server = new HttpServer<>(8080);
server.getUrlMapping()
.append("/", (request, response) -> response.setBody("It's alive!"));
server.start();
```

---

## Framework

- [Installation](#installation)
- [Initialization](#initialization)
- [Building and running](#building-and-running)
- [Url-mapping](#url-mapping)
- [Dependency injection](#di)
- [Configuration](#configuration)
- [Template engine](#template-engine)
- [i18n](#i18n)
- [Taglib](#taglib)

---

#### Installation [↑](#up)

##### Gradle
```
build.gradle
```
```groovy
apply plugin: 'java'
apply plugin: 'application'

repositories {
jcenter()
mavenCentral()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots/"
}
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

version = '0.1'

mainClassName = "com.example.MyWebApp"

dependencies {
compile 'com.wizzardo:http:0.2+'
}

//create a single Jar with all dependencies
task fatJar(type: Jar) {
manifest {
attributes(
"Main-Class": mainClassName
)
}
baseName = project.name + '-all'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
```

---

#### Initialization [↑](#up)

```java
import com.wizzardo.http.framework.Controller;
import com.wizzardo.http.framework.Environment;
import com.wizzardo.http.framework.WebApplication;
import com.wizzardo.http.framework.template.Renderer;

public class MyWebApp {

static class AppController extends Controller {
public Renderer index() {
return renderString("It's alive!");
}
}

public static void main(String[] args) {
WebApplication application = new WebApplication(args);
application.onSetup(app -> {
app.getUrlMapping()
.append("/", AppController.class, "index");
});
application.start();
}
}
```

---

#### Building and running [↑](#up)

```bash
./gradlew fatJar
java -jar build/libs/MyWebApp-all.jar env=prod profiles.active=profile_A,profile_B
```

---

#### Url-mapping [↑](#up)

Controllers and actions could be mapped to static paths or
to something dynamic with variables and wildcards
```java
urlMapping
.append("/index", AppController.class, "index")
.append("/books/$id?", AppController.class, "books") // 'id' - is optional
.append("/optionals/$foo?/$bar?", AppController.class, "optionals") // 'foo' and 'bar' - are optional
.append("/${foo}-${bar}", AppController.class, "fooBar")
.append("/any/*", AppController.class, "any")
.append("*.html", AppController.class, "html")
.append("/upload", AppController.class, "upload", Request.Method.POST) // only POST method is allowed
;
```

---

#### Dependency injection [↑](#up)
Framework supports simple dependency injections, to make class or interface injectable simple annotate it with @Injectable.

There are several scopes for it:
- SINGLETON - one instance per jvm, default
- PROTOTYPE - new instance for every injection
- SESSION - one instance per user-session
- REQUEST - new instance every request
- THREAD_LOCAL - one instance per thread

Controllers are stateful so their scope is PROTOTYPE, Services - SINGLETON.
```java
static class AppController extends Controller {
AppService appService;

public Renderer index() {
return renderString(appService.getMessage());
}
}
```

To make dependency injection work with implicit dependencies, you need to specify package for scan:
```java
application.onSetup(app -> {
DependencyFactory.get(ResourceTools.class)
.addClasspathFilter(className -> className.startsWith("com.example"));
});
```

##### Raw usage of DI
```java
DependencyFactory.get().register(CustomBean.class, new SingletonDependency<>(CustomBean.class));
CustomBean bean = DependencyFactory.get(CustomBean.class);
```

---

#### Configuration [↑](#up)

```
src/main/resources/Config.groovy
```
```groovy
server {
host = '0.0.0.0'
port = 8080
ioWorkersCount = 1
ttl = 5 * 60 * 1000
context = 'myApp'
basicAuth {
username = 'user'
password = 'pass'
token = true
tokenTTL = 7 * 24 * 60 * 60 * 1000l
tokenized { // creates mapping with path '/resourceName/*' and respective name for static resources available by token
resourceName = 'path/to/resource'
}
}

ssl {
cert = '/etc/ssl/certs/hostname.crt'
key = '/etc/ssl/private/hostname.key'
}

session {
ttl = 30 * 60
}

resources {
path = 'public' // load static files from resource folder 'public'
mapping = '/static'
cache = {
enabled = true
gzip = true
ttl = -1L
memoryLimit = 32 * 1024 * 1024L
maxFileSize = 5 * 1024 * 1024L
}
}
debugOutput = false // dump of all requests and responses to System.out
}
//this configuration will be only applied for certain environment
environments {
dev {
custom.key = true
}
prod {
custom.key = false
server.ioWorkersCount = 4
}
}

//this configuration will be only applied for certain profiles
profiles {
profile_A {
environments {
dev {
value = 'value_dev_A'
}
prod {
value = 'value_prod_A'
}
}
}
profile_B {
value = 'value_B'
}
}
```
Configuration stored in Holders:
```java
boolean key = Holders.getConfig().config("custom").get("key", defaulValue);
```
or it can be mapped to pojo and injected to other objects:
```java
public class CustomConfig implements Configuration {
public boolean key;

@Override
public String prefix() {
return "custom";
}
}
```

Configuration is loaded in this order:
- Default configuration and manifest
- Config.groovy
- External configuration (```webApp.onLoadConfiguration(app -> app.loadConfig("MyCustomConfig.groovy"))```)
- Profiles and environments
- OS environment variables (```System.getenv()```)
- Java System properties (```System.getProperties()```)
- Command line arguments

---

#### Template engine [↑](#up)

This framework has it's own template engine, inspired and based on Groovy Server Pages (GSP)
```java
static class AppController extends Controller {
public Renderer index() {
model().append("name", params().get("name", "%user name%"));
return renderView();
}
}
```
Engine will try to render html from template 'resources/views/controller_name/view_name.gsp', by default 'view_name' is 'action_name':
```
src/main/resources/views/app/index.gsp
```
```html


Hello


Hello, ${name}!

```

---

#### i18n [↑](#up)

```java
MessageBundle ms = DependencyFactory.get(MessageBundle.class);

//load message bundle from resources/i18n/messages.properties
//and lazy load any other language, for example messages_en.properties, messages_fr.properties
ms.load("messages");

String foo = ms.get("foo");
String fooDe = ms.get(Locale.GERMANY,"foo");

//it also supports templates
//foobar = {0} {1}
String foobar = ms.get("foobar", "foo", "bar"); // "foo bar"

```

---

#### Taglib [↑](#up)

- [checkBox](#checkBox)
- [collect](#collect)
- [createLink](#createLink)
- [each](#each)
- [else](#else)
- [elseif](#elseif)
- [form](#form)
- [formatBoolean](#formatBoolean)
- [hiddenField](#hiddenField)
- [if](#if)
- [join](#join)
- [layoutBody](#layoutBody)
- [layoutHead](#layoutHead)
- [layoutTitle](#layoutTitle)
- [link](#link)
- [message](#message)
- [passwordField](#passwordField)
- [radio](#radio)
- [resource](#resource)
- [set](#set)
- [textArea](#textArea)
- [textField](#textField)
- [while](#while)

---

##### checkBox [↑](#taglib)
Generates a checkbox form field.

###### Template:
```html

```
###### Result:
```html

```
###### Attributes
- name - The name of the checkbox
- value (optional) - The value of the checkbox
- checked (optional) - Expression if evaluates to true sets to checkbox to checked

---

##### collect [↑](#taglib)
Iterate over each element of the specified collection transforming the result using the expression in the closure

###### Template:
```html



$it



```

###### Action:
```java
model().append("books", Arrays.asList(new Book("Book one"), new Book("Book two")))
```

###### Book.java:
```java
public class Book {
public final String title;

public Book(String title) {
this.title = title;
}
}
```

###### Result:
```html


Book one


Book two



```

###### Attributes
- in - The object to iterative over
- expr - A expression

---

##### createLink [↑](#taglib)
Creates a link that can be used where necessary (for example in an href, JavaScript, Ajax call etc.)

Controller:
```java
public class BookController extends Controller {

public Renderer list() {
return renderString("list of books");
}

public Renderer show() {
return renderString("some book");
}
}
```
url-mapping:
```java
app.getUrlMapping()
.append("/book/list", BookController.class, "list")
.append("/book/$id", BookController.class, "show");
```

###### Template:
```html
// generates link
link

// generates "/book/show?foo=bar&boo=far"

// generates "/book/list"

// generates "http://localhost:8080/book/list"

// generates "http://ya.ru/book/list"

```

###### Attributes:
- action (optional) - The name of the action to use in the link; if not specified the current action will be linked
- controller (optional) - The name of the controller to use in the link; if not specified the current controller will be linked
- id (optional) - The id to use in the link
- fragment (optional) - The link fragment (often called anchor tag) to use
- mapping (optional) - The named URL mapping to use, default mapping = controllerName + '.' + actionName
- params (optional) - A Map of request parameters
- absolute (optional) - If true will prefix the link target address with the value of the server.host property from config
- base (optional) - Sets the prefix to be added to the link target address, typically an absolute server URL. This overrides the behaviour of the absolute property if both are specified.

---

##### each [↑](#taglib)
Iterate over each element of the specified collection.

###### Template:
```html



$i



```
###### Result:
```html

1


2


3



```

###### Attributes:
- in - The collection to iterate over
- status (optional) - The name of a variable to store the iteration index in. Starts with 0 and increments for each iteration.
- var (optional) - The name of the item, defaults to "it".

---

##### else [↑](#taglib)
The logical else tag

###### Template:
```html

never happen

Hello, world!

```

###### Result:
```html
Hello, world!
```

---

##### elseif [↑](#taglib)
The logical elseif tag

###### Template:
```html

never happen

Hello, world!

```

###### Result:
```html
Hello, world!
```

###### Attributes:
- test - The expression to test

---

##### form [↑](#taglib)
Creates a form, extends 'createLink' tag

---

##### formatBoolean [↑](#taglib)
Outputs the given boolean as the specified text label.

###### Template:
```html

```

###### Result:
```html
true
True!
```

###### Attributes:
- boolean - Variable to evaluate
- true (optional) - Output if value is true. If not specified, 'boolean.true' or 'default.boolean.true' is looked up from the Message Source
- false (optional) - Output if value is false. If not specified, 'boolean.false' or 'default.boolean.false' is looked up from the Message Source

---

##### hiddenField [↑](#taglib)
Creates a input of type 'hidden' (a hidden field).

###### Template:
```html

```

###### Result:
```html

```

###### Attributes:
- name - The name of the text field
- value (optional) - The value of the text field

---

##### if [↑](#taglib)
The logical if tag to switch on an expression.

###### Template:
```html

Hello!

```

###### Result:
```html
Hello!
```

###### Attributes:
- test - The expression to test

---

##### join [↑](#taglib)
Concatenate the toString() representation of each item in this collection with the given separator.

###### Template:
```html

```

###### Result:
```html
Hello, World!
```

###### Attributes:
- in - The collection to iterate over
- delimiter (optional) - The value of the delimiter to use during the join. Default: ', '

---

##### layoutBody [↑](#taglib)
Used in layouts to output the contents of the body tag of the decorated page.

###### Decorated page template:
```html





Page to be decorated

```
###### Layout template `views/layouts/myLayout.gsp`:
```html





```

###### Result:
```html





Page to be decorated

```

---

##### layoutHead [↑](#taglib)
Used in layouts to render the contents of the head tag of the decorated page

###### Decorated page template:
```html





Page to be decorated

```
###### Layout template `views/layouts/myLayout.gsp`:
```html





```

###### Result:
```html





Page to be decorated

```

---

##### layoutTitle [↑](#taglib)
Used in layouts to render the contents of the title tag of the decorated page

###### Decorated page template:
```html



Hello World!


Page to be decorated

```
###### Layout template `views/layouts/myLayout.gsp`:
```html






```

###### Result:
```html


Hello World!



Page to be decorated

```

---

##### link [↑](#taglib)
Creates an html anchor tag with the href set based on the specified parameters. Extends 'createLink' tag.

###### Template:
```html
link
```

###### Result:
```html
link
```

###### Attributes:
[same as in createLink tag](#createLink)

---

##### message [↑](#taglib)
Resolves a message from the given code.

###### Template:
```html
// test.message.1.args = test message: {0}

```

###### Result:
```html
test message: one
```

###### Attributes:
- code - The code to resolve the message for.
- default (optional) - The default message to output if the error or code cannot be found in messages.properties.
- args (optional) - A list of argument values to apply to the message when code is used.
- locale (optional) Override Locale to use instead of the one detected

---

##### passwordField [↑](#taglib)
Creates a input of type 'password' (a password field). An implicit "id" attribute is given the same value as name unless you explicitly specify one.

###### Template:
```html

```

###### Result:
```html

```

###### Attributes:
- name - The name of the password field
- value - The value of the password field

---

##### radio [↑](#taglib)
Generates a radio button

###### Template:
```html

```

###### Result:
```html

```

###### Attributes:
- value - The value of the radio button
- name - The name of the radio button
- checked - boolean to indicate that the radio button should be checked

---

##### resource [↑](#taglib)
Generates a link (URI) string for static resources. Can be used in an href, JavaScript, Ajax call, etc.

###### Template:
```html

```

###### Result:
```html

```

###### Attributes:
- dir - the name of the directory containing the resource
- file - the name of the resource file
- tag - the name of the html tag
- url - the name of the attribute for the url
- absolute - If true will prefix the link target address with the value of the `host` property from Config.groovy.

---

##### set [↑](#taglib)
Sets the value of a variable accessible with the GSP page.

###### Template:
```html

Current i = ${i}


```

###### Result:
```html

Current i = 0


Current i = 1


Current i = 2


```

###### Attributes:
- var - The name of the variable
- value - The initial value

---

##### textArea [↑](#taglib)
Creates a HTML text area element. An implicit "id" attribute is given the same value as name unless you explicitly specify one.

###### Template:
```html

```

###### Result:
```html

myValue
>
```

###### Attributes:
- name - The name of the text area
- value - The initial text to display in the text area. By default the text area will be empty.

---

##### textField [↑](#taglib)
Creates a input of type 'text' (a text field). An implicit "id" attribute is given the same value as the name unless you explicitly specify one.

###### Template:
```html

```

###### Result:
```html

```

###### Attributes:
- name - The name of the text field
- value - The initial text to display in the text field. By default the text field will be empty.

---

##### while [↑](#taglib)
Executes a condition in a loop until the condition returns false.

###### Template:
```html

Current i = ${i++}

```

###### Result:
```html

Current i = 0


Current i = 1


Current i = 2


```

###### Attributes:
- test - The conditional expression