MCPcopy Index your code
hub / github.com/lets-blade/blade

github.com/lets-blade/blade @2.1.2.RELEASE sqlite

repository ↗ · DeepWiki ↗ · release 2.1.2.RELEASE ↗
1,845 symbols 6,390 edges 290 files 624 documented · 34%
README
<a href="https://lets-blade.com"><img src="https://i.loli.net/2018/09/18/5ba0cd93c710e.png" width="650"/></a>

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.

🐾 <a href="#quick-start" target="_blank">Quick Start</a> |
🌚 <a href="https://lets-blade.github.io/" target="_blank">Documentation</a> |
:green_book: <a href="https://www.baeldung.com/blade" target="_blank">Guidebook</a> |
💰 <a href="https://lets-blade.github.io/donate" target="_blank">Donate</a> |
🇨🇳 <a href="https://github.com/lets-blade/blade/raw/2.1.2.RELEASE/README_CN.md">简体中文</a>






<a href="https://travis-ci.org/lets-blade/blade"><img src="https://img.shields.io/travis/lets-blade/blade.svg?style=flat-square"></a>
<a href="http://search.maven.org/#search%7Cga%7C1%7Cblade-core"><img src="https://img.shields.io/maven-central/v/com.hellokaton/blade-core.svg?style=flat-square"></a>
<a href="https://github.com/lets-blade/blade/raw/2.1.2.RELEASE/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square"></a>
<a class="badge-align" href="https://www.codacy.com/gh/lets-blade/blade/dashboard"><img src="https://app.codacy.com/project/badge/Grade/1eff0e30bf694402ac1b0ebe587bfa5a"/></a>
<a href="https://gitter.im/lets-blade/blade"><img src="https://badges.gitter.im/hellokaton/blade.svg?style=flat-square"></a>
<a href="https://www.codetriage.com/lets-blade/blade"><img src="https://www.codetriage.com/lets-blade/blade/badges/users.svg"></a>

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

Features

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

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("

<h1>I Love Blade!</h1>

");
}

or

@GET(value = "/html", responseType = ResponseType.HTML)
public String printHtml(RouteContext ctx){
    return "

<h1>I Love Blade!</h1>

";
}

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());
    }

}

Extension points exported contracts — how you extend this code

WebHook (Interface)
Request WebHook Intercept before and after each request logic processing. @author biezhi 2017/6/2 [6 implementers]
blade-core/src/main/java/com/hellokaton/blade/mvc/hook/WebHook.java
Supplier_WithExceptions (Interface)
(no doc) [7 implementers]
blade-kit/src/main/java/com/hellokaton/blade/kit/UncheckedFnKit.java
WebSocketHandler (Interface)
@author hellokaton @date 2022/5/2 [4 implementers]
blade-websocket/src/main/java/com/hellokaton/blade/websocket/WebSocketHandler.java
RequestHandler (Interface)
Request Handler @author biezhi @date 2018/6/29 [7 implementers]
blade-core/src/main/java/com/hellokaton/blade/mvc/handler/RequestHandler.java
SupplierWithExceptions (Interface)
(no doc) [7 implementers]
blade-kit/src/main/java/com/hellokaton/blade/kit/ExceptionKit.java
RouteHandler (Interface)
Route logic handler @author biezhi 2017/5/31 [7 implementers]
blade-core/src/main/java/com/hellokaton/blade/mvc/handler/RouteHandler.java
Runnable_WithExceptions (Interface)
(no doc) [3 implementers]
blade-kit/src/main/java/com/hellokaton/blade/kit/UncheckedFnKit.java
Injector (Interface)
Bean Injector interface @author hellokaton @since 1.5 [5 implementers]
blade-core/src/main/java/com/hellokaton/blade/ioc/Injector.java

Core symbols most depended-on inside this repo

get
called by 231
blade-core/src/main/java/com/hellokaton/blade/mvc/multipart/MimeType.java
put
called by 210
blade-core/src/main/java/com/hellokaton/blade/ioc/SimpleIoc.java
equals
called by 183
blade-kit/src/main/java/com/hellokaton/blade/kit/Tuple2.java
set
called by 139
blade-core/src/main/java/com/hellokaton/blade/mvc/WebContext.java
length
called by 125
blade-core/src/main/java/com/hellokaton/blade/validator/Validators.java
filter
called by 94
blade-security/src/main/java/com/hellokaton/blade/security/filter/HTMLFilter.java
getName
called by 60
blade-core/src/main/java/com/hellokaton/blade/ioc/bean/ClassDefine.java
getAnnotation
called by 53
blade-core/src/main/java/com/hellokaton/blade/ioc/bean/ClassDefine.java

Shape

Method 1,553
Class 249
Interface 36
Enum 7

Languages

Java100%

Modules by API surface

blade-core/src/main/java/com/hellokaton/blade/mvc/http/Request.java54 symbols
blade-core/src/main/java/com/hellokaton/blade/Blade.java47 symbols
blade-core/src/main/java/com/hellokaton/blade/mvc/RouteContext.java45 symbols
blade-kit/src/main/java/com/hellokaton/blade/kit/EncryptKit.java42 symbols
blade-core/src/main/java/com/hellokaton/blade/mvc/http/HttpRequest.java35 symbols
blade-core/src/main/java/com/hellokaton/blade/task/cron/CronExpression.java32 symbols
blade-kit/src/main/java/com/hellokaton/blade/kit/StringKit.java29 symbols
blade-core/src/main/java/com/hellokaton/blade/Environment.java29 symbols
blade-core/src/main/java/com/hellokaton/blade/kit/BladeKit.java27 symbols
blade-core/src/main/java/com/hellokaton/blade/mvc/ui/template/BladeTemplate.java26 symbols
blade-core/src/main/java/com/hellokaton/blade/server/StaticFileHandler.java25 symbols
blade-security/src/main/java/com/hellokaton/blade/security/filter/HTMLFilter.java24 symbols

Dependencies from manifests, versioned

com.carrotsearch:junit-benchmarks
com.hellokaton:blade-asm
com.hellokaton:blade-core
com.hellokaton:blade-kit
com.hellokaton:blade-log
com.hellokaton:blade-security2.1.2.RELEASE · 1×
com.mashape.unirest:unirest-java
io.jsonwebtoken:jjwt-gson
io.jsonwebtoken:jjwt-impl
io.netty:netty-codec-http

Datastores touched

(mysql)Database · 1 repos

For agents

$ claude mcp add blade \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact