8000 GitHub - yinrongping/blade: :rocket: A Simple, Elegant Java Web Framework! website →
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

yinrongping/blade

 
 

Repository files navigation

Based on Java8 + Netty4 to create a lightweight, high-performance, simple and elegant Web framework 😋

Spend 1 hour to learn it to do something interesting, a tool in addition to the other available frameworks.

🐾 Quick Start | 🌚 Documentation | 📗 Guidebook | 💰 Donate | 🇨🇳 简体中文


What Is Blade?

Blade is a pursuit of simple, efficient Web framework, so that JavaWeb development becomes even more powerful, both in performance and flexibility. If you like to try something interesting, I believe you will love it. If you think it's good, you can support it with a star or by donating 😊

Features

  • A new generation MVC framework that doesn't depend on other libraries
  • Get rid of SSH's bloated, modular design
  • Source is less than 500kb, learning it is also simple
  • RESTful-style routing design
  • Template engine support, view development more flexible
  • High performance, 100 concurrent qps 20w/s
  • Run the JAR package to open the web service
  • Streams-style API
  • CSRF and XSS defense
  • Basic Auth and Authorization
  • Supports plug-in extensions
  • Support webjars resources
  • Tasks based on cron expressions
  • Built-in a variety of commonly used middleware
  • Built-in Response output
  • JDK8 +

Overview

» Simplicity: The design is simple, easy to understand and doesn't introduce many layers between you and the standard library. The goal of this project is that the users should be able to understand the whole framework in a single day.
» Elegance: blade supports the RESTful style routing interface, has no invasive interceptors and provides the writing of a DSL grammar.
» Easy deploy: supports maven package jar file running.

Quick Start

Create a basic Maven or Gradle project.

Do not create a webapp project, Blade does not require much trouble.

Run with Maven:

<dependency>
    <groupId>com.hellokaton</groupId>
    <artifactId>blade-core</artifactId>
    <version>2.1.2.RELEASE</version>
</dependency>

or Gradle:

compile 'com.hellokaton:blade-core:2.1.2.RELEASE'

Write the main method and the Hello World:

public static void main(String[] args) {
    Blade.create().get("/", ctx -> ctx.text("Hello Blade")).start();
}

Open http://localhost:9000 in your browser to see your first Blade application!

