<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>
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:
500kb, learning it is also simpleJAR package to open the web serviceCSRF and XSS defenseBasic Auth and Authorizationcron expressions» 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.
Create a basic Maven or Gradle project.
Do not create a
webappproject, 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!
Register Route
Request Parameter
Get EnvironmentGet HeaderGet CookieStatic ResourceUpload FileDownload FileSet SessionRender To Browser
Render Template
RedirectsWrite CookieWeb HookLoggingBasic AuthChange Server PortConfiguration SSLCustom Exception Handlerpublic 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();
}
}
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
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
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
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}'
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}'
Environment environment = WebContext.blade().environment();
String version = environment.get("app.version", "0.0.1");
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);
}
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);
}
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
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()));
}
@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"));
}
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);
}
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);
}
@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!";
}
@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>
";
}
By default all template files are in the templates directory; in most of the cases you do not need to change it.
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>
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());
}
}
$ claude mcp add blade \
-- python -m otcore.mcp_server <graph>