├── blade-upload ├── src │ └── main │ │ ├── resources │ │ ├── upload │ │ │ └── a.txt │ │ └── templates │ │ │ └── upload.html │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── upload │ │ ├── UploadApplication.java │ │ └── UploadController.java └── pom.xml ├── blade-task ├── src │ └── main │ │ ├── resources │ │ └── application.properties │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── task │ │ ├── TaskApplication.java │ │ └── TaskExample.java └── pom.xml ├── .vscode ├── settings.json └── launch.json ├── blade-package ├── src │ └── main │ │ ├── resources │ │ └── static │ │ │ └── hello.css │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── HelloApplication.java ├── package.xml └── pom.xml ├── blade-gzip ├── README.md ├── src │ └── main │ │ ├── resources │ │ └── static │ │ │ └── example.png │ │ └── java │ │ └── com │ │ └── bladejava │ │ └── gzip │ │ └── GzipApplication.java └── pom.xml ├── blade-download ├── src │ └── main │ │ ├── resources │ │ └── static │ │ │ └── octo.png │ │ └── java │ │ └── com │ │ └── bladejava │ │ └── demo │ │ └── download │ │ └── DownloadApplication.java └── pom.xml ├── blade-static ├── src │ └── main │ │ ├── resources │ │ └── static │ │ │ ├── hello.png │ │ │ └── main.css │ │ └── java │ │ └── com │ │ └── bladejava │ │ └── staticdir │ │ └── StaticApplication.java └── pom.xml ├── blade-freemarker ├── src │ └── main │ │ ├── resources │ │ └── templates │ │ │ └── index.ftl │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── freemarker │ │ ├── FreeMarkerApplication.java │ │ ├── Bootstrap.java │ │ └── IndexController.java └── pom.xml ├── blade-errorpage ├── src │ └── main │ │ ├── resources │ │ ├── application.properties │ │ └── templates │ │ │ └── error │ │ │ └── error_404.html │ │ └── java │ │ └── com │ │ └── bladejava │ │ └── errorpage │ │ └── ErrorPageApplication.java └── pom.xml ├── blade-route ├── src │ └── main │ │ ├── resources │ │ └── templates │ │ │ ├── hello2.html │ │ │ └── hello.html │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── route │ │ ├── IndexController.java │ │ ├── RouteApplication.java │ │ ├── User.java │ │ ├── RestController.java │ │ ├── RestController2.java │ │ ├── Hook1.java │ │ └── UserController.java └── pom.xml ├── blade-anima ├── src │ └── main │ │ ├── resources │ │ ├── application.properties │ │ └── schema.sql │ │ └── java │ │ └── com │ │ └── bladejava │ │ └── anima │ │ ├── DBApplication.java │ │ ├── Bootstrap.java │ │ ├── IndexController.java │ │ └── User.java ├── pom.xml └── README.md ├── blade-test ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── bladejava │ │ │ └── demo │ │ │ ├── TestApplication.java │ │ │ ├── service │ │ │ ├── UserService.java │ │ │ └── PostService.java │ │ │ ├── model │ │ │ └── User.java │ │ │ └── controller │ │ │ └── UserController.java │ └── test │ │ └── java │ │ └── com │ │ └── bladejava │ │ └── demo │ │ └── test │ │ ├── BaseTest.java │ │ ├── service │ │ ├── PostServiceTest.java │ │ └── UserServiceTest.java │ │ └── controller │ │ └── UserControllerTest.java └── pom.xml ├── blade-ajax ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── blade │ │ │ └── demo │ │ │ └── ajax │ │ │ ├── AjaxApplication.java │ │ │ ├── IndexController.java │ │ │ └── User.java │ │ └── resources │ │ └── templates │ │ └── index.html └── pom.xml ├── blade-param ├── src │ └── main │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── param │ │ ├── ParamApplication.java │ │ ├── User.java │ │ └── IndexController.java └── pom.xml ├── blade-template ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── blade │ │ │ └── demo │ │ │ └── tpl │ │ │ ├── TemplateApplication.java │ │ │ ├── Bootstrap.java │ │ │ └── IndexController.java │ │ └── resources │ │ ├── templates │ │ ├── index.html │ │ └── login.html │ │ └── static │ │ ├── main.js │ │ └── main.css └── pom.xml ├── blade-helloworld ├── src │ └── main │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── helloworld │ │ └── HelloApplication.java └── pom.xml ├── blade-lattice ├── src │ └── main │ │ ├── resources │ │ └── templates │ │ │ └── login.html │ │ └── java │ │ └── com │ │ └── bladejava │ │ └── lattice │ │ ├── LatticeApplication.java │ │ ├── controller │ │ ├── IndexController.java │ │ └── AdminController.java │ │ ├── bootstrap │ │ ├── Bootstrap.java │ │ └── MyRealm.java │ │ └── model │ │ └── User.java └── pom.xml ├── blade-mongo ├── src │ └── main │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── mongo │ │ ├── MongoApplication.java │ │ ├── MongoConfig.java │ │ └── IndexController.java └── pom.xml ├── blade-custom-banner ├── src │ └── main │ │ └── java │ │ └── com │ │ └── blade │ │ └── demo │ │ └── custom │ │ └── CustomApplication.java └── pom.xml ├── blade-cors ├── src │ └── main │ │ ├── java │ │ └── com │ │ │ └── blade │ │ │ └── demo │ │ │ └── cors │ │ │ ├── CorsApplication.java │ │ │ ├── IndexController.java │ │ │ └── User.java │ │ └── resources │ │ └── templates │ │ └── index.html └── pom.xml ├── blade-websocket ├── pom.xml └── src │ └── main │ ├── resources │ ├── templates │ │ └── index.html │ └── static │ │ ├── main.css │ │ └── main.js │ └── java │ └── com │ └── bladejava │ └── demo │ └── ws │ └── WebSocketApplication.java ├── blade-kit-example ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── blade │ └── demo │ └── kit │ ├── JSONKitExample.java │ └── model │ └── User.java ├── blade-vue-todolist ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── blade │ │ └── demo │ │ └── vue │ │ ├── Todo.java │ │ └── TodoApplication.java │ └── resources │ ├── templates │ └── index.html │ └── static │ ├── app.js │ ├── base.js │ ├── app.css │ └── director.js ├── blade-verify-code ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── blade │ └── demo │ └── verifycode │ └── VerifyCodeApplication.java ├── blade-csrf-token ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── bladejava │ └── demo │ └── csrf │ └── CSRFApplication.java ├── blade-activemq └── pom.xml ├── blade-basic-auth ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── bladejava │ └── demo │ └── basicauth │ └── BasicAuthApplication.java ├── README.md ├── .gitignore └── pom.xml /blade-upload/src/main/resources/upload/a.txt: -------------------------------------------------------------------------------- 1 | the first file. -------------------------------------------------------------------------------- /blade-task/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | task_exp=*/3 * * * * ? -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic" 3 | } -------------------------------------------------------------------------------- /blade-package/src/main/resources/static/hello.css: -------------------------------------------------------------------------------- 1 | body, html{ 2 | background-color: aqua; 3 | } -------------------------------------------------------------------------------- /blade-gzip/README.md: -------------------------------------------------------------------------------- 1 | # blade-zip 2 | 3 | you can access url 4 | 5 | - http://127.0.0.1:9000/ 6 | - http://127.0.0.1:9000/static/example.png 7 | 8 | -------------------------------------------------------------------------------- /blade-download/src/main/resources/static/octo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lets-blade/blade-demos/HEAD/blade-download/src/main/resources/static/octo.png -------------------------------------------------------------------------------- /blade-gzip/src/main/resources/static/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lets-blade/blade-demos/HEAD/blade-gzip/src/main/resources/static/example.png -------------------------------------------------------------------------------- /blade-static/src/main/resources/static/hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lets-blade/blade-demos/HEAD/blade-static/src/main/resources/static/hello.png -------------------------------------------------------------------------------- /blade-freemarker/src/main/resources/templates/index.ftl: -------------------------------------------------------------------------------- 1 | [#ftl] 2 | 循环 3 | [#list users as user] 4 | ${user} 5 | [/#list] 6 |
7 | 8 | map:${map.name} ${map.age} -------------------------------------------------------------------------------- /blade-errorpage/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | mvc.view.404=/error/error_404.html 2 | app.devMode=true 3 | 4 | blade.logger.dir=./logs 5 | blade.logger.defaultLogLevel=debug 6 | -------------------------------------------------------------------------------- /blade-errorpage/src/main/resources/templates/error/error_404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | my 404 9 | 10 | -------------------------------------------------------------------------------- /blade-route/src/main/resources/templates/hello2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

Hello 222222

9 | 10 | -------------------------------------------------------------------------------- /blade-anima/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | jdbc.url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true 2 | jdbc.username=root 3 | jdbc.password=123456 4 | 5 | com.blade.logger.org.sql2o=debug 6 | com.blade.logger.dir=./logs -------------------------------------------------------------------------------- /blade-route/src/main/resources/templates/hello.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 |
10 |

Hello Page.