Contents

  • Register Route
  • Request Parameter
  • Get Environment
  • Get Header
  • Get Cookie
  • Static Resource
  • Upload File
  • Download File
  • Set Session
  • Render To Browser

    Register Route

    HardCode

    public static void main(String[] args) {
        // Create multiple routes GET, POST, PUT, DELETE using Blade instance
        Blade.create()
            .get("/user/21", getting)
            .post("/save", posting)
            .delete("/remove", deleting)
            .put("/putValue", putting)
            .start();
    }

    Controller

    @Path
    public class IndexController {
    
        @GET("/login")
        public String login(){
            return "login.html";
        }
        
        @POST(value = "/login", responseType = ResponseType.JSON)
        public RestResponse doLogin(RouteContext ctx){
            // do something
            return RestResponse.ok();
        }
    
    }

    Request Parameter

    URL Parameter

    Using RouteContext

    public static void main(String[] args) {
        Blade.create().get("/user", ctx -> {
            Integer age = ctx.queryInt("age");
            System.out.println("age is:" + age);
        }).start();
    }

    Using @Query annotation

    @GET("/user")
    public void savePerson(@Query Integer age){
      System.out.println("age is:" + age);
    }

    Test it with sample data from the terminal

    curl -X GET http://127.0.0.1:9000/user?age=25

    Form Parameter

    Here is an example:

    Using RouteContext

    public static void main(String[] args) {
        Blade.create().get("/user", ctx -> {
            Integer age = ctx.fromInt("age");
            System.out.println("age is:" + age);
        }).start();
    }

    Using @Form Annotation

    @POST("/save")
    public void savePerson(@Form String username, @Form Integer age){
      System.out.println("username is:" + username + ", age is:" + age);
    }

    Test it with sample data from the terminal

    curl -X POST http://127.0.0.1:9000/save -F username=jack -F age=16

    Path Parameter

    Using RouteContext

    public static void main(String[] args) {
        Blade blade = Blade.create();
        // Create a route: /user/:uid
        blade.get("/user/:uid", ctx -> {
            Integer uid = ctx.pathInt("uid");
            ctx.text("uid : " + uid);
        });
    
        // Create two parameters route
        blade.get("/users/:uid/post/:pid", ctx -> {
            Integer uid = ctx.pathInt("uid");
            Integer pid = ctx.pathInt("pid");
            String msg = "uid = " + uid + ", pid = " + pid;
            ctx.text(msg);
        });
        
        // Start blade
        blade.start();
    }

    Using @PathParam Annotation

    @GET("/users/:username/:page")
    public void userTopics(@PathParam String username, @PathParam Integer page){
        System.out.println("username is:" + usernam + ", page is:" + page);
    }

    Test it with sample data from the terminal

    curl -X GET http://127.0.0.1:9000/users/hellokaton/2

    Body Parameter

    public static void main(String[] args) {
        Blade.create().post("/body", ctx -> {
            System.out.println("body string is:" + ctx.bodyToString());
        }).start();
    }

    Using @Body Annotation

    @POST("/body")
    public void readBody(@Body String data){
        System.out.println("data is:" + data);
    }

    Test it with sample data from the terminal

    curl -X POST http://127.0.0.1:9000/body -d '{"username":"hellokaton","age":22}'

    Parse To Model

    This is the User model.

    public class User {
        private String username;
        private Integer age;
        // getter and setter
    }

    By Annotation

    @POST("/users")
    public void saveUser(@Form User user) {
        System.out.println("user => " + user);
    }

    Test it with sample data from the terminal

    curl -X POST http://127.0.0.1:9000/users -F username=jack -F age=16

    Custom model identification

    @POST("/users")
    public void saveUser(@Form(name="u") User user) {
        System.out.println("user => " + user);
    }

    Test it with sample data from the terminal

    curl -X POST http://127.0.0.1:9000/users -F u[username]=jack -F u[age]=16

    Body Parameter To Model

    @POST("/body")
    public void body(@Body User user) {
        System.out.println("user => " + user);
    }

    Test it with sample data from the terminal

    curl -X POST http://127.0.0.1:9000/body -d '{"username":"hellokaton","age":22}'

    Get Environment

    Environment environment = WebContext.blade().environment();
    String version = environment.get("app.version", "0.0.1");

    Get Header

    By Context

    @GET("header")
    public void readHeader(RouteContext ctx){
        System.out.println("Host => " + ctx.header("Host"));
        // get useragent
        System.out.println("UserAgent => " + ctx.userAgent());
        // get client ip
        System.out.println("Client Address => " + ctx.address());
    }

    By Annotation

    @GET("header")
    public void readHeader(@Header String host){
        System.out.println("Host => " + host);
    }

    Get Cookie

    By Context

    @GET("cookie")
    public void readCookie(RouteContext ctx){
        System.out.println("UID => " + ctx.cookie("UID"));
    }

    By Annotation

    @GET("cookie")
    public void readCookie(@Cookie String uid){
        System.out.println("Cookie UID => " + uid);
    }

    Static Resource

    Blade builds a few static resource catalog, as long as you will save the resource file in the static directory under the classpath, and then browse http://127.0.0.1:9000/static/style.css

    If you want to customize the static resource URL

    Blade.create().addStatics("/mydir");

    Of course you can also specify it in the configuration file. application.properties (location in classpath)

    mvc.statics=/mydir

    Upload File

    By Request

    @POST("upload")
    public void upload(Request request){
        request.fileItem("img").ifPresent(fileItem -> {
            fileItem.moveTo(new File(fileItem.getFileName()));
        });
    }

    By Annotation

    @POST("upload")
    public void upload(@Multipart FileItem fileItem){
        // Save to new path
        fileItem.moveTo(new File(fileItem.getFileName()));
    }

    Download File

    @GET(value = "/download", responseType = ResponseType.STREAM)
    public void download(Response response) throws IOException {
        response.write("abcd.pdf", new File("146373013842336153820220427172437.pdf"));
    }

    If you want to preview certain files in your browser

    @GET(value = "/preview", responseType = ResponseType.PREVIEW)
    public void preview(Response response) throws IOException {
        response.write(new File("146373013842336153820220427172437.pdf"));
    }

    Set Session

    The session is disabled by default, you must enable the session.

    Blade.create()
         .http(HttpOptions::enableSession)
         .start(Application.class, args);

    💡 It can also be enabled using a configuration file,http.session.enabled=true

    public void login(Session session){
        // if login success
        session.attribute("login_key", SOME_MODEL);
    }

    Render To Browser

    Render Response

    By Context

    @GET("users/json")
    public void printJSON(RouteContext ctx){
        User user = new User("hellokaton", 18);
        ctx.json(user);
    }

    By Annotation

    This form looks more concise 😶

    @GET(value = "/users/json", responseType = ResponseType.JSON)
    public User printJSON(){
        return new User("hellokaton", 18);
    }

    Render Text

    @GET("text")
    public void printText(RouteContext ctx){
        ctx.text("I Love Blade!");
    }

    or

    @GET(value = "/text", responseType = ResponseType.TEXT)
    public String printText(RouteContext ctx){
        return "I Love Blade!";
    }

    Render Html

    @GET("html")
    public void printHtml(RouteContext ctx){
        ctx.html("<center><h1>I Love Blade!</h1></center>");
    }

    or

    @GET(value = "/html", responseType = ResponseType.HTML)
    public String printHtml(RouteContext ctx){
        return "<center><h1>I Love Blade!</h1></center>";
    }

    Render Template

    By default all template files are in the templates directory; in most of the cases you do not need to change it.

    Default Template

    By default, Blade uses the built-in template engine, which is very simple. In a real-world web project, you can try several other extensions.

    public static void main(String[] args) {
        Blade.create().get("/hello", ctx -> {
            ctx.attribute("name", "hellokaton");
            ctx.render("hello.html");
        }).start(Hello.class, args);
    }

    The hello.html template

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello Page</title>
    </head>
    <body>
    
        <h1>Hello, ${name}</h1>
    
    </body>
    </html>

    Jetbrick Template

    Config Jetbrick Template

    Create a BladeLoader class and load some config

    @Bean
    public class TemplateConfig implements BladeLoader {
    
        @Override
        public void load(Blade blade) {
            blade.templateEngine(new JetbrickTemplateEngine());
        }
    
    }

    Write some data for the template engine to render

    public static void main(String[] args) {
        Blade.create().get("/hello", ctx -> {
            User user = new User("hellokaton", 50);
            ctx.attribute("user", user);
            ctx.render("hello.html");
        }).start(Hello.class, args);
    }

    The hello.html template

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello Page</title>
    </head>
    <body>
    
        <h1>Hello, ${user.username}</h1>
    
        #if(user.age > 18)
            <p>Good Boy!</p>
        #else
            <p>Gooood Baby!</p>
        #end
    
    </body>
    </html>

    Render API

    Redirects

    @GET("redirect")
    public void redirectToGithub(RouteContext ctx){
        ctx.redirect("https://github.com/hellokaton");
    }

    Redirect API

    Write Cookie

    @GET("write-cookie")
    public void writeCookie(RouteContext ctx){
        ctx.cookie("hello", "world");
        ctx.cookie("UID", "22", 3600);
    }

    Cookie API

    Web Hook

    WebHook is the interface in the Blade framework that can be intercepted before and after the execution of the route.

    public static void main(String[] args) {
        // All requests are exported before execution before
        Blade.create().before("/*", ctx -> {
            System.out.println("before...");
        }).start();
    }

    Logging

    Blade uses slf4j-api as logging interface, the default implementation of a simple log package (modified from simple-logger); if you need complex logging you can also use a custom library, you only need to exclude the blade-log from the dependencies.

    private static final Logger log = LoggerFactory.getLogger(Hello.class);
    
    public static void main(String[] args) {
        log.info("Hello Info, {}", "2017");
        log.warn("Hello Warn");
        log.debug("Hello Debug");
        log.error("Hello Error");
    }

    Basic Auth

    Blade includes a few middleware, like Basic Authentication; of course, it can also be customized to achieve more complex goals.

    public static void main(String[] args) {
        Blade.create().use(new BasicAuthMiddleware()).start();
    }

    Specify the user name and password in the application.properties configuration file.

    http.auth.username=admin
    http.auth.password=123456

    Change Server Port

    There are three ways to modify the port: hard coding it, in a configuration file, and through a command line parameter.

    Hard Coding

    Blade.create().listen(9001).start();

    Configuration For application.properties

    server.port=9001

    Command Line

    java -jar blade-app.jar --server.port=9001

    Configuration SSL

    Configuration For application.properties

    server.ssl.enable=true
    server.ssl.cert-path=cert.pem
    server.ssl.private-key-path=private_key.pem
    server.ssl.private-key-pass=123456

    Custom Exception Handler

    Blade has an exception handler already implemented by default; if you need to deal with custom exceptions, you can do it like follows.

    @Bean
    public class GlobalExceptionHandler extends DefaultExceptionHandler {
        
        @Override
        public void handle(Exception e) {
            if (e instanceof CustomException) {
                CustomException customException = (CustomException) e;
                String code = customException.getCode();
                // do something
            } else {
                super.handle(e);
            }
        }
    
    }

    Besides looking easy, the features above are only the tip of the iceberg, and there are more surprises to see in the documentation and sample projects:

    Change Logs

    See Here

    Contact

    Contributors

    Thanks goes to these wonderful people

    contributors.svg

    Contributions of any kind are welcome!

    Licenses

    Please see Apache License

About

🚀 A Simple, Elegant Java Web Framework! website →

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 99.5%
  • Other 0.5%
0