webery

by wizzardo

wizzardo /webery
141 Stars 10 Forks Last release: Not found MIT License 1.1K Commits 5 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

CircleCI codecov

Java HTTP-server

server based on my epoll

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

Framework


Installation

Gradle
build.gradle
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

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 -&gt; {
        app.getUrlMapping()
                .append("/", AppController.class, "index");
    });
    application.start();
}

}


Building and running

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

Url-mapping

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

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
DependencyFactory.get().register(CustomBean.class, new SingletonDependency<>(CustomBean.class));
CustomBean bean = DependencyFactory.get(CustomBean.class);

Configuration

src/main/resources/Config.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

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/controllername/viewname.gsp', by default 'viewname' is 'actionname':
src/main/resources/views/app/index.gsp
html


  <title>Hello</title>


  Hello, ${name}!


i18n

    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


checkBox

Generates a checkbox form field.

Template:

Result:

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

Iterate over each element of the specified collection transforming the result using the expression in the closure

Template:
$it
Action:
model().append("books", Arrays.asList(new Book("Book one"), new Book("Book two")))
Book.java:
public class Book {
    public final String title;

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

}

Result:
Book one
Book two
Attributes
  • in - The object to iterative over
  • expr - A expression

createLink

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:
// 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

Iterate over each element of the specified collection.

Template:
$i
Result:
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

The logical else tag

Template:
    never happen


    Hello, world!

Result:
    Hello, world!

elseif

The logical elseif tag

Template:
    never happen


    Hello, world!

Result:
    Hello, world!
Attributes:
  • test - The expression to test

form

Creates a form, extends 'createLink' tag


formatBoolean

Outputs the given boolean as the specified text label.

Template:

Result:
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

Creates a input of type 'hidden' (a hidden field).

Template:

Result:

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

if

The logical if tag to switch on an expression.

Template:
    Hello!

Result:
    Hello!
Attributes:
  • test - The expression to test

join

Concatenate the toString() representation of each item in this collection with the given separator.

Template:

Result:
Hello, World!
Attributes:
  • in - The collection to iterate over
  • delimiter (optional) - The value of the delimiter to use during the join. Default: ', '

layoutBody

Used in layouts to output the contents of the body tag of the decorated page.

Decorated page template:
    <meta name="layout" content="myLayout">
    <script src="myscript.js"></script>

Page to be decorated

Layout template
views/layouts/myLayout.gsp
:
    <script src="global.js"></script>
    <layouthead></layouthead>

Result:
    <script src="global.js"></script>
    <script src="myscript.js"></script>

Page to be decorated


layoutHead

Used in layouts to render the contents of the head tag of the decorated page

Decorated page template:
    <meta name="layout" content="myLayout">
    <script src="myscript.js"></script>

Page to be decorated

Layout template
views/layouts/myLayout.gsp
:
    <script src="global.js"></script>
    <layouthead></layouthead>

Result:
    <script src="global.js"></script>
    <script src="myscript.js"></script>

Page to be decorated


layoutTitle

Used in layouts to render the contents of the title tag of the decorated page

Decorated page template:
    <meta name="layout" content="myLayout">
    <title>Hello World!</title>
    <script src="myscript.js"></script>

Page to be decorated

Layout template
views/layouts/myLayout.gsp
:
    <title><layouttitle default="Some Title"></layouttitle></title>
    <script src="global.js"></script>
    <layouthead></layouthead>

Result:
    <title>Hello World!</title>
    <script src="global.js"></script>
    <script src="myscript.js"></script>

Page to be decorated


link

Creates an html anchor tag with the href set based on the specified parameters. Extends 'createLink' tag.

Template:

Result:
link
Attributes:

same as in createLink tag


message

Resolves a message from the given code.

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

Result:
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

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:

Result:

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

radio

Generates a radio button

Template:

Result:

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

Generates a link (URI) string for static resources. Can be used in an href, JavaScript, Ajax call, etc.

Template:


Result:


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

Sets the value of a variable accessible with the GSP page.

Template:
    

Current i = ${i}

Result:
    

Current i = 0

Current i = 1

Current i = 2

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

textArea

Creates a HTML text area element. An implicit "id" attribute is given the same value as name unless you explicitly specify one.

Template:

Result:
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

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:

Result:

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

Executes a condition in a loop until the condition returns false.

Template:
    

Current i = ${i++}

Result:
    

Current i = 0

Current i = 1

Current i = 2

Attributes:
  • test - The conditional expression

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.