11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /blade-test/src/main/java/com/bladejava/demo/TestApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/5/31 6 | */ 7 | public class TestApplication { 8 | 9 | public static void main(String[] args) { 10 | 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /blade-anima/src/main/java/com/bladejava/anima/DBApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.anima; 2 | 3 | 4 | import com.hellokaton.blade.Blade; 5 | 6 | public class DBApplication { 7 | 8 | public static void main(String[] args) { 9 | Blade.create().start(DBApplication.class, args); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /blade-ajax/src/main/java/com/blade/demo/ajax/AjaxApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.ajax; 2 | 3 | 4 | import com.hellokaton.blade.Blade; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2017/9/28 9 | */ 10 | public class AjaxApplication { 11 | 12 | public static void main(String[] args) { 13 | Blade.create().start(AjaxApplication.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /blade-task/src/main/java/com/blade/demo/task/TaskApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.task; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2018/4/12 8 | */ 9 | public class TaskApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create().start(TaskApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /blade-param/src/main/java/com/blade/demo/param/ParamApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.param; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2018/5/30 8 | */ 9 | public class ParamApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create().start(ParamApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /blade-template/src/main/java/com/blade/demo/tpl/TemplateApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.tpl; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2017/9/28 8 | */ 9 | public class TemplateApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create().start(TemplateApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /blade-static/src/main/java/com/bladejava/staticdir/StaticApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.staticdir; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * 7 | * @author biezhi 8 | * @date 2018/6/1 9 | */ 10 | public class StaticApplication { 11 | 12 | public static void main(String[] args) { 13 | Blade.create().start(StaticApplication.class, args); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blade-errorpage/src/main/java/com/bladejava/errorpage/ErrorPageApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.errorpage; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2018/6/3 8 | */ 9 | public class ErrorPageApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create().start(ErrorPageApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /blade-freemarker/src/main/java/com/blade/demo/freemarker/FreeMarkerApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.freemarker; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2017/9/28 8 | */ 9 | public class FreeMarkerApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create().start(FreeMarkerApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /blade-package/src/main/java/com/blade/demo/HelloApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2017/9/28 8 | */ 9 | public class HelloApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create().get("/", ctx -> ctx.text("Hello World")).start(HelloApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /blade-route/src/main/java/com/blade/demo/route/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.route; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2017/9/28 9 | */ 10 | @Path 11 | public class IndexController { 12 | 13 | @GET("hello") 14 | public String hello() { 15 | return "hello.html"; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blade-helloworld/src/main/java/com/blade/demo/helloworld/HelloApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.helloworld; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author hellokaton 7 | * @date 2022/5/3 8 | */ 9 | public class HelloApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create().get("/", ctx -> ctx.text("Hello World")).start(HelloApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /blade-template/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 14 | 15 |
16 | 17 | ${map.name} -> ${map.age} 18 | 19 |
20 | 21 | #if(map.age > 18) 22 | 成年 23 | #else 24 | 未成年 25 | #end 26 | 27 | 28 | -------------------------------------------------------------------------------- /blade-ajax/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 首页 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | -------------------------------------------------------------------------------- /blade-lattice/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

Login

9 |
10 | UserName:
11 | PassWord:
12 | 13 |
14 | 15 | -------------------------------------------------------------------------------- /blade-mongo/src/main/java/com/blade/demo/mongo/MongoApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.mongo; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * http://www.mkyong.com/mongodb/java-mongodb-hello-world-example/ 7 | * 8 | * @author biezhi 9 | * @date 2018/4/27 10 | */ 11 | public class MongoApplication { 12 | 13 | public static void main(String[] args) { 14 | Blade.create().start(MongoApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /blade-test/src/test/java/com/bladejava/demo/test/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.test; 2 | 3 | import com.hellokaton.blade.test.BladeApplication; 4 | import com.hellokaton.blade.test.BladeTestRunner; 5 | import com.bladejava.demo.TestApplication; 6 | import org.junit.runner.RunWith; 7 | 8 | /** 9 | * @author biezhi 10 | * @date 2018/5/31 11 | */ 12 | @RunWith(BladeTestRunner.class) 13 | @BladeApplication(TestApplication.class) 14 | public abstract class BaseTest { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /blade-custom-banner/src/main/java/com/blade/demo/custom/CustomApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.custom; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2017/12/15 8 | */ 9 | public class CustomApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create() 13 | .bannerText("Hei hei hei~~~") 14 | .threadName("(*  ̄3)(ε ̄ *)") 15 | .start(CustomApplication.class, args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blade-lattice/src/main/java/com/bladejava/lattice/LatticeApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.lattice; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.lattice.LatticeMiddleware; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2018/6/4 9 | */ 10 | public class LatticeApplication { 11 | 12 | public static void main(String[] args) { 13 | Blade.create() 14 | .use(new LatticeMiddleware()) 15 | .start(LatticeApplication.class, args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blade-route/src/main/java/com/blade/demo/route/RouteApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.route; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2017/9/28 8 | */ 9 | public class RouteApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create() 13 | .get("/get", ctx -> ctx.text("Get Route")) 14 | .post("/post", ctx -> ctx.text("Post Route")) 15 | .start(RouteApplication.class, args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /blade-cors/src/main/java/com/blade/demo/cors/CorsApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.cors; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.options.CorsOptions; 5 | 6 | public class CorsApplication { 7 | 8 | public static void main(String[] args) { 9 | CorsOptions corsOptions = CorsOptions.forAnyOrigin().allowNullOrigin().allowCredentials(); 10 | 11 | Blade.create() 12 | .cors(corsOptions) 13 | .start(CorsApplication.class, args); 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /blade-test/src/main/java/com/bladejava/demo/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.service; 2 | 3 | import com.bladejava.demo.model.User; 4 | import com.hellokaton.blade.ioc.annotation.Bean; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2018/5/31 9 | */ 10 | @Bean 11 | public class UserService { 12 | 13 | public String sayHello() { 14 | return "Hello"; 15 | } 16 | 17 | public Long saveUser(User user) { 18 | System.out.println("save user: " + user); 19 | return user.getUid(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /blade-ajax/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-ajax 13 | 14 | -------------------------------------------------------------------------------- /blade-cors/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-cors 13 | 14 | -------------------------------------------------------------------------------- /blade-param/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-param 13 | 14 | -------------------------------------------------------------------------------- /blade-gzip/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-gzip 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-gzip/src/main/java/com/bladejava/gzip/GzipApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.gzip; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.options.HttpOptions; 5 | 6 | /** 7 | * @author hellokaton 8 | * @date 2022/5/3 9 | */ 10 | public class GzipApplication { 11 | 12 | public static void main(String[] args) { 13 | Blade.create() 14 | .get("/", ctx -> ctx.render("index.html")) 15 | .http(HttpOptions::enableGzip) 16 | .start(GzipApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /blade-route/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-route 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-task/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-task 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-download/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-download 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-upload/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-upload 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-custom-banner/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-custom-banner 13 | 14 | -------------------------------------------------------------------------------- /blade-errorpage/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-errorpage 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-websocket/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-websocket 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-kit-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-kit-example 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-template/src/main/java/com/blade/demo/tpl/Bootstrap.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.tpl; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.ioc.annotation.Bean; 5 | import com.hellokaton.blade.loader.BladeLoader; 6 | import com.hellokaton.blade.template.JetbrickTemplateEngine; 7 | 8 | /** 9 | * @author biezhi 10 | * @date 2017/9/28 11 | */ 12 | @Bean 13 | public class Bootstrap implements BladeLoader { 14 | 15 | @Override 16 | public void load(Blade blade) { 17 | blade.templateEngine(new JetbrickTemplateEngine()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /blade-vue-todolist/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-vue-todolist 13 | 14 | 15 | -------------------------------------------------------------------------------- /blade-anima/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `t_user` ( 2 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 3 | `username` varchar(20) DEFAULT NULL, 4 | `password` varchar(50) DEFAULT NULL, 5 | `real_name` varchar(20) DEFAULT NULL, 6 | `age` int(10) DEFAULT NULL, 7 | PRIMARY KEY (`id`) 8 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; 9 | 10 | INSERT INTO `t_user` (`id`, `username`, `password`, `real_name`, `age`) 11 | VALUES 12 | (1, 'jack', 'aaa', '杰克', 32), 13 | (2, 'rose', '999', '螺丝', 29), 14 | (3, 'biezhi', '123556', '魔王不造反', 19), 15 | (4, 'codesofun', '123556', '代码真香', 20); 16 | -------------------------------------------------------------------------------- /blade-test/src/main/java/com/bladejava/demo/service/PostService.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.service; 2 | 3 | import com.bladejava.demo.model.User; 4 | import com.hellokaton.blade.ioc.annotation.Bean; 5 | import com.hellokaton.blade.ioc.annotation.Inject; 6 | 7 | /** 8 | * @author biezhi 9 | * @date 2018/5/31 10 | */ 11 | @Bean 12 | public class PostService { 13 | 14 | @Inject 15 | private UserService userService; 16 | 17 | public boolean savePost(Long uid) { 18 | userService.saveUser(new User(uid, "biezhi")); 19 | // save post 20 | return true; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /blade-upload/src/main/java/com/blade/demo/upload/UploadApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.upload; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.options.CorsOptions; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2017/10/1 9 | */ 10 | public class UploadApplication { 11 | 12 | public static void main(String[] args) { 13 | CorsOptions corsOptions = CorsOptions.forAnyOrigin().allowNullOrigin().allowCredentials(); 14 | Blade.create().showFileList(true) 15 | .cors(corsOptions) 16 | .start(UploadApplication.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /blade-param/src/main/java/com/blade/demo/param/User.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.param; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2018/5/30 8 | */ 9 | public class User implements Serializable { 10 | 11 | private Long uid; 12 | private String name; 13 | 14 | public Long getUid() { 15 | return uid; 16 | } 17 | 18 | public void setUid(Long uid) { 19 | this.uid = uid; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /blade-lattice/src/main/java/com/bladejava/lattice/controller/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.lattice.controller; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.mvc.http.Response; 6 | 7 | /** 8 | * @author biezhi 9 | * @date 2018/6/4 10 | */ 11 | @Path 12 | public class IndexController { 13 | 14 | @GET("/") 15 | public void home(Response response) { 16 | response.html("Home Page."); 17 | } 18 | 19 | @GET("/login") 20 | public String login() { 21 | return "login.html"; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /blade-route/src/main/java/com/blade/demo/route/User.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.route; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2017/9/28 6 | */ 7 | public class User { 8 | 9 | private String username; 10 | private String password; 11 | 12 | public String getUsername() { 13 | return username; 14 | } 15 | 16 | public void setUsername(String username) { 17 | this.username = username; 18 | } 19 | 20 | public String getPassword() { 21 | return password; 22 | } 23 | 24 | public void setPassword(String password) { 25 | this.password = password; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /blade-test/src/test/java/com/bladejava/demo/test/service/PostServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.test.service; 2 | 3 | import com.bladejava.demo.service.PostService; 4 | import com.bladejava.demo.test.BaseTest; 5 | import com.hellokaton.blade.ioc.annotation.Inject; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | 9 | /** 10 | * @author biezhi 11 | * @date 2018/5/31 12 | */ 13 | public class PostServiceTest extends BaseTest { 14 | 15 | @Inject 16 | private PostService postService; 17 | 18 | @Test 19 | public void testSayHello() { 20 | boolean result = postService.savePost(2333L); 21 | Assert.assertEquals(true, result); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /blade-lattice/src/main/java/com/bladejava/lattice/bootstrap/Bootstrap.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.lattice.bootstrap; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.ioc.annotation.Bean; 5 | import com.hellokaton.blade.loader.BladeLoader; 6 | import com.hellokaton.lattice.Lattice; 7 | 8 | /** 9 | * @author biezhi 10 | * @date 2018/6/4 11 | */ 12 | @Bean 13 | public class Bootstrap implements BladeLoader { 14 | 15 | @Override 16 | public void load(Blade blade) { 17 | Lattice lattice = new Lattice(); 18 | lattice.loginUrl("/login").unauthorizedUrl("/unauthorized"); 19 | lattice.realm(new MyRealm()); 20 | blade.register(lattice); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /blade-websocket/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 |
10 |

WebSockets Demo

11 | 12 |
正在连接...
13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /blade-freemarker/src/main/java/com/blade/demo/freemarker/Bootstrap.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.freemarker; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.ioc.annotation.Bean; 5 | import com.hellokaton.blade.loader.BladeLoader; 6 | import com.hellokaton.blade.template.FreeMarkerTemplateEngine; 7 | 8 | /** 9 | * Created by Administrator on 2017/12/24. 10 | */ 11 | @Bean 12 | public class Bootstrap implements BladeLoader { 13 | 14 | @Override 15 | public void load(Blade blade) { 16 | blade.templateEngine(new FreeMarkerTemplateEngine()); 17 | // if you need to do more configration you can use this constructor 18 | // FreeMarkerTemplateEngine(Configration config) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /blade-route/src/main/java/com/blade/demo/route/RestController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.route; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.annotation.route.POST; 6 | import com.hellokaton.blade.mvc.ui.ResponseType; 7 | import com.hellokaton.blade.mvc.ui.RestResponse; 8 | 9 | /** 10 | * @author biezhi 11 | * @date 2018/6/26 12 | */ 13 | @Path(responseType = ResponseType.JSON) 14 | public class RestController { 15 | 16 | @POST("/hello") 17 | public RestResponse hello() { 18 | return RestResponse.ok("hello"); 19 | } 20 | 21 | @GET("/world") 22 | public RestResponse world() { 23 | return RestResponse.ok("world"); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blade-route/src/main/java/com/blade/demo/route/RestController2.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.route; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.annotation.route.POST; 6 | import com.hellokaton.blade.mvc.ui.ResponseType; 7 | import com.hellokaton.blade.mvc.ui.RestResponse; 8 | 9 | /** 10 | * @author biezhi 11 | * @date 2018/6/26 12 | */ 13 | @Path(value = "rest", responseType = ResponseType.JSON) 14 | public class RestController2 { 15 | 16 | @POST("/hello") 17 | public RestResponse hello() { 18 | return RestResponse.ok("hello"); 19 | } 20 | 21 | @GET("/world") 22 | public RestResponse world() { 23 | return RestResponse.ok("world"); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blade-mongo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-mongo 13 | 14 | 15 | 16 | org.mongodb 17 | mongodb-driver 18 | 3.6.3 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blade-lattice/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-lattice 13 | 14 | 15 | 16 | com.hellokaton 17 | blade-lattice 18 | 0.1.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blade-verify-code/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-verify-code 13 | 14 | 15 | 16 | com.hellokaton 17 | blade-patchca 18 | 1.2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blade-csrf-token/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-csrf-token 13 | 14 | 15 | 16 | com.hellokaton 17 | blade-security 18 | 2.1.0.BETA 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blade-route/src/main/java/com/blade/demo/route/Hook1.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.route; 2 | 3 | import com.hellokaton.blade.ioc.annotation.Bean; 4 | import com.hellokaton.blade.mvc.RouteContext; 5 | import com.hellokaton.blade.mvc.hook.WebHook; 6 | import com.hellokaton.blade.mvc.ui.ModelAndView; 7 | 8 | /** 9 | * @author biezhi 10 | * @date 2018/5/30 11 | */ 12 | @Bean 13 | public class Hook1 implements WebHook { 14 | 15 | @Override 16 | public boolean before(RouteContext context) { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean after(RouteContext context) { 22 | ModelAndView modelAndView = context.response().modelAndView(); 23 | if (null != modelAndView) { 24 | modelAndView.setView("hello2.html"); 25 | } 26 | return true; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /blade-template/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-template 13 | 14 | 15 | 16 | com.hellokaton 17 | blade-template-jetbrick 18 | 0.2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blade-activemq/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-activemq 13 | 14 | 15 | 16 | 17 | org.apache.activemq 18 | activemq-all 19 | 5.14.5 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /blade-freemarker/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-freemarker 13 | 14 | 15 | 16 | com.hellokaton 17 | blade-template-freemarker 18 | 0.0.2 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blade-basic-auth/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-basic-auth 13 | 14 | 15 | 16 | com.hellokaton 17 | blade-security 18 | ${blade-core.version} 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /blade-basic-auth/src/main/java/com/bladejava/demo/basicauth/BasicAuthApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.basicauth; 2 | 3 | 4 | import com.hellokaton.blade.Blade; 5 | import com.hellokaton.blade.security.auth.AuthOption; 6 | import com.hellokaton.blade.security.auth.BasicAuthMiddleware; 7 | 8 | /** 9 | * Basic Auth Example 10 | * 11 | * @author biezhi 12 | * @date 2018/7/30 13 | */ 14 | public class BasicAuthApplication { 15 | 16 | public static void main(String[] args) { 17 | AuthOption authOption = AuthOption.builder().build(); 18 | authOption.addUser("admin", "123456"); 19 | 20 | Blade.create() 21 | .get("/", ctx -> ctx.text("Hello World.")) 22 | .use(new BasicAuthMiddleware(authOption)) 23 | .start(BasicAuthApplication.class, args); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blade-cors/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 首页 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 | Please check the Network's response headers 16 |
17 | 18 | 19 | 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blade-demos 2 | 3 | - [blade-helloworld](blade-helloworld) 4 | - [blade-static](blade-static) 5 | - [blade-upload](blade-upload) 6 | - [blade-download](blade-download) 7 | - [blade-ajax](blade-ajax) 8 | - [blade-route](blade-route) 9 | - [blade-template](blade-template) 10 | - [blade-vue-todolist](blade-vue-todolist) 11 | - [blade-package](blade-package) 12 | - [blade-custom-banner](blade-custom-banner) 13 | - [blade-kit-example](blade-kit-example) 14 | - [blade-freemarker-example](blade-freemarker) 15 | - [blade-task](blade-task) 16 | - [blade-mongo](blade-mongo) 17 | - [blade-param](blade-param) 18 | - [blade-test](blade-test) 19 | - [blade-errorpage](blade-errorpage) 20 | - [blade-gzip](blade-gzip) 21 | - [blade-basic-auth](blade-basic-auth) 22 | - [blade-csrf-token](blade-csrf-token) 23 | - [blade-websocket](blade-websocket) 24 | - [blade-verify-code](blade-verify-code) 25 | - [blade-cors](blade-cors) -------------------------------------------------------------------------------- /blade-test/src/test/java/com/bladejava/demo/test/service/UserServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.test.service; 2 | 3 | import com.bladejava.demo.model.User; 4 | import com.bladejava.demo.service.UserService; 5 | import com.bladejava.demo.test.BaseTest; 6 | import com.hellokaton.blade.ioc.annotation.Inject; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | /** 11 | * @author biezhi 12 | * @date 2018/5/31 13 | */ 14 | public class UserServiceTest extends BaseTest { 15 | 16 | @Inject 17 | private UserService userService; 18 | 19 | @Test 20 | public void testSayHello() { 21 | String hello = userService.sayHello(); 22 | Assert.assertEquals("Hello", hello); 23 | } 24 | 25 | @Test 26 | public void testSaveUser() { 27 | long uid = userService.saveUser(new User(9881L, "rose")); 28 | Assert.assertEquals(9881, uid); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blade-test/src/test/java/com/bladejava/demo/test/controller/UserControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.test.controller; 2 | 3 | import com.bladejava.demo.test.BaseTest; 4 | import com.mashape.unirest.http.Unirest; 5 | import com.mashape.unirest.http.exceptions.UnirestException; 6 | import org.junit.Test; 7 | 8 | /** 9 | * @author biezhi 10 | * @date 2018/5/31 11 | */ 12 | public class UserControllerTest extends BaseTest { 13 | 14 | @Test 15 | public void testList() throws UnirestException { 16 | int statusCode = Unirest.get("http://127.0.0.1:9000/user/list").asString().getStatus(); 17 | System.out.println("statusCode = " + statusCode); 18 | } 19 | 20 | @Test 21 | public void testDetail() throws UnirestException { 22 | String body = Unirest.get("http://127.0.0.1:9000/user/detail/23").asString().getBody(); 23 | System.out.println("body = " + body); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /blade-ajax/src/main/java/com/blade/demo/ajax/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.ajax; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.mvc.ui.ResponseType; 6 | import com.hellokaton.blade.mvc.ui.RestResponse; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @author biezhi 13 | * @date 2017/9/28 14 | */ 15 | @Path 16 | public class IndexController { 17 | 18 | @GET 19 | public String index() { 20 | return "index.html"; 21 | } 22 | 23 | @GET(value = "users", responseType = ResponseType.JSON) 24 | public RestResponse> users() { 25 | List users = this.buildUsers(); 26 | return RestResponse.ok(users); 27 | } 28 | 29 | private List buildUsers() { 30 | List users = new ArrayList<>(); 31 | return users; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /blade-test/src/main/java/com/bladejava/demo/model/User.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.model; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/5/31 6 | */ 7 | public class User { 8 | 9 | private Long uid; 10 | private String name; 11 | 12 | public User() { 13 | 14 | } 15 | 16 | public User(Long uid, String name) { 17 | this.uid = uid; 18 | this.name = name; 19 | } 20 | 21 | public Long getUid() { 22 | return uid; 23 | } 24 | 25 | public void setUid(Long uid) { 26 | this.uid = uid; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "User{" + 40 | "uid=" + uid + 41 | ", name='" + name + '\'' + 42 | '}'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /blade-kit-example/src/main/java/com/blade/demo/kit/JSONKitExample.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.kit; 2 | 3 | import com.blade.demo.kit.model.User; 4 | import com.hellokaton.blade.kit.JsonKit; 5 | 6 | import java.util.Date; 7 | 8 | /** 9 | * @author hellokaton 10 | * @date 2022/5/3 11 | */ 12 | public class JSONKitExample { 13 | 14 | public static void main(String[] args) { 15 | User u1 = new User(); 16 | u1.setAge(22); 17 | u1.setBirthday(new Date()); 18 | u1.setMoney(208.1D); 19 | u1.setSex(true); 20 | u1.setStatus(Byte.valueOf("2")); 21 | u1.setUsername("biezhi"); 22 | 23 | String json = JsonKit.toString(u1); 24 | System.out.println(json); 25 | 26 | String str = "{\"username\":\"biezhi\",\"age\":22,\"money\":208.1,\"birthday\":\"2017年12月20日 14:34\",\"sex\":true,\"status\":2}"; 27 | 28 | User u2 = JsonKit.fromJson(str, User.class); 29 | System.out.println(u2); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /blade-anima/src/main/java/com/bladejava/anima/Bootstrap.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.anima; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.hellokaton.blade.Blade; 5 | import com.hellokaton.blade.ioc.annotation.Bean; 6 | import com.hellokaton.blade.loader.BladeLoader; 7 | import com.hellokaton.anima.Anima; 8 | 9 | /** 10 | * 启动加载项 11 | * 12 | * @author biezhi 13 | * @date 2022/5/3 14 | */ 15 | @Bean 16 | public class Bootstrap implements BladeLoader { 17 | 18 | @Override 19 | public void load(Blade blade) { 20 | // JDBC 21 | DruidDataSource dataSource = new DruidDataSource(); 22 | dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 23 | dataSource.setUrl(blade.environment().getOrNull("jdbc.url")); 24 | dataSource.setUsername(blade.environment().getOrNull("jdbc.username")); 25 | dataSource.setPassword(blade.environment().getOrNull("jdbc.password")); 26 | 27 | Anima.open(dataSource); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /blade-template/src/main/java/com/blade/demo/tpl/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.tpl; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.mvc.http.Request; 6 | 7 | import java.util.Arrays; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author biezhi 14 | * @date 2017/9/28 15 | */ 16 | @Path 17 | public class IndexController { 18 | 19 | @GET 20 | public String index(Request request) { 21 | List users = Arrays.asList("jack", "biezhi", "rose"); 22 | request.attribute("users", users); 23 | 24 | Map map = new HashMap<>(); 25 | map.put("name", "jack"); 26 | map.put("age", 20); 27 | request.attribute("map", map); 28 | 29 | return "index.html"; 30 | } 31 | 32 | @GET("login") 33 | public String login() { 34 | return "login.html"; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /blade-freemarker/src/main/java/com/blade/demo/freemarker/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.freemarker; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.mvc.http.Request; 6 | 7 | import java.util.Arrays; 8 | import java.util.HashMap; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author biezhi 14 | * @date 2017/9/28 15 | */ 16 | @Path 17 | public class IndexController { 18 | 19 | @GET 20 | public String index(Request request) { 21 | 22 | List users = Arrays.asList("jack", "biezhi", "rose"); 23 | request.attribute("users", users); 24 | 25 | Map map = new HashMap<>(); 26 | map.put("name", "jack"); 27 | map.put("age", 20); 28 | request.attribute("map", map); 29 | 30 | return "index"; 31 | } 32 | 33 | @GET("login") 34 | public String login() { 35 | return "login.html"; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /blade-lattice/src/main/java/com/bladejava/lattice/controller/AdminController.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.lattice.controller; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.annotation.route.POST; 6 | import com.hellokaton.blade.mvc.ui.RestResponse; 7 | import com.hellokaton.lattice.annotation.Permissions; 8 | import com.hellokaton.lattice.annotation.Roles; 9 | import com.hellokaton.lattice.annotation.Users; 10 | 11 | /** 12 | * @author biezhi 13 | * @date 2018/6/4 14 | */ 15 | @Path("admin") 16 | @Users 17 | public class AdminController { 18 | 19 | @GET("index") 20 | public String index() { 21 | return "index.html"; 22 | } 23 | 24 | @Roles("admin") 25 | @GET("deleteUser") 26 | public String deleteUserPage() { 27 | return "delete"; 28 | } 29 | 30 | @Permissions("user:delete") 31 | @POST("deleteUser") 32 | public RestResponse deleteUser() { 33 | return RestResponse.ok(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /blade-vue-todolist/src/main/java/com/blade/demo/vue/Todo.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.vue; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2017/9/28 6 | */ 7 | public class Todo { 8 | 9 | public static final String ACTIVE = "active"; 10 | public static final String COMPLETED = "completed"; 11 | 12 | private String value; 13 | private String status; 14 | 15 | public Todo() { 16 | 17 | } 18 | 19 | public Todo(String value, String status) { 20 | this.value = value; 21 | this.status = status; 22 | } 23 | 24 | public String getValue() { 25 | return value; 26 | } 27 | 28 | public void setValue(String value) { 29 | this.value = value; 30 | } 31 | 32 | public String getStatus() { 33 | return status; 34 | } 35 | 36 | public void setStatus(String status) { 37 | this.status = status; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return "Todo(value='" + value + ", status='" + status + ')'; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /blade-test/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-test 13 | 14 | 15 | 16 | junit 17 | junit 18 | 4.12 19 | test 20 | 21 | 22 | com.mashape.unirest 23 | unirest-java 24 | 1.4.9 25 | test 26 | 27 | 28 | -------------------------------------------------------------------------------- /blade-lattice/src/main/java/com/bladejava/lattice/bootstrap/MyRealm.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.lattice.bootstrap; 2 | 3 | import com.bladejava.lattice.model.User; 4 | import com.hellokaton.lattice.AuthInfo; 5 | import com.hellokaton.lattice.LatticeRealm; 6 | import com.hellokaton.lattice.LoginToken; 7 | import com.hellokaton.lattice.exception.UnknownAccountException; 8 | 9 | /** 10 | * @author hellokaton 11 | * @date 2022/5/4 12 | */ 13 | public class MyRealm implements LatticeRealm { 14 | 15 | @Override 16 | public AuthInfo doAuthenticate(LoginToken loginToken) { 17 | AuthInfo authInfo = new AuthInfo<>(); 18 | if (!"hellokaton".equals(loginToken.getUsername())) { 19 | throw new UnknownAccountException(); 20 | } 21 | authInfo.setUsername(loginToken.getUsername()); 22 | authInfo.setUser(new User("hellokaton", "123456", 18, "王爵nice")); 23 | 24 | return authInfo; 25 | } 26 | 27 | @Override 28 | public void doAuthorize(AuthInfo authInfo) { 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /blade-csrf-token/src/main/java/com/bladejava/demo/csrf/CSRFApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.csrf; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.security.csrf.CsrfMiddleware; 5 | 6 | /** 7 | * CSRF Token Example 8 | * 9 | * 一个请求发送后 token 会被存储在 request context, 10 | * 你可以通过 request.attribute("_csrf_token") 获取。 11 | * 也可以通过在模板文件中输出一个 input, 通过 request.attribute("_csrf_token_input") 获取。 12 | * 13 | * 客户端在发送 POST 请求的时候必须至少包含以下一个参数 14 | * 15 | * 1. 在 header 中传递 X-CSRF-TOKEN, 值为 token 16 | * 2. 在 header 中传递 X-XSRF-TOKEN, 值为 token 17 | * 3. 在 form 表单中传递 _token, 值为 token 18 | * 19 | * @author biezhi 20 | * @date 2018/7/30 21 | */ 22 | public class CSRFApplication { 23 | 24 | public static void main(String[] args) { 25 | Blade.create() 26 | .get("/", ctx -> ctx.text("token: " + ctx.request().attribute("_csrf_token"))) 27 | .post("/", ctx -> ctx.text("Access OK!")) 28 | .use(new CsrfMiddleware()) 29 | .start(CSRFApplication.class, args); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /blade-route/src/main/java/com/blade/demo/route/UserController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.route; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.request.Form; 5 | import com.hellokaton.blade.annotation.route.POST; 6 | import com.hellokaton.blade.mvc.ui.ResponseType; 7 | import com.hellokaton.blade.mvc.ui.RestResponse; 8 | 9 | /** 10 | * @author biezhi 11 | * @date 2022/5/3 12 | */ 13 | @Path(value = "user", responseType = ResponseType.JSON) 14 | public class UserController { 15 | 16 | @POST("save") 17 | public RestResponse saveUser(@Form String username, @Form String password) { 18 | System.out.println("username => " + username); 19 | System.out.println("password => " + password); 20 | return RestResponse.ok(); 21 | } 22 | 23 | @POST("save-by-model") 24 | public RestResponse saveUserByModel(User user) { 25 | System.out.println("username => " + user.getUsername()); 26 | System.out.println("password => " + user.getPassword()); 27 | return RestResponse.ok(); 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /blade-cors/src/main/java/com/blade/demo/cors/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.cors; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.hellokaton.blade.mvc.ui.ResponseType; 6 | import com.hellokaton.blade.mvc.ui.RestResponse; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Date; 10 | import java.util.List; 11 | 12 | /** 13 | * @author psh 14 | * @date 2018/11/2 15 | */ 16 | @Path 17 | public class IndexController { 18 | 19 | @GET 20 | public String index() { 21 | return "index.html"; 22 | } 23 | 24 | @GET(value = "users", responseType = ResponseType.JSON) 25 | public RestResponse> users() { 26 | List users = this.buildUsers(); 27 | return RestResponse.ok(users); 28 | } 29 | 30 | private List buildUsers() { 31 | List users = new ArrayList<>(); 32 | User sam = new User(1, "sam", 22, new Date()); 33 | User tom = new User(2, "tom", 23, new Date()); 34 | users.add(sam); 35 | users.add(tom); 36 | return users; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /blade-mongo/src/main/java/com/blade/demo/mongo/MongoConfig.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.mongo; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.ioc.annotation.Bean; 5 | import com.hellokaton.blade.loader.BladeLoader; 6 | import com.mongodb.MongoClient; 7 | import com.mongodb.client.MongoDatabase; 8 | 9 | /** 10 | * @author biezhi 11 | * @date 2018/4/27 12 | */ 13 | @Bean 14 | public class MongoConfig implements BladeLoader { 15 | 16 | private static MongoDatabase mongoDatabase; 17 | 18 | public static MongoDatabase getMongoDatabase() { 19 | return mongoDatabase; 20 | } 21 | 22 | @Override 23 | public void load(Blade blade) { 24 | MongoClient mongoClient = new MongoClient("localhost"); 25 | // MongoClient mongoClient = new MongoClient("localhost", 27017); 26 | // MongoClientURI connectionString = new MongoClientURI("mongodb://localhost:27017"); 27 | // MongoClient mongoClient = new MongoClient(connectionString); 28 | 29 | mongoDatabase = mongoClient.getDatabase("blade_demo"); 30 | System.out.println(mongoDatabase.getName()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /blade-upload/src/main/java/com/blade/demo/upload/UploadController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.upload; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.request.Multipart; 5 | import com.hellokaton.blade.annotation.route.GET; 6 | import com.hellokaton.blade.annotation.route.POST; 7 | import com.hellokaton.blade.kit.BladeKit; 8 | import com.hellokaton.blade.mvc.multipart.FileItem; 9 | import com.hellokaton.blade.mvc.ui.RestResponse; 10 | 11 | import java.io.IOException; 12 | import java.nio.file.Paths; 13 | 14 | /** 15 | * 上传文件控制器 16 | * 17 | * @author biezhi 18 | * @date 2017/10/1 19 | */ 20 | @Path 21 | public class UploadController { 22 | 23 | @GET 24 | public String index() { 25 | return "upload.html"; 26 | } 27 | 28 | @POST("upload") 29 | public RestResponse doUpload(@Multipart FileItem fileItem) throws IOException { 30 | if (null != fileItem) { 31 | fileItem.moveTo(Paths.get(BladeKit.getCurrentClassPath() + "/upload/" + fileItem.getFileName())); 32 | return RestResponse.ok(); 33 | } 34 | return RestResponse.fail("没有文件上传"); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /blade-anima/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-anima 13 | 14 | 15 | 16 | 17 | com.hellokaton 18 | anima 19 | 0.3.1 20 | 21 | 22 | 23 | com.alibaba 24 | druid 25 | 1.2.9 26 | 27 | 28 | 29 | mysql 30 | mysql-connector-java 31 | 5.1.47 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /blade-anima/src/main/java/com/bladejava/anima/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.anima; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.request.Body; 5 | import com.hellokaton.blade.annotation.request.PathParam; 6 | import com.hellokaton.blade.annotation.route.DELETE; 7 | import com.hellokaton.blade.annotation.route.GET; 8 | import com.hellokaton.blade.annotation.route.POST; 9 | import com.hellokaton.blade.mvc.ui.ResponseType; 10 | import com.hellokaton.blade.mvc.ui.RestResponse; 11 | 12 | import static com.hellokaton.anima.Anima.deleteById; 13 | import static com.hellokaton.anima.Anima.select; 14 | 15 | @Path(responseType = ResponseType.JSON) 16 | public class IndexController { 17 | 18 | @GET("users") 19 | public RestResponse users() { 20 | return RestResponse.ok(select().from(User.class).all()); 21 | } 22 | 23 | @POST("users") 24 | public RestResponse saveUser(@Body User user) { 25 | return RestResponse.ok(user.save().asInt()); 26 | } 27 | 28 | @DELETE("user/:uid") 29 | public RestResponse deleteUser(@PathParam Integer uid) { 30 | return RestResponse.ok(deleteById(User.class, uid)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /blade-upload/src/main/resources/templates/upload.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 |
11 |

12 | 查看文件列表 13 |

14 |
15 | 16 | 17 |
18 |
19 | 20 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /blade-websocket/src/main/java/com/bladejava/demo/ws/WebSocketApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.ws; 2 | 3 | import com.hellokaton.blade.Blade; 4 | 5 | /** 6 | * @author biezhi 7 | * @date 2018/8/16 8 | */ 9 | public class WebSocketApplication { 10 | 11 | public static void main(String[] args) { 12 | Blade.create() 13 | .get("/", ctx -> ctx.render("index.html")) 14 | // .webSocket("/chat", new WebSocketHandler() { 15 | // @Override 16 | // public void onConnect(WebSocketContext ctx) { 17 | // System.out.println("有新连接: " + ctx); 18 | // } 19 | // 20 | // @Override 21 | // public void onText(WebSocketContext ctx) { 22 | // System.out.println("有新消息: " + ctx.getReqText()); 23 | // ctx.message("服务器返回:" + ctx.getReqText()); 24 | // } 25 | // 26 | // @Override 27 | // public void onDisConnect(WebSocketContext ctx) { 28 | // System.out.println("有断开连接: " + ctx); 29 | // } 30 | // }) 31 | .start(WebSocketApplication.class, args); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /blade-anima/README.md: -------------------------------------------------------------------------------- 1 | # blade-anima 2 | 3 | 1. 导入数据库结构和数据 `resources/schema.sql` 4 | 2. 启动 `DBApplication.java` 5 | 6 | ## 测试 7 | 8 | 获取所有用户 9 | 10 | ```shell 11 | curl -i http://127.0.0.1:9000/users 12 | 13 | HTTP/1.1 200 OK 14 | Content-Length: 391 15 | Date: Tue, 27 Nov 2018 16:30:29 GMT 16 | X-Powered-By: blade-2.0.12.BETA 17 | Set-Cookie: SESSION=thiim3pjq4hvgpmf64ilj4hiei; Path=/; HTTPOnly 18 | Content-Type: application/json; charset=UTF-8 19 | Connection: keep-alive 20 | 21 | {"payload":[{"id":1,"username":"jack","password":"aaa","realName":"杰克","age":32},{"id":2,"username":"rose","password":"999","realName":"螺丝","age":29},{"id":3,"username":"biezhi","password":"123556","realName":"魔王不造反","age":19},{"id":4,"username":"codesofun","password":"123556","realName":"代码真香","age":20}],"success":true,"msg":null,"code":0,"timestamp":1543307430} 22 | ``` 23 | 24 | 添加一个用户 25 | 26 | ```shell 27 | curl -X POST http://127.0.0.1:9000/users \ 28 | -H 'Content-Type: application/json' \ 29 | -d '{"username":"test","password":"123456","realName":"测试数据","age": 10}' 30 | 31 | {"payload":5,"success":true,"msg":null,"code":0,"timestamp":1543307570} 32 | ``` 33 | 34 | 删除一个用户 35 | 36 | ```shell 37 | curl -X DELETE http://127.0.0.1:9000/user/5 38 | 39 | {"payload":1,"success":true,"msg":null,"code":0,"timestamp":1543307647} 40 | ``` -------------------------------------------------------------------------------- /blade-package/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | customAssembly 7 | 8 | 9 | dir 10 | 11 | 12 | false 13 | 14 | 15 | 16 | src/main/resources/ 17 | /resources 18 | 19 | 20 | 21 | 22 | 23 | /lib 24 | runtime 25 | 26 | ${project.groupId}:${project.artifactId} 27 | 28 | 29 | 30 | / 31 | 32 | ${project.groupId}:${project.artifactId} 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /blade-lattice/src/main/java/com/bladejava/lattice/model/User.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.lattice.model; 2 | 3 | /** 4 | * @author biezhi 5 | * @date 2018/6/4 6 | */ 7 | public class User { 8 | 9 | private String username; 10 | private String password; 11 | private Integer age; 12 | private String nickname; 13 | 14 | public User() { 15 | } 16 | 17 | public User(String username, String password, Integer age, String nickname) { 18 | this.username = username; 19 | this.password = password; 20 | this.age = age; 21 | this.nickname = nickname; 22 | } 23 | 24 | public String getUsername() { 25 | return username; 26 | } 27 | 28 | public void setUsername(String username) { 29 | this.username = username; 30 | } 31 | 32 | public String getPassword() { 33 | return password; 34 | } 35 | 36 | public void setPassword(String password) { 37 | this.password = password; 38 | } 39 | 40 | public Integer getAge() { 41 | return age; 42 | } 43 | 44 | public void setAge(Integer age) { 45 | this.age = age; 46 | } 47 | 48 | public String getNickname() { 49 | return nickname; 50 | } 51 | 52 | public void setNickname(String nickname) { 53 | this.nickname = nickname; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /blade-download/src/main/java/com/bladejava/demo/download/DownloadApplication.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.download; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.mvc.http.ByteBody; 5 | 6 | import java.io.File; 7 | 8 | /** 9 | * 访问 10 | *

11 | * http://127.0.0.1:9000/download1 12 | * http://127.0.0.1:9000/download2 13 | * 14 | * @author biezhi 15 | * @date 2022/5/3 16 | * @since blade-2.1.0.BETA 17 | */ 18 | public class DownloadApplication { 19 | 20 | public static void main(String[] args) { 21 | Blade.create() 22 | .get("/download1", ctx -> { 23 | File file = new File("blade-download/src/main/resources/static/octo.png"); 24 | ctx.response().contentType("image/png"); 25 | ctx.response().header("Content-Disposition", "attachment; filename=hello.png"); 26 | ctx.response().body(ByteBody.of(file)); 27 | }) 28 | .get("/download2", ctx -> { 29 | String str = "hello world"; 30 | ctx.response().contentType("text/plain; charset=UTF-8"); 31 | ctx.response().header("Content-Disposition", "attachment; filename=hello.txt"); 32 | ctx.response().body(ByteBody.of(str.getBytes())); 33 | }) 34 | .start(DownloadApplication.class, args); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /blade-anima/src/main/java/com/bladejava/anima/User.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.anima; 2 | 3 | import com.hellokaton.anima.Model; 4 | import com.hellokaton.anima.annotation.Table; 5 | 6 | /** 7 | * User Entity 8 | *

9 | * default table name is 'users' 10 | * 11 | * @author biezhi 12 | * @date 2018-11-27 13 | */ 14 | @Table(name = "t_user") 15 | public class User extends Model { 16 | 17 | private Integer id; 18 | private String username; 19 | private String password; 20 | private String realName; 21 | private Integer age; 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public String getUsername() { 32 | return username; 33 | } 34 | 35 | public void setUsername(String username) { 36 | this.username = username; 37 | } 38 | 39 | public String getPassword() { 40 | return password; 41 | } 42 | 43 | public void setPassword(String password) { 44 | this.password = password; 45 | } 46 | 47 | public String getRealName() { 48 | return realName; 49 | } 50 | 51 | public void setRealName(String realName) { 52 | this.realName = realName; 53 | } 54 | 55 | public Integer getAge() { 56 | return age; 57 | } 58 | 59 | public void setAge(Integer age) { 60 | this.age = age; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /blade-template/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 登陆页面 6 | 7 | 8 | 9 | 10 |

11 |
12 | 13 |

14 | 25 | 26 | 忘记密码? 27 | 28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /blade-test/src/main/java/com/bladejava/demo/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.bladejava.demo.controller; 2 | 3 | import com.bladejava.demo.model.User; 4 | import com.bladejava.demo.service.UserService; 5 | import com.hellokaton.blade.annotation.Path; 6 | import com.hellokaton.blade.annotation.request.Body; 7 | import com.hellokaton.blade.annotation.request.PathParam; 8 | import com.hellokaton.blade.annotation.route.GET; 9 | import com.hellokaton.blade.annotation.route.POST; 10 | import com.hellokaton.blade.ioc.annotation.Inject; 11 | import com.hellokaton.blade.kit.StringKit; 12 | import com.hellokaton.blade.mvc.ui.ResponseType; 13 | import com.hellokaton.blade.mvc.ui.RestResponse; 14 | 15 | import java.util.Collections; 16 | 17 | /** 18 | * @author biezhi 19 | * @date 2018/5/31 20 | */ 21 | @Path(value = "user", responseType = ResponseType.JSON) 22 | public class UserController { 23 | 24 | @Inject 25 | private UserService userService; 26 | 27 | @POST("save") 28 | public RestResponse saveUser(@Body User user) { 29 | return RestResponse.ok(userService.saveUser(user)); 30 | } 31 | 32 | @GET("list") 33 | public RestResponse list() { 34 | return RestResponse.ok(Collections.singletonList(new User(123L, "biezhi"))); 35 | } 36 | 37 | @GET("detail/:uid") 38 | public RestResponse detail(@PathParam Long uid) { 39 | return RestResponse.ok(new User(uid, StringKit.rand(10))); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /blade-verify-code/src/main/java/com/blade/demo/verifycode/VerifyCodeApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.verifycode; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.options.HttpOptions; 5 | import com.hellokaton.blade.patchca.DefaultPatchca; 6 | import com.hellokaton.blade.patchca.PatchcaException; 7 | 8 | /** 9 | * Blade Patcha Example 10 | *

11 | * 1. generate code 12 | * http://127.0.0.1:9000/code 13 | *

14 | * 2. verify code 15 | * http://127.0.0.1:9000/verify?code=LmCGY 16 | * 17 | * @author hellokaton 18 | * @date 2022/5/4 19 | */ 20 | public class VerifyCodeApplication { 21 | 22 | public static void main(String[] args) { 23 | 24 | // 这行代码应该放在启动时加载 25 | DefaultPatchca patchca = new DefaultPatchca(); 26 | 27 | Blade.create() 28 | .get("/code", ctx -> { 29 | try { 30 | String code = patchca.render(); 31 | System.out.println("verify code: " + code); 32 | } catch (PatchcaException e) { 33 | System.out.println("Patchca Error: " + e.getMessage()); 34 | } 35 | }) 36 | .get("/verify", ctx -> { 37 | String code = ctx.request().query("code", "CODE"); 38 | boolean success = patchca.verify(code); 39 | ctx.text("verify result: " + success); 40 | }) 41 | .http(HttpOptions::enableSession) 42 | .start(VerifyCodeApplication.class, args); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /blade-mongo/src/main/java/com/blade/demo/mongo/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.mongo; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.route.GET; 5 | import com.mongodb.client.MongoCollection; 6 | import com.mongodb.client.MongoCursor; 7 | import org.bson.Document; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.util.Arrays; 12 | 13 | /** 14 | * @author biezhi 15 | * @date 2018/4/27 16 | */ 17 | @Path 18 | public class IndexController { 19 | 20 | private static final Logger log = LoggerFactory.getLogger(IndexController.class); 21 | 22 | @GET("/read") 23 | public void read() { 24 | MongoCollection collection = MongoConfig.getMongoDatabase().getCollection("test"); 25 | MongoCursor cursor = collection.find().iterator(); 26 | 27 | try { 28 | while (cursor.hasNext()) { 29 | log.info(cursor.next().toJson()); 30 | } 31 | } finally { 32 | cursor.close(); 33 | } 34 | } 35 | 36 | @GET("/write") 37 | public void write() { 38 | MongoCollection collection = MongoConfig.getMongoDatabase().getCollection("test"); 39 | 40 | Document doc = new Document("name", "MongoDB") 41 | .append("type", "database") 42 | .append("count", 1) 43 | .append("versions", Arrays.asList("v3.2", "v3.0", "v2.6")) 44 | .append("info", new Document("x", 203).append("y", 102)); 45 | 46 | collection.insertOne(doc); 47 | 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /blade-ajax/src/main/java/com/blade/demo/ajax/User.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.ajax; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * User 7 | */ 8 | public class User { 9 | 10 | private Integer id; 11 | private String userName; 12 | private Integer age; 13 | private Date birthday; 14 | 15 | public User(){ 16 | 17 | } 18 | 19 | public User(Integer id, String userName, Integer age, Date birthday){ 20 | this.id = id; 21 | this.userName = userName; 22 | this.age = age; 23 | this.birthday = birthday; 24 | } 25 | 26 | /** 27 | * @return the id 28 | */ 29 | public Integer getId() { 30 | return id; 31 | } 32 | 33 | /** 34 | * @param id the id to set 35 | */ 36 | public void setId(Integer id) { 37 | this.id = id; 38 | } 39 | 40 | /** 41 | * @return the userName 42 | */ 43 | public String getUserName() { 44 | return userName; 45 | } 46 | 47 | /** 48 | * @param userName the userName to set 49 | */ 50 | public void setUserName(String userName) { 51 | this.userName = userName; 52 | } 53 | 54 | /** 55 | * @return the birthday 56 | */ 57 | public Date getBirthday() { 58 | return birthday; 59 | } 60 | 61 | /** 62 | * @param birthday the birthday to set 63 | */ 64 | public void setBirthday(Date birthday) { 65 | this.birthday = birthday; 66 | } 67 | 68 | /** 69 | * @return the age 70 | */ 71 | public Integer getAge() { 72 | return age; 73 | } 74 | 75 | /** 76 | * @param age the age to set 77 | */ 78 | public void setAge(Integer age) { 79 | this.age = age; 80 | } 81 | 82 | } -------------------------------------------------------------------------------- /blade-cors/src/main/java/com/blade/demo/cors/User.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.cors; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * User 7 | */ 8 | public class User { 9 | 10 | private Integer id; 11 | private String userName; 12 | private Integer age; 13 | private Date birthday; 14 | 15 | public User(){ 16 | 17 | } 18 | 19 | public User(Integer id, String userName, Integer age, Date birthday){ 20 | this.id = id; 21 | this.userName = userName; 22 | this.age = age; 23 | this.birthday = birthday; 24 | } 25 | 26 | /** 27 | * @return the id 28 | */ 29 | public Integer getId() { 30 | return id; 31 | } 32 | 33 | /** 34 | * @param id the id to set 35 | */ 36 | public void setId(Integer id) { 37 | this.id = id; 38 | } 39 | 40 | /** 41 | * @return the userName 42 | */ 43 | public String getUserName() { 44 | return userName; 45 | } 46 | 47 | /** 48 | * @param userName the userName to set 49 | */ 50 | public void setUserName(String userName) { 51 | this.userName = userName; 52 | } 53 | 54 | /** 55 | * @return the birthday 56 | */ 57 | public Date getBirthday() { 58 | return birthday; 59 | } 60 | 61 | /** 62 | * @param birthday the birthday to set 63 | */ 64 | public void setBirthday(Date birthday) { 65 | this.birthday = birthday; 66 | } 67 | 68 | /** 69 | * @return the age 70 | */ 71 | public Integer getAge() { 72 | return age; 73 | } 74 | 75 | /** 76 | * @param age the age to set 77 | */ 78 | public void setAge(Integer age) { 79 | this.age = age; 80 | } 81 | 82 | } -------------------------------------------------------------------------------- /blade-static/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-static 13 | 14 | 15 | blade-static 16 | 17 | 18 | maven-assembly-plugin 19 | 20 | ${project.build.finalName} 21 | false 22 | 23 | 24 | com.hellokaton.staticdir.StaticApplication 25 | 26 | 27 | 28 | jar-with-dependencies 29 | 30 | 31 | 32 | 33 | make-assembly 34 | package 35 | 36 | single 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /blade-helloworld/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | 12 | blade-helloworld 13 | 14 | 15 | helloworld 16 | 17 | 18 | maven-assembly-plugin 19 | 20 | ${project.build.finalName} 21 | false 22 | 23 | 24 | com.blade.demo.helloworld.HelloApplication 25 | 26 | 27 | 28 | jar-with-dependencies 29 | 30 | 31 | 32 | 33 | make-assembly 34 | package 35 | 36 | single 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /blade-kit-example/src/main/java/com/blade/demo/kit/model/User.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.kit.model; 2 | 3 | 4 | import java.util.Date; 5 | 6 | /** 7 | * @author biezhi 8 | * @date 2017/12/20 9 | */ 10 | public class User { 11 | 12 | private String username; 13 | private Integer age; 14 | private double money; 15 | 16 | // @JsonFormat(value = "yyyy年MM月dd日 HH:mm", type = MappingType.DATE_PATTEN) 17 | private Date birthday; 18 | private Boolean sex; 19 | private Byte status; 20 | 21 | public String getUsername() { 22 | return username; 23 | } 24 | 25 | public void setUsername(String username) { 26 | this.username = username; 27 | } 28 | 29 | public Integer getAge() { 30 | return age; 31 | } 32 | 33 | public void setAge(Integer age) { 34 | this.age = age; 35 | } 36 | 37 | public double getMoney() { 38 | return money; 39 | } 40 | 41 | public void setMoney(double money) { 42 | this.money = money; 43 | } 44 | 45 | public Date getBirthday() { 46 | return birthday; 47 | } 48 | 49 | public void setBirthday(Date birthday) { 50 | this.birthday = birthday; 51 | } 52 | 53 | public Boolean getSex() { 54 | return sex; 55 | } 56 | 57 | public void setSex(Boolean sex) { 58 | this.sex = sex; 59 | } 60 | 61 | public Byte getStatus() { 62 | return status; 63 | } 64 | 65 | public void setStatus(Byte status) { 66 | this.status = status; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return "User(" + 72 | "username='" + username + '\'' + 73 | ", age=" + age + 74 | ", money=" + money + 75 | ", birthday=" + birthday + 76 | ", sex=" + sex + 77 | ", status=" + status + 78 | ')'; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /blade-task/src/main/java/com/blade/demo/task/TaskExample.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.task; 2 | 3 | import com.hellokaton.blade.ioc.annotation.Bean; 4 | import com.hellokaton.blade.kit.DateKit; 5 | import com.hellokaton.blade.task.TaskContext; 6 | import com.hellokaton.blade.task.TaskManager; 7 | import com.hellokaton.blade.task.annotation.Schedule; 8 | 9 | import java.time.LocalDateTime; 10 | import java.util.concurrent.atomic.AtomicInteger; 11 | 12 | /** 13 | * Task Example 14 | * 15 | * @author biezhi 16 | * @date 2018/4/12 17 | */ 18 | @Bean 19 | public class TaskExample { 20 | 21 | /** 22 | * 每秒执行一次 23 | */ 24 | @Schedule(cron = "* * * * * ?") 25 | public void one() { 26 | System.out.println("每秒钟执行一次,现在是: " + DateKit.toString(LocalDateTime.now())); 27 | } 28 | 29 | /** 30 | * 每五秒执行一次 31 | */ 32 | @Schedule(name = "taskTwo", cron = "*/5 * * * * ?") 33 | public void two() { 34 | System.out.println("每五秒钟执行一次,现在是: " + DateKit.toString(LocalDateTime.now())); 35 | } 36 | 37 | private AtomicInteger size = new AtomicInteger(); 38 | 39 | /** 40 | * 每秒执行一次,当 size == 3 时停止 41 | * 42 | * @param taskContext 43 | */ 44 | @Schedule(cron = "* * * * * ?") 45 | public void three(TaskContext taskContext) { 46 | if (size.getAndIncrement() == 3) { 47 | return; 48 | } 49 | System.out.println("Task Three: " + size.get()); 50 | } 51 | 52 | private AtomicInteger fourSize = new AtomicInteger(); 53 | 54 | /** 55 | * 每秒执行一次,10秒后开始执行 56 | *

57 | * 使用静态方法 TaskManager.stopTask 停止任务 58 | */ 59 | @Schedule(name = "fourTask", cron = "* * * * * ?", delay = 1000L) 60 | public void four() { 61 | if (fourSize.getAndIncrement() == 2) { 62 | TaskManager.stopTask("fourTask"); 63 | return; 64 | } 65 | System.out.println("Four Task: " + fourSize.get()); 66 | } 67 | 68 | @Schedule(name = "expression_demo", cron = "${task_exp}") 69 | public void expressionDemo() { 70 | System.out.println(LocalDateTime.now() + ": 我是表达式的例子"); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /blade-websocket/src/main/resources/static/main.css: -------------------------------------------------------------------------------- 1 | *, *:before, *:after { 2 | -moz-box-sizing: border-box; 3 | -webkit-box-sizing: border-box; 4 | box-sizing: border-box; 5 | } 6 | 7 | html { 8 | font-family: Helvetica, Arial, sans-serif; 9 | font-size: 100%; 10 | background: #333; 11 | } 12 | 13 | #page-wrapper { 14 | width: 650px; 15 | background: #FFF; 16 | padding: 1em; 17 | margin: 1em auto; 18 | border-top: 5px solid #69c773; 19 | box-shadow: 0 2px 10px rgba(0,0,0,0.8); 20 | } 21 | 22 | h1 { 23 | margin-top: 0; 24 | } 25 | 26 | #status { 27 | font-size: 0.9rem; 28 | margin-bottom: 1rem; 29 | } 30 | 31 | .open { 32 | color: green; 33 | } 34 | 35 | .closed { 36 | color: red; 37 | } 38 | 39 | 40 | ul { 41 | list-style: none; 42 | margin: 0; 43 | padding: 0; 44 | font-size: 0.95rem; 45 | } 46 | 47 | ul li { 48 | padding: 0.5rem 0.75rem; 49 | border-bottom: 1px solid #EEE; 50 | } 51 | 52 | ul li:first-child { 53 | border-top: 1px solid #EEE; 54 | } 55 | 56 | ul li span { 57 | display: inline-block; 58 | width: 90px; 59 | font-weight: bold; 60 | color: #999; 61 | font-size: 0.7rem; 62 | text-transform: uppercase; 63 | letter-spacing: 1px; 64 | } 65 | 66 | .sent { 67 | background-color: #F7F7F7; 68 | } 69 | 70 | .received {} 71 | 72 | #message-form { 73 | margin-top: 1.5rem; 74 | } 75 | 76 | textarea { 77 | width: 100%; 78 | padding: 0.5rem; 79 | font-size: 1rem; 80 | border: 1px solid #D9D9D9; 81 | border-radius: 3px; 82 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1); 83 | min-height: 100px; 84 | margin-bottom: 1rem; 85 | } 86 | 87 | button { 88 | display: inline-block; 89 | border-radius: 3px; 90 | border: none; 91 | font-size: 0.9rem; 92 | padding: 0.6rem 1em; 93 | color: white; 94 | margin: 0 0.25rem; 95 | text-align: center; 96 | background: #BABABA; 97 | border-bottom: 1px solid #999; 98 | } 99 | 100 | button[type="submit"] { 101 | background: #86b32d; 102 | border-bottom: 1px solid #5d7d1f; 103 | } 104 | 105 | button:hover { 106 | opacity: 0.75; 107 | cursor: pointer; 108 | } 109 | -------------------------------------------------------------------------------- /blade-websocket/src/main/resources/static/main.js: -------------------------------------------------------------------------------- 1 | window.onload = function() { 2 | 3 | // Get references to elements on the page. 4 | var form = document.getElementById('message-form'); 5 | var messageField = document.getElementById('message'); 6 | var messagesList = document.getElementById('messages'); 7 | var socketStatus = document.getElementById('status'); 8 | var closeBtn = document.getElementById('close'); 9 | 10 | 11 | // Create a new WebSocket. 12 | var socket = new WebSocket('ws://127.0.0.1:9000/chat'); 13 | 14 | // Handle any errors that occur. 15 | socket.onerror = function(error) { 16 | console.log('WebSocket Error: ' + error); 17 | }; 18 | 19 | // Show a connected message when the WebSocket is opened. 20 | socket.onopen = function(event) { 21 | socketStatus.innerHTML = '连接到: ' + event.currentTarget.url; 22 | socketStatus.className = 'open'; 23 | }; 24 | 25 | 26 | // Handle messages sent by the server. 27 | socket.onmessage = function(event) { 28 | var message = event.data; 29 | messagesList.innerHTML += '

  • Received:' + message + '
  • '; 30 | }; 31 | 32 | 33 | // Show a disconnected message when the WebSocket is closed. 34 | socket.onclose = function(event) { 35 | socketStatus.innerHTML = '断开 WebSocket 连接'; 36 | socketStatus.className = 'closed'; 37 | }; 38 | 39 | 40 | // Send a message when the form is submitted. 41 | form.onsubmit = function(e) { 42 | e.preventDefault(); 43 | 44 | // Retrieve the message from the textarea. 45 | var message = messageField.value; 46 | 47 | // Send the message through the WebSocket. 48 | socket.send(message); 49 | 50 | // Add the message to the messages list. 51 | messagesList.innerHTML += '
  • Sent:' + message + '
  • '; 52 | 53 | // Clear out the message field. 54 | messageField.value = ''; 55 | 56 | return false; 57 | }; 58 | 59 | 60 | // Close the WebSocket connection when the close button is clicked. 61 | closeBtn.onclick = function(e) { 62 | e.preventDefault(); 63 | 64 | // Close the WebSocket. 65 | socket.close(); 66 | 67 | return false; 68 | }; 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /blade-vue-todolist/src/main/java/com/blade/demo/vue/TodoApplication.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.vue; 2 | 3 | import com.hellokaton.blade.Blade; 4 | import com.hellokaton.blade.kit.StringKit; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author hellokaton 11 | * @date 2022/5/3 12 | */ 13 | public class TodoApplication { 14 | 15 | private static final List todoList = new ArrayList<>(); 16 | 17 | public static void main(String[] args) { 18 | Blade.create() 19 | .get("/", ctx -> ctx.render("index.html")) 20 | .post("/add", ctx -> { 21 | String todo = ctx.query("todo"); 22 | if (StringKit.isNotBlank(todo)) { 23 | todoList.add(new Todo(todo, Todo.ACTIVE)); 24 | } 25 | System.out.println("TodoList: " + todoList); 26 | ctx.text("success"); 27 | }) 28 | .post("/edit", ctx -> { 29 | String todo = ctx.query("oldTodo"); 30 | if (StringKit.isNotBlank(todo)) { 31 | todoList.stream().filter(t -> t.getValue().equals(todo)) 32 | .findFirst() 33 | .ifPresent(todoModel -> todoModel.setValue(todo)); 34 | } 35 | System.out.println("TodoList: " + todoList); 36 | ctx.text("success"); 37 | }) 38 | .post("/remove", ctx -> { 39 | String todo = ctx.query("todo"); 40 | if (StringKit.isNotBlank(todo)) { 41 | todoList.stream().filter(t -> t.getValue().equals(todo)) 42 | .findFirst() 43 | .ifPresent(todoList::remove); 44 | } 45 | System.out.println("TodoList: " + todoList); 46 | ctx.text("success"); 47 | }) 48 | .post("/status/:status", ctx -> { 49 | String status = ctx.pathString("status"); 50 | ctx.request().form("todo") 51 | .flatMap(todo -> todoList.stream().filter(t -> t.getValue().equals(todo)) 52 | .findFirst()).ifPresent(todoModel -> todoModel.setStatus(status)); 53 | System.out.println("TodoList: " + todoList); 54 | ctx.text("success"); 55 | }) 56 | .post("/clean", ctx -> { 57 | todoList.clear(); 58 | ctx.text("success"); 59 | }) 60 | .start(TodoApplication.class, args); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /blade-template/src/main/resources/static/main.js: -------------------------------------------------------------------------------- 1 | $( document ).ready(function() { 2 | // DOM ready 3 | 4 | // Test data 5 | /* 6 | * To test the script you should discomment the function 7 | * testLocalStorageData and refresh the page. The function 8 | * will load some test data and the loadProfile 9 | * will do the changes in the UI 10 | */ 11 | // testLocalStorageData(); 12 | // Load profile if it exits 13 | loadProfile(); 14 | }); 15 | 16 | /** 17 | * Function that gets the data of the profile in case 18 | * thar it has already saved in localstorage. Only the 19 | * UI will be update in case that all data is available 20 | * 21 | * A not existing key in localstorage return null 22 | * 23 | */ 24 | function getLocalProfile(callback){ 25 | var profileImgSrc = localStorage.getItem("PROFILE_IMG_SRC"); 26 | var profileName = localStorage.getItem("PROFILE_NAME"); 27 | var profileReAuthEmail = localStorage.getItem("PROFILE_REAUTH_EMAIL"); 28 | 29 | if(profileName !== null 30 | && profileReAuthEmail !== null 31 | && profileImgSrc !== null) { 32 | callback(profileImgSrc, profileName, profileReAuthEmail); 33 | } 34 | } 35 | 36 | /** 37 | * Main function that load the profile if exists 38 | * in localstorage 39 | */ 40 | function loadProfile() { 41 | if(!supportsHTML5Storage()) { return false; } 42 | // we have to provide to the callback the basic 43 | // information to set the profile 44 | getLocalProfile(function(profileImgSrc, profileName, profileReAuthEmail) { 45 | //changes in the UI 46 | $("#profile-img").attr("src",profileImgSrc); 47 | $("#profile-name").html(profileName); 48 | $("#reauth-email").html(profileReAuthEmail); 49 | $("#inputEmail").hide(); 50 | $("#remember").hide(); 51 | }); 52 | } 53 | 54 | /** 55 | * function that checks if the browser supports HTML5 56 | * local storage 57 | * 58 | * @returns {boolean} 59 | */ 60 | function supportsHTML5Storage() { 61 | try { 62 | return 'localStorage' in window && window['localStorage'] !== null; 63 | } catch (e) { 64 | return false; 65 | } 66 | } 67 | 68 | /** 69 | * Test data. This data will be safe by the web app 70 | * in the first successful login of a auth user. 71 | * To Test the scripts, delete the localstorage data 72 | * and comment this call. 73 | * 74 | * @returns {boolean} 75 | */ 76 | function testLocalStorageData() { 77 | if(!supportsHTML5Storage()) { return false; } 78 | localStorage.setItem("PROFILE_IMG_SRC", "//lh3.googleusercontent.com/-6V8xOA6M7BA/AAAAAAAAAAI/AAAAAAAAAAA/rzlHcD0KYwo/photo.jpg?sz=120" ); 79 | localStorage.setItem("PROFILE_NAME", "César Izquierdo Tello"); 80 | localStorage.setItem("PROFILE_REAUTH_EMAIL", "oneaccount@gmail.com"); 81 | } -------------------------------------------------------------------------------- /blade-vue-todolist/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Blade & Vue.js • TodoList 6 | 7 | 8 | 9 | 10 | 11 |
    12 |
    13 |

    Blade Todos

    14 | 19 |
    20 |
    21 | 22 |
      23 |
    • 27 |
      28 | 29 | 30 | 31 |
      32 | 38 |
    • 39 |
    40 |
    41 |
    42 | 43 | {{ remaining }} {{ remaining | pluralize }} left 44 | 45 | 50 | 53 |
    54 |
    55 |
    56 |

    双击编辑Todo

    57 |

    Written by biezhi

    58 |

    Part of TodoMVC

    59 |
    60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Eclipse template 3 | 4 | .metadata 5 | bin/ 6 | tmp/ 7 | *.tmp 8 | *.bak 9 | *.swp 10 | *~.nib 11 | local.properties 12 | .settings/ 13 | .loadpath 14 | .recommenders 15 | *.project 16 | *.classpath 17 | .settings 18 | *.iml 19 | .idea 20 | 21 | # External tool builders 22 | .externalToolBuilders/ 23 | 24 | # Locally stored "Eclipse launch configurations" 25 | *.launch 26 | 27 | # PyDev specific (Python IDE for Eclipse) 28 | *.pydevproject 29 | 30 | # CDT-specific (C/C++ Development Tooling) 31 | .cproject 32 | 33 | # Java annotation processor (APT) 34 | .factorypath 35 | 36 | # PDT-specific (PHP Development Tools) 37 | .buildpath 38 | 39 | # sbteclipse plugin 40 | .target 41 | 42 | # Tern plugin 43 | .tern-project 44 | 45 | # TeXlipse plugin 46 | .texlipse 47 | 48 | # STS (Spring Tool Suite) 49 | .springBeans 50 | 51 | # Code Recommenders 52 | .recommenders/ 53 | 54 | # Scala IDE specific (Scala & Java development for Eclipse) 55 | .cache-main 56 | .scala_dependencies 57 | .worksheet 58 | ### Maven template 59 | target/ 60 | pom.xml.tag 61 | pom.xml.releaseBackup 62 | pom.xml.versionsBackup 63 | pom.xml.next 64 | release.properties 65 | dependency-reduced-pom.xml 66 | buildNumber.properties 67 | .mvn/timing.properties 68 | 69 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 70 | !/.mvn/wrapper/maven-wrapper.jar 71 | ### Java template 72 | # Compiled class file 73 | *.class 74 | 75 | # Log file 76 | *.log 77 | 78 | # BlueJ files 79 | *.ctxt 80 | 81 | # Mobile Tools for Java (J2ME) 82 | .mtj.tmp/ 83 | 84 | # Package Files # 85 | *.jar 86 | *.war 87 | *.ear 88 | *.zip 89 | *.tar.gz 90 | *.rar 91 | 92 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 93 | hs_err_pid* 94 | ### JetBrains template 95 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 96 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 97 | 98 | # User-specific stuff: 99 | .idea/**/workspace.xml 100 | .idea/**/tasks.xml 101 | .idea/dictionaries 102 | 103 | # Sensitive or high-churn files: 104 | .idea/**/dataSources/ 105 | .idea/**/dataSources.ids 106 | .idea/**/dataSources.xml 107 | .idea/**/dataSources.local.xml 108 | .idea/**/sqlDataSources.xml 109 | .idea/**/dynamic.xml 110 | .idea/**/uiDesigner.xml 111 | 112 | # Gradle: 113 | .idea/**/gradle.xml 114 | .idea/**/libraries 115 | 116 | # CMake 117 | cmake-build-debug/ 118 | 119 | # Mongo Explorer plugin: 120 | .idea/**/mongoSettings.xml 121 | 122 | ## File-based project format: 123 | *.iws 124 | 125 | ## Plugin-specific files: 126 | 127 | # IntelliJ 128 | out/ 129 | 130 | # mpeltonen/sbt-idea plugin 131 | .idea_modules/ 132 | 133 | # JIRA plugin 134 | atlassian-ide-plugin.xml 135 | 136 | # Cursive Clojure plugin 137 | .idea/replstate.xml 138 | 139 | # Crashlytics plugin (for Android Studio and IntelliJ) 140 | com_crashlytics_export_strings.xml 141 | crashlytics.properties 142 | crashlytics-build.properties 143 | fabric.properties 144 | 145 | -------------------------------------------------------------------------------- /blade-static/src/main/resources/static/main.css: -------------------------------------------------------------------------------- 1 | body, h1, h2, h3, h4, h5, h6, p, ul, ol, li, div, span, img, footer { 2 | margin: 0px; 3 | cursor: default; 4 | 5 | -moz-user-select: none; 6 | -webkit-user-select: none; 7 | -webkit-user-drag: none; 8 | } 9 | body { 10 | background: #e5e5e5 url(../images/background.png); 11 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 12 | font-size: 15px; 13 | } 14 | a { 15 | color: #333; 16 | text-decoration: none; 17 | 18 | -moz-user-select: none; 19 | -webkit-user-select: none; 20 | -webkit-user-drag: none; 21 | 22 | transition: 500ms; 23 | -o-transition: 500ms; 24 | -moz-transition: 500ms; 25 | -webkit-transition: 500ms; 26 | } 27 | a:hover { 28 | color: #707070; 29 | text-shadow: 1px 1px 5px #969696; 30 | } 31 | img { 32 | max-width: 100%; 33 | border-radius: 5px; 34 | 35 | -moz-user-select: none; 36 | -webkit-user-select: none; 37 | -webkit-user-drag: none; 38 | 39 | transition: 500ms; 40 | -o-transition: 500ms; 41 | -moz-transition: 500ms; 42 | -webkit-transition: 500ms; 43 | } 44 | img:hover { 45 | -moz-box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.1),1px 1px 30px 5px rgba(0, 0, 0, 0.2); 46 | box-shadow: 0px 2px 8px 2px rgba(0, 0, 0, 0.1),1px 1px 30px 5px rgba(0, 0, 0, 0.2); 47 | 48 | opacity: .8; 49 | } 50 | 51 | /* 侧边栏友情链接和回复列表中的头像 */ 52 | img.avatar { 53 | float: left; 54 | height: 40px; 55 | width: 40px; 56 | margin-right: 10px; 57 | border-radius: 50px; 58 | 59 | transition: 500ms; 60 | -o-transition: 500ms; 61 | -moz-transition: 500ms; 62 | -webkit-transition: 500ms; 63 | } 64 | 65 | 66 | .article-list .main p { 67 | margin: 10px 0px; 68 | } 69 | 70 | /* 布局 */ 71 | 72 | .container { 73 | max-width: 90%; 74 | margin: 0 auto; 75 | } 76 | .container:after { 77 | clear: both; 78 | content: ""; 79 | display: table; 80 | } 81 | @media (min-width: 1170px) { 82 | .container { 83 | max-width: 80%; 84 | } 85 | } 86 | 87 | 88 | /* semantic框架提供的 label */ 89 | 90 | .ui.ribbon.label { 91 | margin-top: 5px; 92 | margin-bottom: 5px; 93 | } 94 | 95 | 96 | /* 代码 */ 97 | 98 | pre, code { 99 | border-radius: 5px; 100 | color: #DE3859; 101 | border: 1px solid #ddd; 102 | padding: 2px 5px; 103 | font-family: Consolas, 'Liberation Mono', Courier, monospace; 104 | } 105 | pre { 106 | padding: 10px; 107 | border-left: 4px solid #de3859; 108 | overflow: auto; 109 | } 110 | pre code { 111 | border: 0px; 112 | padding: 0px; 113 | } 114 | 115 | 116 | /* footer 部分 */ 117 | 118 | footer { 119 | text-align: center; 120 | margin-top: 20px; 121 | color: rgb(136, 136, 136); 122 | font-size: 14px; 123 | } 124 | footer p { 125 | margin: 5px 0px; 126 | } 127 | footer a { 128 | color: rgb(136, 136, 136); 129 | } 130 | footer a:hover { 131 | color: rgb(200, 200, 200); 132 | } 133 | 134 | /* 光标 */ 135 | .side .block .label:hover, .main .block .comments:hover, .main .block .round-date:hover { 136 | cursor: pointer; 137 | } 138 | 139 | 140 | #content { 141 | position:relative; 142 | margin-top: -180px; 143 | } 144 | 145 | .zocial:before { 146 | border: none; 147 | } 148 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.hellokaton 8 | blade-demos 9 | pom 10 | 0.0.1 11 | 12 | 13 | blade-helloworld 14 | blade-route 15 | blade-template 16 | blade-ajax 17 | blade-vue-todolist 18 | blade-upload 19 | blade-custom-banner 20 | blade-kit-example 21 | blade-freemarker 22 | blade-task 23 | blade-mongo 24 | blade-package 25 | blade-activemq 26 | blade-param 27 | blade-test 28 | blade-static 29 | blade-errorpage 30 | blade-lattice 31 | blade-anima 32 | blade-gzip 33 | blade-basic-auth 34 | blade-csrf-token 35 | blade-websocket 36 | blade-verify-code 37 | blade-download 38 | blade-cors 39 | 40 | 41 | 42 | UTF-8 43 | 2.1.1.RELEASE 44 | 45 | 46 | 47 | 48 | 49 | com.hellokaton 50 | blade-core 51 | ${blade-core.version} 52 | 53 | 54 | 55 | 56 | 57 | oss-release 58 | https://oss.sonatype.org/content/repositories/releases 59 | 60 | true 61 | 62 | 63 | 64 | oss-snapshots 65 | https://oss.sonatype.org/content/repositories/snapshots 66 | 67 | true 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | src/main/java 76 | false 77 | 78 | 79 | src/main/resources 80 | false 81 | 82 | 83 | 84 | 85 | maven-compiler-plugin 86 | 2.5.1 87 | 88 | 1.8 89 | 1.8 90 | UTF-8 91 | 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /blade-param/src/main/java/com/blade/demo/param/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.blade.demo.param; 2 | 3 | import com.hellokaton.blade.annotation.Path; 4 | import com.hellokaton.blade.annotation.request.Body; 5 | import com.hellokaton.blade.annotation.request.Form; 6 | import com.hellokaton.blade.annotation.request.PathParam; 7 | import com.hellokaton.blade.annotation.request.Query; 8 | import com.hellokaton.blade.annotation.route.GET; 9 | import com.hellokaton.blade.annotation.route.POST; 10 | import com.hellokaton.blade.mvc.http.Request; 11 | import com.hellokaton.blade.mvc.http.Response; 12 | import com.hellokaton.blade.mvc.ui.ResponseType; 13 | import com.hellokaton.blade.mvc.ui.RestResponse; 14 | 15 | import java.util.Map; 16 | import java.util.Optional; 17 | 18 | /** 19 | * @author biezhi 20 | * @date 2018/5/30 21 | */ 22 | @Path(responseType = ResponseType.JSON) 23 | public class IndexController { 24 | 25 | /** 26 | * http://127.0.0.1:9000/p1 27 | * http://127.0.0.1:9000/p1?test=hello 28 | * 29 | * @param test 30 | * @return 31 | */ 32 | @GET("p1") 33 | public RestResponse p1(@Query String test) { 34 | return RestResponse.ok(test); 35 | } 36 | 37 | @POST("p2") 38 | public void p2(@Form String test, com.hellokaton.blade.mvc.http.Response response) { 39 | response.text(Optional.ofNullable(test).orElse("默认值")); 40 | } 41 | 42 | @GET("p3/:uid") 43 | public void p3(@PathParam Integer uid, Response response) { 44 | response.text("UID: " + uid); 45 | } 46 | 47 | @GET("p4") 48 | public void p4(Request request, Response response) { 49 | response.text("username: " + request.query("username", "默认值")); 50 | } 51 | 52 | @GET("p5") 53 | public RestResponse p5(User user) { 54 | return RestResponse.ok(user); 55 | } 56 | 57 | @GET("p6") 58 | public RestResponse p6(@Query(name = "user") User user) { 59 | return RestResponse.ok(user); 60 | } 61 | 62 | @GET("p7") 63 | public RestResponse p7(@Body User user) { 64 | return RestResponse.ok(user); 65 | } 66 | 67 | /** 68 | * curl -X POST \ 69 | * http://127.0.0.1:9000/p8 \ 70 | * -H 'content-type: application/json' \ 71 | * -d '{"name":"{\"inoutTypeCode\":2,\"passDeviceCode\":\"TZ_001_65010078ZHONGDA_I7\",\"passTypeCode\":1,\"idnumber\":\"152825198404205136\",\"passTime\":\"2018-06-01 14:05:33\",\"name\":\"两伊。\",\"snapPhoto\":\"data:image/jpeg;base64,Qk12AQAAAAAAADYAAAAoAAAADQAAAAgAAAABABgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////AP///////////////////////////////////////////////////wD///////////////////////////////////////////////////8A////////////////////////////////////////////////////AFpaWlpaWlpaWlpaWlpaWlpaWlRUVHt7e////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqKir///////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAANTU1////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADU1Nf///////////////////wA=\",\"refId\":\"p9049vighuhg0r83dbfv7ip1f6\",\"idCardPhoto\":\"data:image/jpeg;base64,Qk12AQAAAAAAADYAAAAoAAAADQAAAAgAAAABABgAAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////////////////////////////////AP///////////////////////////////////////////////////wD///////////////////////////////////////////////////8A////////////////////////////////////////////////////AFpaWlpaWlpaWlpaWlpaWlpaWlRUVHt7e////////////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqKir///////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAANTU1////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAADU1Nf///////////////////wA=\"}"}' 72 | */ 73 | @POST("p8") 74 | public RestResponse p8(@Body Map map) { 75 | return RestResponse.ok(map); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /blade-template/src/main/resources/static/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Specific styles of signin component 3 | */ 4 | /* 5 | * General styles 6 | */ 7 | body, html { 8 | height: 100%; 9 | background-repeat: no-repeat; 10 | background-image: linear-gradient(rgb(104, 145, 162), rgb(12, 97, 33)); 11 | } 12 | 13 | .card-container.card { 14 | max-width: 350px; 15 | padding: 40px 40px; 16 | } 17 | 18 | .btn { 19 | font-weight: 700; 20 | height: 36px; 21 | -moz-user-select: none; 22 | -webkit-user-select: none; 23 | user-select: none; 24 | cursor: default; 25 | } 26 | 27 | /* 28 | * Card component 29 | */ 30 | .card { 31 | background-color: #F7F7F7; 32 | /* just in case there no content*/ 33 | padding: 20px 25px 30px; 34 | margin: 0 auto 25px; 35 | margin-top: 50px; 36 | /* shadows and rounded borders */ 37 | -moz-border-radius: 2px; 38 | -webkit-border-radius: 2px; 39 | border-radius: 2px; 40 | -moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); 41 | -webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); 42 | box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3); 43 | } 44 | 45 | .profile-img-card { 46 | width: 96px; 47 | height: 96px; 48 | margin: 0 auto 10px; 49 | display: block; 50 | -moz-border-radius: 50%; 51 | -webkit-border-radius: 50%; 52 | border-radius: 50%; 53 | } 54 | 55 | /* 56 | * Form styles 57 | */ 58 | .profile-name-card { 59 | font-size: 16px; 60 | font-weight: bold; 61 | text-align: center; 62 | margin: 10px 0 0; 63 | min-height: 1em; 64 | } 65 | 66 | .reauth-email { 67 | display: block; 68 | color: #404040; 69 | line-height: 2; 70 | margin-bottom: 10px; 71 | font-size: 14px; 72 | text-align: center; 73 | overflow: hidden; 74 | text-overflow: ellipsis; 75 | white-space: nowrap; 76 | -moz-box-sizing: border-box; 77 | -webkit-box-sizing: border-box; 78 | box-sizing: border-box; 79 | } 80 | 81 | .form-signin #inputEmail, 82 | .form-signin #inputPassword { 83 | direction: ltr; 84 | height: 44px; 85 | font-size: 16px; 86 | } 87 | 88 | .form-signin input[type=email], 89 | .form-signin input[type=password], 90 | .form-signin input[type=text], 91 | .form-signin button { 92 | width: 100%; 93 | display: block; 94 | margin-bottom: 10px; 95 | z-index: 1; 96 | position: relative; 97 | -moz-box-sizing: border-box; 98 | -webkit-box-sizing: border-box; 99 | box-sizing: border-box; 100 | } 101 | 102 | .form-signin .form-control:focus { 103 | border-color: rgb(104, 145, 162); 104 | outline: 0; 105 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgb(104, 145, 162); 106 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgb(104, 145, 162); 107 | } 108 | 109 | .btn.btn-signin { 110 | /*background-color: #4d90fe; */ 111 | background-color: rgb(104, 145, 162); 112 | /* background-color: linear-gradient(rgb(104, 145, 162), rgb(12, 97, 33));*/ 113 | padding: 0px; 114 | font-weight: 700; 115 | font-size: 14px; 116 | height: 36px; 117 | -moz-border-radius: 3px; 118 | -webkit-border-radius: 3px; 119 | border-radius: 3px; 120 | border: none; 121 | -o-transition: all 0.218s; 122 | -moz-transition: all 0.218s; 123 | -webkit-transition: all 0.218s; 124 | transition: all 0.218s; 125 | } 126 | 127 | .btn.btn-signin:hover, 128 | .btn.btn-signin:active, 129 | .btn.btn-signin:focus { 130 | background-color: rgb(12, 97, 33); 131 | } 132 | 133 | .forgot-password { 134 | color: rgb(104, 145, 162); 135 | } 136 | 137 | .forgot-password:hover, 138 | .forgot-password:active, 139 | .forgot-password:focus{ 140 | color: rgb(12, 97, 33); 141 | } -------------------------------------------------------------------------------- /blade-package/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | blade-demos 7 | com.hellokaton 8 | 0.0.1 9 | 10 | 4.0.0 11 | blade-package 12 | 13 | 14 | 15 | dev 16 | 17 | dev 18 | 19 | 20 | 21 | true 22 | 23 | 24 | 25 | 26 | src/main/java 27 | false 28 | 29 | 30 | src/main/resources 31 | false 32 | 33 | 34 | src/main/test 35 | false 36 | 37 | 38 | src/test/resources 39 | false 40 | 41 | 42 | 43 | 44 | 45 | prod 46 | 47 | prod 48 | 49 | 50 | 51 | 52 | src/main/java 53 | false 54 | 55 | **/*.java 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | maven-compiler-plugin 67 | 68 | 1.8 69 | 1.8 70 | UTF-8 71 | 72 | 73 | 74 | maven-assembly-plugin 75 | 76 | false 77 | 78 | package.xml 79 | 80 | ${project.build.directory}/dist/ 81 | 82 | 83 | 84 | make-assembly 85 | package 86 | 87 | single 88 | 89 | 90 | 91 | 92 | 93 | org.apache.maven.plugins 94 | maven-jar-plugin 95 | 2.4 96 | 97 | 98 | 99 | com.blade.demo.HelloApplication 100 | lib/ 101 | true 102 | 103 | 104 | resources/ 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "java", 9 | "name": "Debug (Launch)-AjaxApplication", 10 | "request": "launch", 11 | "cwd": "${workspaceFolder}", 12 | "console": "internalConsole", 13 | "stopOnEntry": false, 14 | "mainClass": "com.blade.demo.ajax.AjaxApplication", 15 | "projectName": "blade-ajax", 16 | "args": "" 17 | }, 18 | { 19 | "type": "java", 20 | "name": "Debug (Launch)-CustomApplication", 21 | "request": "launch", 22 | "cwd": "${workspaceFolder}", 23 | "console": "internalConsole", 24 | "stopOnEntry": false, 25 | "mainClass": "com.blade.demo.custom.CustomApplication", 26 | "projectName": "blade-custom-banner", 27 | "args": "" 28 | }, 29 | { 30 | "type": "java", 31 | "name": "Debug (Launch)-FreeMarkerApplication", 32 | "request": "launch", 33 | "cwd": "${workspaceFolder}", 34 | "console": "internalConsole", 35 | "stopOnEntry": false, 36 | "mainClass": "com.blade.demo.freemarker.FreeMarkerApplication", 37 | "projectName": "blade-freemarker", 38 | "args": "" 39 | }, 40 | { 41 | "type": "java", 42 | "name": "Debug (Launch)-HelloApplication", 43 | "request": "launch", 44 | "cwd": "${workspaceFolder}", 45 | "console": "internalConsole", 46 | "stopOnEntry": false, 47 | "mainClass": "com.blade.demo.helloworld.HelloApplication", 48 | "projectName": "blade-helloworld", 49 | "args": "" 50 | }, 51 | { 52 | "type": "java", 53 | "name": "Debug (Launch)-JSONKitExample", 54 | "request": "launch", 55 | "cwd": "${workspaceFolder}", 56 | "console": "internalConsole", 57 | "stopOnEntry": false, 58 | "mainClass": "com.blade.demo.kit.JSONKitExample", 59 | "projectName": "blade-kit-example", 60 | "args": "" 61 | }, 62 | { 63 | "type": "java", 64 | "name": "Debug (Launch)-HelloApplication", 65 | "request": "launch", 66 | "cwd": "${workspaceFolder}", 67 | "console": "internalConsole", 68 | "stopOnEntry": false, 69 | "mainClass": "com.blade.demo.HelloApplication", 70 | "projectName": "blade-package", 71 | "args": "" 72 | }, 73 | { 74 | "type": "java", 75 | "name": "Debug (Launch)-RouteApplication", 76 | "request": "launch", 77 | "cwd": "${workspaceFolder}", 78 | "console": "internalConsole", 79 | "stopOnEntry": false, 80 | "mainClass": "com.blade.demo.route.RouteApplication", 81 | "projectName": "blade-route", 82 | "args": "" 83 | }, 84 | { 85 | "type": "java", 86 | "name": "Debug (Launch)-TplApplication", 87 | "request": "launch", 88 | "cwd": "${workspaceFolder}", 89 | "console": "internalConsole", 90 | "stopOnEntry": false, 91 | "mainClass": "com.blade.demo.tpl.TplApplication", 92 | "projectName": "blade-template", 93 | "args": "" 94 | }, 95 | { 96 | "type": "java", 97 | "name": "Debug (Launch)-UploadApplication", 98 | "request": "launch", 99 | "cwd": "${workspaceFolder}", 100 | "console": "internalConsole", 101 | "stopOnEntry": false, 102 | "mainClass": "com.blade.demo.upload.UploadApplication", 103 | "projectName": "blade-upload", 104 | "args": "" 105 | }, 106 | { 107 | "type": "java", 108 | "name": "Debug (Launch)-TodoApplication", 109 | "request": "launch", 110 | "cwd": "${workspaceFolder}", 111 | "console": "internalConsole", 112 | "stopOnEntry": false, 113 | "mainClass": "com.blade.demo.vue.TodoApplication", 114 | "projectName": "blade-vue-todolist", 115 | "args": "" 116 | }, 117 | { 118 | "type": "java", 119 | "name": "Debug (Attach)", 120 | "request": "attach", 121 | "hostName": "localhost", 122 | "port": 0 123 | } 124 | ] 125 | } -------------------------------------------------------------------------------- /blade-vue-todolist/src/main/resources/static/app.js: -------------------------------------------------------------------------------- 1 | // Full spec-compliant TodoMVC with localStorage persistence 2 | // and hash-based routing in ~120 effective lines of JavaScript. 3 | 4 | // localStorage persistence 5 | var STORAGE_KEY = 'todos-vuejs-2.0' 6 | var todoStorage = { 7 | fetch: function () { 8 | var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]') 9 | todos.forEach(function (todo, index) { 10 | todo.id = index 11 | }); 12 | todoStorage.uid = todos.length 13 | return todos 14 | }, 15 | save: function (todos) { 16 | localStorage.setItem(STORAGE_KEY, JSON.stringify(todos)) 17 | } 18 | }; 19 | 20 | // visibility filters 21 | var filters = { 22 | all: function (todos) { 23 | return todos 24 | }, 25 | active: function (todos) { 26 | return todos.filter(function (todo) { 27 | return !todo.completed 28 | }) 29 | }, 30 | completed: function (todos) { 31 | return todos.filter(function (todo) { 32 | return todo.completed 33 | }) 34 | } 35 | }; 36 | 37 | // app Vue instance 38 | var app = new Vue({ 39 | // app initial state 40 | data: { 41 | todos: todoStorage.fetch(), 42 | newTodo: '', 43 | editedTodo: null, 44 | visibility: 'all' 45 | }, 46 | 47 | // watch todos change for localStorage persistence 48 | watch: { 49 | todos: { 50 | handler: function (todos) { 51 | todoStorage.save(todos) 52 | }, 53 | deep: true 54 | } 55 | }, 56 | 57 | // computed properties 58 | // http://vuejs.org/guide/computed.html 59 | computed: { 60 | filteredTodos: function () { 61 | return filters[this.visibility](this.todos) 62 | }, 63 | remaining: function () { 64 | return filters.active(this.todos).length 65 | }, 66 | allDone: { 67 | get: function () { 68 | return this.remaining === 0 69 | }, 70 | set: function (value) { 71 | this.todos.forEach(function (todo) { 72 | todo.completed = value 73 | }) 74 | } 75 | } 76 | }, 77 | 78 | filters: { 79 | pluralize: function (n) { 80 | return n === 1 ? 'item' : 'items' 81 | } 82 | }, 83 | 84 | // methods that implement data logic. 85 | // note there's no DOM manipulation here at all. 86 | methods: { 87 | addTodo: function () { 88 | var value = this.newTodo && this.newTodo.trim() 89 | if (!value) { 90 | return 91 | } 92 | this.todos.push({ 93 | id: todoStorage.uid++, 94 | title: value, 95 | completed: false 96 | }); 97 | $.post('/add', {todo: value}, function (data) { 98 | }); 99 | this.newTodo = '' 100 | }, 101 | 102 | removeTodo: function (todo) { 103 | this.todos.splice(this.todos.indexOf(todo), 1); 104 | $.post('/remove', {todo: todo}, function (data) { 105 | 106 | }); 107 | }, 108 | editTodo: function (todo) { 109 | this.beforeEditCache = todo.title; 110 | this.editedTodo = todo; 111 | }, 112 | doneEdit: function (todo) { 113 | if (!this.editedTodo) { 114 | return 115 | } 116 | this.editedTodo = null; 117 | todo.title = todo.title.trim() 118 | if (!todo.title) { 119 | this.removeTodo(todo) 120 | } 121 | console.log(this.editedTodo.title); 122 | }, 123 | cancelEdit: function (todo) { 124 | this.editedTodo = null; 125 | todo.title = this.beforeEditCache 126 | }, 127 | removeCompleted: function () { 128 | this.todos = filters.active(this.todos); 129 | $.post('/status/active', {todo: this.todos[0]}, function (data) { 130 | 131 | }); 132 | } 133 | }, 134 | 135 | // a custom directive to wait for the DOM to be updated 136 | // before focusing on the input field. 137 | // http://vuejs.org/guide/custom-directive.html 138 | directives: { 139 | 'todo-focus': function (el, binding) { 140 | if (binding.value) { 141 | el.focus() 142 | } 143 | } 144 | } 145 | }); 146 | 147 | // handle routing 148 | function onHashChange() { 149 | var visibility = window.location.hash.replace(/#\/?/, ''); 150 | if (filters[visibility]) { 151 | app.visibility = visibility 152 | } else { 153 | window.location.hash = ''; 154 | app.visibility = 'all' 155 | } 156 | } 157 | 158 | window.addEventListener('hashchange', onHashChange) 159 | onHashChange(); 160 | 161 | // mount 162 | app.$mount('.todoapp') -------------------------------------------------------------------------------- /blade-vue-todolist/src/main/resources/static/base.js: -------------------------------------------------------------------------------- 1 | /* global _ */ 2 | (function () { 3 | 'use strict'; 4 | 5 | /* jshint ignore:start */ 6 | // Underscore's Template Module 7 | // Courtesy of underscorejs.org 8 | var _ = (function (_) { 9 | _.defaults = function (object) { 10 | if (!object) { 11 | return object; 12 | } 13 | for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) { 14 | var iterable = arguments[argsIndex]; 15 | if (iterable) { 16 | for (var key in iterable) { 17 | if (object[key] == null) { 18 | object[key] = iterable[key]; 19 | } 20 | } 21 | } 22 | } 23 | return object; 24 | } 25 | 26 | // By default, Underscore uses ERB-style template delimiters, change the 27 | // following template settings to use alternative delimiters. 28 | _.templateSettings = { 29 | evaluate : /<%([\s\S]+?)%>/g, 30 | interpolate : /<%=([\s\S]+?)%>/g, 31 | escape : /<%-([\s\S]+?)%>/g 32 | }; 33 | 34 | // When customizing `templateSettings`, if you don't want to define an 35 | // interpolation, evaluation or escaping regex, we need one that is 36 | // guaranteed not to match. 37 | var noMatch = /(.)^/; 38 | 39 | // Certain characters need to be escaped so that they can be put into a 40 | // string literal. 41 | var escapes = { 42 | "'": "'", 43 | '\\': '\\', 44 | '\r': 'r', 45 | '\n': 'n', 46 | '\t': 't', 47 | '\u2028': 'u2028', 48 | '\u2029': 'u2029' 49 | }; 50 | 51 | var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g; 52 | 53 | // JavaScript micro-templating, similar to John Resig's implementation. 54 | // Underscore templating handles arbitrary delimiters, preserves whitespace, 55 | // and correctly escapes quotes within interpolated code. 56 | _.template = function(text, data, settings) { 57 | var render; 58 | settings = _.defaults({}, settings, _.templateSettings); 59 | 60 | // Combine delimiters into one regular expression via alternation. 61 | var matcher = new RegExp([ 62 | (settings.escape || noMatch).source, 63 | (settings.interpolate || noMatch).source, 64 | (settings.evaluate || noMatch).source 65 | ].join('|') + '|$', 'g'); 66 | 67 | // Compile the template source, escaping string literals appropriately. 68 | var index = 0; 69 | var source = "__p+='"; 70 | text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 71 | source += text.slice(index, offset) 72 | .replace(escaper, function(match) { return '\\' + escapes[match]; }); 73 | 74 | if (escape) { 75 | source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 76 | } 77 | if (interpolate) { 78 | source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 79 | } 80 | if (evaluate) { 81 | source += "';\n" + evaluate + "\n__p+='"; 82 | } 83 | index = offset + match.length; 84 | return match; 85 | }); 86 | source += "';\n"; 87 | 88 | // If a variable is not specified, place data values in local scope. 89 | if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 90 | 91 | source = "var __t,__p='',__j=Array.prototype.join," + 92 | "print=function(){__p+=__j.call(arguments,'');};\n" + 93 | source + "return __p;\n"; 94 | 95 | try { 96 | render = new Function(settings.variable || 'obj', '_', source); 97 | } catch (e) { 98 | e.source = source; 99 | throw e; 100 | } 101 | 102 | if (data) return render(data, _); 103 | var template = function(data) { 104 | return render.call(this, data, _); 105 | }; 106 | 107 | // Provide the compiled function source as a convenience for precompilation. 108 | template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}'; 109 | 110 | return template; 111 | }; 112 | 113 | return _; 114 | })({}); 115 | 116 | if (location.hostname === 'todomvc.com') { 117 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 118 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 119 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 120 | })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 121 | ga('create', 'UA-31081062-1', 'auto'); 122 | ga('send', 'pageview'); 123 | } 124 | /* jshint ignore:end */ 125 | 126 | function redirect() { 127 | if (location.hostname === 'tastejs.github.io') { 128 | location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com'); 129 | } 130 | } 131 | 132 | function findRoot() { 133 | var base = location.href.indexOf('examples/'); 134 | return location.href.substr(0, base); 135 | } 136 | 137 | function getFile(file, callback) { 138 | if (!location.host) { 139 | return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.'); 140 | } 141 | 142 | var xhr = new XMLHttpRequest(); 143 | 144 | xhr.open('GET', findRoot() + file, true); 145 | xhr.send(); 146 | 147 | xhr.onload = function () { 148 | if (xhr.status === 200 && callback) { 149 | callback(xhr.responseText); 150 | } 151 | }; 152 | } 153 | 154 | function Learn(learnJSON, config) { 155 | if (!(this instanceof Learn)) { 156 | return new Learn(learnJSON, config); 157 | } 158 | 159 | var template, framework; 160 | 161 | if (typeof learnJSON !== 'object') { 162 | try { 163 | learnJSON = JSON.parse(learnJSON); 164 | } catch (e) { 165 | return; 166 | } 167 | } 168 | 169 | if (config) { 170 | template = config.template; 171 | framework = config.framework; 172 | } 173 | 174 | if (!template && learnJSON.templates) { 175 | template = learnJSON.templates.todomvc; 176 | } 177 | 178 | if (!framework && document.querySelector('[data-framework]')) { 179 | framework = document.querySelector('[data-framework]').dataset.framework; 180 | } 181 | 182 | this.template = template; 183 | 184 | if (learnJSON.backend) { 185 | this.frameworkJSON = learnJSON.backend; 186 | this.frameworkJSON.issueLabel = framework; 187 | this.append({ 188 | backend: true 189 | }); 190 | } else if (learnJSON[framework]) { 191 | this.frameworkJSON = learnJSON[framework]; 192 | this.frameworkJSON.issueLabel = framework; 193 | this.append(); 194 | } 195 | 196 | this.fetchIssueCount(); 197 | } 198 | 199 | Learn.prototype.append = function (opts) { 200 | var aside = document.createElement('aside'); 201 | aside.innerHTML = _.template(this.template, this.frameworkJSON); 202 | aside.className = 'learn'; 203 | 204 | if (opts && opts.backend) { 205 | // Remove demo link 206 | var sourceLinks = aside.querySelector('.source-links'); 207 | var heading = sourceLinks.firstElementChild; 208 | var sourceLink = sourceLinks.lastElementChild; 209 | // Correct link path 210 | var href = sourceLink.getAttribute('href'); 211 | sourceLink.setAttribute('href', href.substr(href.lastIndexOf('http'))); 212 | sourceLinks.innerHTML = heading.outerHTML + sourceLink.outerHTML; 213 | } else { 214 | // Localize demo links 215 | var demoLinks = aside.querySelectorAll('.demo-link'); 216 | Array.prototype.forEach.call(demoLinks, function (demoLink) { 217 | if (demoLink.getAttribute('href').substr(0, 4) !== 'http') { 218 | demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href')); 219 | } 220 | }); 221 | } 222 | 223 | document.body.className = (document.body.className + ' learn-bar').trim(); 224 | document.body.insertAdjacentHTML('afterBegin', aside.outerHTML); 225 | }; 226 | 227 | Learn.prototype.fetchIssueCount = function () { 228 | var issueLink = document.getElementById('issue-count-link'); 229 | if (issueLink) { 230 | var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos'); 231 | var xhr = new XMLHttpRequest(); 232 | xhr.open('GET', url, true); 233 | xhr.onload = function (e) { 234 | var parsedResponse = JSON.parse(e.target.responseText); 235 | if (parsedResponse instanceof Array) { 236 | var count = parsedResponse.length; 237 | if (count !== 0) { 238 | issueLink.innerHTML = 'This app has ' + count + ' open issues'; 239 | document.getElementById('issue-count').style.display = 'inline'; 240 | } 241 | } 242 | }; 243 | xhr.send(); 244 | } 245 | }; 246 | 247 | redirect(); 248 | getFile('learn.json', Learn); 249 | })(); -------------------------------------------------------------------------------- /blade-vue-todolist/src/main/resources/static/app.css: -------------------------------------------------------------------------------- 1 | 2 | hr { 3 | margin: 20px 0; 4 | border: 0; 5 | border-top: 1px dashed #c5c5c5; 6 | border-bottom: 1px dashed #f7f7f7; 7 | } 8 | 9 | .learn a { 10 | font-weight: normal; 11 | text-decoration: none; 12 | color: #b83f45; 13 | } 14 | 15 | .learn a:hover { 16 | text-decoration: underline; 17 | color: #787e7e; 18 | } 19 | 20 | .learn h3, 21 | .learn h4, 22 | .learn h5 { 23 | margin: 10px 0; 24 | font-weight: 500; 25 | line-height: 1.2; 26 | color: #000; 27 | } 28 | 29 | .learn h3 { 30 | font-size: 24px; 31 | } 32 | 33 | .learn h4 { 34 | font-size: 18px; 35 | } 36 | 37 | .learn h5 { 38 | margin-bottom: 0; 39 | font-size: 14px; 40 | } 41 | 42 | .learn ul { 43 | padding: 0; 44 | margin: 0 0 30px 25px; 45 | } 46 | 47 | .learn li { 48 | line-height: 20px; 49 | } 50 | 51 | .learn p { 52 | font-size: 15px; 53 | font-weight: 300; 54 | line-height: 1.3; 55 | margin-top: 0; 56 | margin-bottom: 0; 57 | } 58 | 59 | #issue-count { 60 | display: none; 61 | } 62 | 63 | .quote { 64 | border: none; 65 | margin: 20px 0 60px 0; 66 | } 67 | 68 | .quote p { 69 | font-style: italic; 70 | } 71 | 72 | .quote p:before { 73 | content: '“'; 74 | font-size: 50px; 75 | opacity: .15; 76 | position: absolute; 77 | top: -20px; 78 | left: 3px; 79 | } 80 | 81 | .quote p:after { 82 | content: '”'; 83 | font-size: 50px; 84 | opacity: .15; 85 | position: absolute; 86 | bottom: -42px; 87 | right: 3px; 88 | } 89 | 90 | .quote footer { 91 | position: absolute; 92 | bottom: -40px; 93 | right: 0; 94 | } 95 | 96 | .quote footer img { 97 | border-radius: 3px; 98 | } 99 | 100 | .quote footer a { 101 | margin-left: 5px; 102 | vertical-align: middle; 103 | } 104 | 105 | .speech-bubble { 106 | position: relative; 107 | padding: 10px; 108 | background: rgba(0, 0, 0, .04); 109 | border-radius: 5px; 110 | } 111 | 112 | .speech-bubble:after { 113 | content: ''; 114 | position: absolute; 115 | top: 100%; 116 | right: 30px; 117 | border: 13px solid transparent; 118 | border-top-color: rgba(0, 0, 0, .04); 119 | } 120 | 121 | .learn-bar > .learn { 122 | position: absolute; 123 | width: 272px; 124 | top: 8px; 125 | left: -300px; 126 | padding: 10px; 127 | border-radius: 5px; 128 | background-color: rgba(255, 255, 255, .6); 129 | transition-property: left; 130 | transition-duration: 500ms; 131 | } 132 | 133 | @media (min-width: 899px) { 134 | .learn-bar { 135 | width: auto; 136 | padding-left: 300px; 137 | } 138 | 139 | .learn-bar > .learn { 140 | left: 8px; 141 | } 142 | } 143 | 144 | html, 145 | body { 146 | margin: 0; 147 | padding: 0; 148 | } 149 | 150 | button { 151 | margin: 0; 152 | padding: 0; 153 | border: 0; 154 | background: none; 155 | font-size: 100%; 156 | vertical-align: baseline; 157 | font-family: inherit; 158 | font-weight: inherit; 159 | color: inherit; 160 | -webkit-appearance: none; 161 | appearance: none; 162 | -webkit-font-smoothing: antialiased; 163 | -moz-osx-font-smoothing: grayscale; 164 | } 165 | 166 | body { 167 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; 168 | line-height: 1.4em; 169 | background: #f5f5f5; 170 | color: #4d4d4d; 171 | min-width: 230px; 172 | max-width: 550px; 173 | margin: 0 auto; 174 | -webkit-font-smoothing: antialiased; 175 | -moz-osx-font-smoothing: grayscale; 176 | font-weight: 300; 177 | } 178 | 179 | :focus { 180 | outline: 0; 181 | } 182 | 183 | .hidden { 184 | display: none; 185 | } 186 | 187 | .todoapp { 188 | background: #fff; 189 | margin: 130px 0 40px 0; 190 | position: relative; 191 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 192 | 0 25px 50px 0 rgba(0, 0, 0, 0.1); 193 | } 194 | 195 | .todoapp input::-webkit-input-placeholder { 196 | font-style: italic; 197 | font-weight: 300; 198 | color: #e6e6e6; 199 | } 200 | 201 | .todoapp input::-moz-placeholder { 202 | font-style: italic; 203 | font-weight: 300; 204 | color: #e6e6e6; 205 | } 206 | 207 | .todoapp input::input-placeholder { 208 | font-style: italic; 209 | font-weight: 300; 210 | color: #e6e6e6; 211 | } 212 | 213 | .todoapp h1 { 214 | position: absolute; 215 | top: -155px; 216 | width: 100%; 217 | font-size: 100px; 218 | font-weight: 100; 219 | text-align: center; 220 | color: rgba(175, 47, 47, 0.15); 221 | -webkit-text-rendering: optimizeLegibility; 222 | -moz-text-rendering: optimizeLegibility; 223 | text-rendering: optimizeLegibility; 224 | } 225 | 226 | .new-todo, 227 | .edit { 228 | position: relative; 229 | margin: 0; 230 | width: 100%; 231 | font-size: 24px; 232 | font-family: inherit; 233 | font-weight: inherit; 234 | line-height: 1.4em; 235 | border: 0; 236 | color: inherit; 237 | padding: 6px; 238 | border: 1px solid #999; 239 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); 240 | box-sizing: border-box; 241 | -webkit-font-smoothing: antialiased; 242 | -moz-osx-font-smoothing: grayscale; 243 | } 244 | 245 | .new-todo { 246 | padding: 16px 16px 16px 60px; 247 | border: none; 248 | background: rgba(0, 0, 0, 0.003); 249 | box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); 250 | } 251 | 252 | .main { 253 | position: relative; 254 | z-index: 2; 255 | border-top: 1px solid #e6e6e6; 256 | } 257 | 258 | label[for='toggle-all'] { 259 | display: none; 260 | } 261 | 262 | .toggle-all { 263 | position: absolute; 264 | top: -55px; 265 | left: -12px; 266 | width: 60px; 267 | height: 34px; 268 | text-align: center; 269 | border: none; /* Mobile Safari */ 270 | } 271 | 272 | .toggle-all:before { 273 | content: '❯'; 274 | font-size: 22px; 275 | color: #e6e6e6; 276 | padding: 10px 27px 10px 27px; 277 | } 278 | 279 | .toggle-all:checked:before { 280 | color: #737373; 281 | } 282 | 283 | .todo-list { 284 | margin: 0; 285 | padding: 0; 286 | list-style: none; 287 | } 288 | 289 | .todo-list li { 290 | position: relative; 291 | font-size: 24px; 292 | border-bottom: 1px solid #ededed; 293 | } 294 | 295 | .todo-list li:last-child { 296 | border-bottom: none; 297 | } 298 | 299 | .todo-list li.editing { 300 | border-bottom: none; 301 | padding: 0; 302 | } 303 | 304 | .todo-list li.editing .edit { 305 | display: block; 306 | width: 506px; 307 | padding: 12px 16px; 308 | margin: 0 0 0 43px; 309 | } 310 | 311 | .todo-list li.editing .view { 312 | display: none; 313 | } 314 | 315 | .todo-list li .toggle { 316 | text-align: center; 317 | width: 40px; 318 | /* auto, since non-WebKit browsers doesn't support input styling */ 319 | height: auto; 320 | position: absolute; 321 | top: 0; 322 | bottom: 0; 323 | margin: auto 0; 324 | border: none; /* Mobile Safari */ 325 | -webkit-appearance: none; 326 | appearance: none; 327 | } 328 | 329 | .todo-list li .toggle:after { 330 | content: url('data:image/svg+xml;utf8,'); 331 | } 332 | 333 | .todo-list li .toggle:checked:after { 334 | content: url('data:image/svg+xml;utf8,'); 335 | } 336 | 337 | .todo-list li label { 338 | word-break: break-all; 339 | padding: 15px 60px 15px 15px; 340 | margin-left: 45px; 341 | display: block; 342 | line-height: 1.2; 343 | transition: color 0.4s; 344 | } 345 | 346 | .todo-list li.completed label { 347 | color: #d9d9d9; 348 | text-decoration: line-through; 349 | } 350 | 351 | .todo-list li .destroy { 352 | display: none; 353 | position: absolute; 354 | top: 0; 355 | right: 10px; 356 | bottom: 0; 357 | width: 40px; 358 | height: 40px; 359 | margin: auto 0; 360 | font-size: 30px; 361 | color: #cc9a9a; 362 | margin-bottom: 11px; 363 | transition: color 0.2s ease-out; 364 | } 365 | 366 | .todo-list li .destroy:hover { 367 | color: #af5b5e; 368 | } 369 | 370 | .todo-list li .destroy:after { 371 | content: '×'; 372 | } 373 | 374 | .todo-list li:hover .destroy { 375 | display: block; 376 | } 377 | 378 | .todo-list li .edit { 379 | display: none; 380 | } 381 | 382 | .todo-list li.editing:last-child { 383 | margin-bottom: -1px; 384 | } 385 | 386 | .footer { 387 | color: #777; 388 | padding: 10px 15px; 389 | height: 20px; 390 | text-align: center; 391 | border-top: 1px solid #e6e6e6; 392 | } 393 | 394 | .footer:before { 395 | content: ''; 396 | position: absolute; 397 | right: 0; 398 | bottom: 0; 399 | left: 0; 400 | height: 50px; 401 | overflow: hidden; 402 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 403 | 0 8px 0 -3px #f6f6f6, 404 | 0 9px 1px -3px rgba(0, 0, 0, 0.2), 405 | 0 16px 0 -6px #f6f6f6, 406 | 0 17px 2px -6px rgba(0, 0, 0, 0.2); 407 | } 408 | 409 | .todo-count { 410 | float: left; 411 | text-align: left; 412 | } 413 | 414 | .todo-count strong { 415 | font-weight: 300; 416 | } 417 | 418 | .filters { 419 | margin: 0; 420 | padding: 0; 421 | list-style: none; 422 | position: absolute; 423 | right: 0; 424 | left: 0; 425 | } 426 | 427 | .filters li { 428 | display: inline; 429 | } 430 | 431 | .filters li a { 432 | color: inherit; 433 | margin: 3px; 434 | padding: 3px 7px; 435 | text-decoration: none; 436 | border: 1px solid transparent; 437 | border-radius: 3px; 438 | } 439 | 440 | .filters li a:hover { 441 | border-color: rgba(175, 47, 47, 0.1); 442 | } 443 | 444 | .filters li a.selected { 445 | border-color: rgba(175, 47, 47, 0.2); 446 | } 447 | 448 | .clear-completed, 449 | html .clear-completed:active { 450 | float: right; 451 | position: relative; 452 | line-height: 20px; 453 | text-decoration: none; 454 | cursor: pointer; 455 | } 456 | 457 | .clear-completed:hover { 458 | text-decoration: underline; 459 | } 460 | 461 | .info { 462 | margin: 65px auto 0; 463 | color: #bfbfbf; 464 | font-size: 10px; 465 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); 466 | text-align: center; 467 | } 468 | 469 | .info p { 470 | line-height: 1; 471 | } 472 | 473 | .info a { 474 | color: inherit; 475 | text-decoration: none; 476 | font-weight: 400; 477 | } 478 | 479 | .info a:hover { 480 | text-decoration: underline; 481 | } 482 | 483 | /* 484 | Hack to remove background from Mobile Safari. 485 | Can't use it globally since it destroys checkboxes in Firefox 486 | */ 487 | @media screen and (-webkit-min-device-pixel-ratio:0) { 488 | .toggle-all, 489 | .todo-list li .toggle { 490 | background: none; 491 | } 492 | 493 | .todo-list li .toggle { 494 | height: 40px; 495 | } 496 | 497 | .toggle-all { 498 | -webkit-transform: rotate(90deg); 499 | transform: rotate(90deg); 500 | -webkit-appearance: none; 501 | appearance: none; 502 | } 503 | } 504 | 505 | @media (max-width: 430px) { 506 | .footer { 507 | height: 50px; 508 | } 509 | 510 | .filters { 511 | bottom: 10px; 512 | } 513 | } -------------------------------------------------------------------------------- /blade-vue-todolist/src/main/resources/static/director.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | // 4 | // Generated on Tue Dec 16 2014 12:13:47 GMT+0100 (CET) by Charlie Robbins, Paolo Fragomeni & the Contributors (Using Codesurgeon). 5 | // Version 1.2.6 6 | // 7 | 8 | (function (exports) { 9 | 10 | /* 11 | * browser.js: Browser specific functionality for director. 12 | * 13 | * (C) 2011, Charlie Robbins, Paolo Fragomeni, & the Contributors. 14 | * MIT LICENSE 15 | * 16 | */ 17 | 18 | var dloc = document.location; 19 | 20 | function dlocHashEmpty() { 21 | // Non-IE browsers return '' when the address bar shows '#'; Director's logic 22 | // assumes both mean empty. 23 | return dloc.hash === '' || dloc.hash === '#'; 24 | } 25 | 26 | var listener = { 27 | mode: 'modern', 28 | hash: dloc.hash, 29 | history: false, 30 | 31 | check: function () { 32 | var h = dloc.hash; 33 | if (h != this.hash) { 34 | this.hash = h; 35 | this.onHashChanged(); 36 | } 37 | }, 38 | 39 | fire: function () { 40 | if (this.mode === 'modern') { 41 | this.history === true ? window.onpopstate() : window.onhashchange(); 42 | } 43 | else { 44 | this.onHashChanged(); 45 | } 46 | }, 47 | 48 | init: function (fn, history) { 49 | var self = this; 50 | this.history = history; 51 | 52 | if (!Router.listeners) { 53 | Router.listeners = []; 54 | } 55 | 56 | function onchange(onChangeEvent) { 57 | for (var i = 0, l = Router.listeners.length; i < l; i++) { 58 | Router.listeners[i](onChangeEvent); 59 | } 60 | } 61 | 62 | //note IE8 is being counted as 'modern' because it has the hashchange event 63 | if ('onhashchange' in window && (document.documentMode === undefined 64 | || document.documentMode > 7)) { 65 | // At least for now HTML5 history is available for 'modern' browsers only 66 | if (this.history === true) { 67 | // There is an old bug in Chrome that causes onpopstate to fire even 68 | // upon initial page load. Since the handler is run manually in init(), 69 | // this would cause Chrome to run it twise. Currently the only 70 | // workaround seems to be to set the handler after the initial page load 71 | // http://code.google.com/p/chromium/issues/detail?id=63040 72 | setTimeout(function() { 73 | window.onpopstate = onchange; 74 | }, 500); 75 | } 76 | else { 77 | window.onhashchange = onchange; 78 | } 79 | this.mode = 'modern'; 80 | } 81 | else { 82 | // 83 | // IE support, based on a concept by Erik Arvidson ... 84 | // 85 | var frame = document.createElement('iframe'); 86 | frame.id = 'state-frame'; 87 | frame.style.display = 'none'; 88 | document.body.appendChild(frame); 89 | this.writeFrame(''); 90 | 91 | if ('onpropertychange' in document && 'attachEvent' in document) { 92 | document.attachEvent('onpropertychange', function () { 93 | if (event.propertyName === 'location') { 94 | self.check(); 95 | } 96 | }); 97 | } 98 | 99 | window.setInterval(function () { self.check(); }, 50); 100 | 101 | this.onHashChanged = onchange; 102 | this.mode = 'legacy'; 103 | } 104 | 105 | Router.listeners.push(fn); 106 | 107 | return this.mode; 108 | }, 109 | 110 | destroy: function (fn) { 111 | if (!Router || !Router.listeners) { 112 | return; 113 | } 114 | 115 | var listeners = Router.listeners; 116 | 117 | for (var i = listeners.length - 1; i >= 0; i--) { 118 | if (listeners[i] === fn) { 119 | listeners.splice(i, 1); 120 | } 121 | } 122 | }, 123 | 124 | setHash: function (s) { 125 | // Mozilla always adds an entry to the history 126 | if (this.mode === 'legacy') { 127 | this.writeFrame(s); 128 | } 129 | 130 | if (this.history === true) { 131 | window.history.pushState({}, document.title, s); 132 | // Fire an onpopstate event manually since pushing does not obviously 133 | // trigger the pop event. 134 | this.fire(); 135 | } else { 136 | dloc.hash = (s[0] === '/') ? s : '/' + s; 137 | } 138 | return this; 139 | }, 140 | 141 | writeFrame: function (s) { 142 | // IE support... 143 | var f = document.getElementById('state-frame'); 144 | var d = f.contentDocument || f.contentWindow.document; 145 | d.open(); 146 | d.write("