{"id":8929,"date":"2015-12-14T09:45:37","date_gmt":"2015-12-14T00:45:37","guid":{"rendered":"http:\/\/www.techscore.com\/blog\/?p=8929"},"modified":"2018-11-14T16:33:46","modified_gmt":"2018-11-14T07:33:46","slug":"ninja-micro-frame-work","status":"publish","type":"post","link":"https:\/\/www.techscore.com\/blog\/2015\/12\/14\/ninja-micro-frame-work\/","title":{"rendered":"\u30de\u30a4\u30af\u30ed\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u300cNinja\u300d\u3092\u4f7f\u3063\u3066\u307f\u308b"},"content":{"rendered":"

\u3053\u3093\u306b\u3061\u306f\u3001\u9577\u4e95\u3067\u3059\u3002<\/p>\n

\u3053\u308c\u306f TECHSCORE Advent Calendar 2015<\/a> \u306e14\u65e5\u76ee\u306e\u8a18\u4e8b\u3067\u3059\u3002<\/p>\n

\u672c\u8a18\u4e8b\u3067\u306fJava\u306e\u30de\u30a4\u30af\u30ed\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u300cNinja<\/a>\u300d\u3092\u4f7f\u3063\u3066 Twetter \u306e\u30c4\u30a4\u30fc\u30c8\u3092\u691c\u7d22\u3059\u308b Web\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u4f5c\u308a\u307e\u3059\u3002<\/p>\n

\u30de\u30a4\u30af\u30ed\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3068\u306f\u4f55\u304b\u306b\u3064\u3044\u3066\u306f\u3053\u3061\u3089<\/a>\u306e\u8a18\u4e8b\u3092\u3054\u89a7\u4e0b\u3055\u3044\u3002<\/p>\n

Ninja \u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306f Maven<\/a> \u3067\u884c\u3044\u307e\u3059\u3002
\n\u4eca\u56de\u306e\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u4f5c\u6210\u306f Linux(
Arch Linux<\/a>) \u3067\u884c\u3044\u307e\u3057\u305f\u3002\u524d\u63d0\u3068\u3057\u3066 Java, Maven \u304c\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u308b\u3082\u306e\u3068\u3057\u307e\u3059\u3002\uff08\u53c2\u8003\u2026Windows\u74b0\u5883\u3067\u306eMaven\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u65b9\u6cd5<\/a>\uff09<\/p>\n

\u307e\u305a\u306f Maven \u3067\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002<\/p>\n

\r\n$ mvn archetype:generate -DarchetypeGroupId=org.ninjaframework \\\r\n-DarchetypeArtifactId=ninja-servlet-archetype-simple\r\n<\/pre>\n

\u5e7e\u3064\u304b\u30d1\u30e9\u30e1\u30fc\u30bf\u5165\u529b\u3092\u4fc3\u3055\u308c\u307e\u3059\u304c\u3053\u3053<\/a>\u3084\u3053\u3053<\/a>\u3092\u53c2\u8003\u306b\u5165\u529b\u3057\u307e\u3059\u3002\u4eca\u56de\u306f groupId \u306f\u300ccom.example\u300d, artifactId \u306f\u300cninjaSmp\u300d, version, package \u306f\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u307e\u307e\u300c 1.0-SNAPSHOT\u300d\u304a\u3088\u3073\u300ccom.example\u300d\u306b\u3057\u307e\u3057\u305f\u3002<\/p>\n

\u6b21\u306b\u4f5c\u6210\u3055\u308c\u305f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u79fb\u52d5\u3057\u3066\u30b3\u30f3\u30d1\u30a4\u30eb\u3092\u5b9f\u884c\u3057\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u8d77\u52d5\u3057\u307e\u3059\u3002<\/p>\n

\r\n$ cd ninjaSmp           # \u4f5c\u6210\u3055\u308c\u305f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\r\n$ mvn clean install     # \u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u30ed\u30fc\u30ab\u30eb\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n$ mvn ninja:run         # \u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u8d77\u52d5<\/pre>\n

\"20151211001\"<\/a>\uff08\u30af\u30ea\u30c3\u30af\u3067\u62e1\u5927\uff09
\n\u25b2\u30b3\u30f3\u30d1\u30a4\u30eb\u304c\u5b8c\u4e86\u3057\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u304c\u8d77\u52d5\u3057\u305f\u3068\u304d\u306e\u30b3\u30f3\u30bd\u30fc\u30eb<\/p>\n

\u300chttp:\/\/localhost:8080\u300d\u3067\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u3059\u3002<\/p>\n

\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u4f5c\u6210<\/h2>\n

\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b\u624b\u3092\u52a0\u3048\u3066\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u5b8c\u6210\u3055\u305b\u307e\u3059\u3002
\n\u4ee5\u964d\u3067\u898b\u308b\u30b3\u30fc\u30c9\u306f\u624b\u3092\u52a0\u3048\u305f\u5b8c\u6210\u5f8c\u306e\u3082\u306e\u3067\u3059\u3002
\n\u3068\u306f\u8a00\u3063\u3066\u3082\u624b\u3092\u3044\u308c\u308b\u5185\u5bb9\u306f\u305d\u308c\u307b\u3069\u306b\u591a\u304f\u3042\u308a\u307e\u305b\u3093\u3002<\/p>\n

\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u968e\u5c64\u306f\u4ee5\u4e0b\u306e\u69d8\u306b\u306a\u308a\u307e\u3059\u3002Maven \u306e\u6a19\u6e96\u306b\u6e96\u62e0\u3057\u3066\u3044\u308b\u306e\u3067\u3053\u306e\u307e\u307e Eclipse \u7b49\u306e IDE \u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3068\u3057\u3066\u30a4\u30f3\u30dd\u30fc\u30c8\u3059\u308b\u4e8b\u3082\u53ef\u80fd\u3067\u3059\u3002<\/p>\n

ninjaSamp\r\n\u2502\r\n\u251c\u2500\u2500 pom.xml\r\n\u251c\u2500\u2500 src\r\n\u2502     \u251c\u2500\u2500 main\r\n\u2502     \u2502     \u251c\u2500\u2500 java\r\n\u2502     \u2502     \u2502     \u251c\u2500\u2500 assets\r\n\u2502     \u2502     \u2502     \u2502     \u2514\u2500\u2500 css\r\n\u2502     \u2502     \u2502     \u2502         \u2514\u2500\u2500 custom.css\r\n\u2502     \u2502     \u2502     \u251c\u2500\u2500 conf\r\n\u2502     \u2502     \u2502     \u2502     \u251c\u2500\u2500 application.conf\r\n\u2502     \u2502     \u2502     \u2502     \u251c\u2500\u2500 messages.properties\r\n\u2502     \u2502     \u2502     \u2502     \u251c\u2500\u2500 Module.java\r\n\u2502     \u2502     \u2502     \u2502     \u2514\u2500\u2500 Routes.java\r\n\u2502     \u2502     \u2502     \u251c\u2500\u2500 controllers\r\n\u2502     \u2502     \u2502     \u2502     \u2514\u2500\u2500 ApplicationController.java\r\n\u2502     \u2502     \u2502     \u2514\u2500\u2500 views\r\n\u2502     \u2502     \u2502         \u251c\u2500\u2500 ApplicationController\r\n\u2502     \u2502     \u2502         \u2502     \u251c\u2500\u2500 collect.ftl.html\r\n\u2502     \u2502     \u2502         \u2502     \u2514\u2500\u2500 index.ftl.html\r\n\u2502     \u2502     \u2502         \u251c\u2500\u2500 layout\r\n\u2502     \u2502     \u2502         \u2502     \u251c\u2500\u2500 defaultLayout.ftl.html\r\n\u2502     \u2502     \u2502         \u2502     \u251c\u2500\u2500 footer.ftl.html\r\n\u2502     \u2502     \u2502         \u2502     \u2514\u2500\u2500 header.ftl.html\r\n\u2502     \u2502     \u2502         \u2514\u2500\u2500 system\r\n\u2502     \u2502     \u2502             \u251c\u2500\u2500 403forbidden.ftl.html\r\n\u2502     \u2502     \u2502             \u2514\u2500\u2500 404notFound.ftl.html\r\n\u2502     \u2502     \u2514\u2500\u2500 webapp\r\n\u2502     \u2502         \u2514\u2500\u2500 WEB-INF\r\n\u2502     \u2502             \u2514\u2500\u2500 web.xml\r\n\u2502     \u2514\u2500\u2500 test\r\n\u2502         \u2514\u2500\u2500 java\r\n\u2502             \u2514\u2500\u2500 controllers\r\n\u2502                 \u2514\u2500\u2500 ApiControllerDocTesterTest.java\r\n\u2514\u2500\u2500 target\r\n    \u251c\u2500\u2500 classes\r\n        \u2502\r\n           \uff1c\u4ee5\u4e0b\u7701\u7565\uff1e\r\n<\/pre>\n

conf\/ \u4ee5\u4e0b\u306b URL \u306e\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3068\u30e1\u30c3\u30bb\u30fc\u30b8\u30d7\u30ed\u30d1\u30c6\u30a3\u3001controllers\/ \u4ee5\u4e0b\u306b\u5404\u51e6\u7406\u3092\u5236\u5fa1\u3059\u308b\u30af\u30e9\u30b9\uff08\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\uff09\u304c\u3042\u308a\u307e\u3059\u3002
\n\u753b\u9762\u307e\u308f\u308a\u306e\u30d5\u30a1\u30a4\u30eb\u306fviews\/\u4ee5\u4e0b\u306b\u3042\u308a\u307e\u3059\u3002
\n\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u30a8\u30f3\u30b8\u30f3\u3068\u3057\u3066
Apache FreeMaker<\/a> \u304c\u5229\u7528\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n

\u624b\u3092\u52a0\u3048\u305f\u7b87\u6240<\/h2>\n

Routes.java<\/h3>\n
package conf;\r\n\r\n\r\nimport ninja.AssetsController;\r\nimport ninja.Router;\r\nimport ninja.application.ApplicationRoutes;\r\nimport controllers.ApplicationController;\r\n\r\npublic class Routes implements ApplicationRoutes {\r\n\r\n    @Override\r\n    public void init(Router router) {  \r\n        \r\n        router.GET().route(\"\/\").with(ApplicationController.class, \"index\");\r\n\r\n        \/\/ \u4eca\u56de\u8ffd\u52a0\u3057\u305f\u30b3\u30fc\u30c9\r\n        router.POST().route(\"\/collect\").with(ApplicationController.class, \"collect\");\r\n        router.GET().route(\"\/collect\").with(ApplicationController.class, \"collect\");\r\n\r\n        router.GET().route(\"\/hello_world.json\").with(ApplicationController.class, \"helloWorldJson\");\r\n        \r\n \r\n        \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n        \/\/ Assets (pictures \/ javascript)\r\n        \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/    \r\n        router.GET().route(\"\/assets\/webjars\/{fileName: .*}\").with(AssetsController.class, \"serveWebJars\");\r\n        router.GET().route(\"\/assets\/{fileName: .*}\").with(AssetsController.class, \"serveStatic\");\r\n        \r\n        \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n        \/\/ Index \/ Catchall shows index page\r\n        \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n        router.GET().route(\"\/.*\").with(ApplicationController.class, \"index\");\r\n    }\r\n\r\n}\r\n<\/pre>\n

URL \u306b\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u30af\u30e9\u30b9\u3068\u305d\u306e\u30e1\u30bd\u30c3\u30c9\u540d\u3092\u95a2\u9023\u4ed8\u3051\u3066\u3044\u307e\u3059\u3002\u4eca\u56de\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306b URL \"\/collect\" \u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n

ApplicationController.java<\/h3>\n
package controllers;\r\n\r\nimport java.util.HashMap;\r\nimport java.util.List;\r\nimport java.util.Map;\r\n\r\nimport com.google.inject.Singleton;\r\n\r\nimport ninja.Result;\r\nimport ninja.Results;\r\nimport ninja.params.Param;\r\n\r\n@Singleton\r\npublic class ApplicationController {\r\n\r\n\tpublic Result index() {\r\n\r\n\t\tMap<String, Object> map = new HashMap<>();\r\n\t\tmap.put(\"m1\", \"Honour thy error as a hidden intention.\");\r\n\t\tmap.put(\"m2\", \"You don't have to be ashamed of using your own ideas\");\r\n\t\tmap.put(\"m3\", \"Use an unacceptable color\");\r\n\t\treturn Results.html().render(map).template(\"views\/ApplicationController\/index.ftl.html\");\r\n\r\n\t}\r\n\r\n\tpublic Result helloWorldJson() {\r\n\r\n\t\tSimplePojo simplePojo = new SimplePojo();\r\n\t\tsimplePojo.content = \"Hello World! Hello Json!\";\r\n\t\treturn Results.json().render(simplePojo);\r\n\r\n\t}\r\n\r\n\tpublic static class SimplePojo {\r\n\r\n\t\tpublic String content;\r\n\r\n\t}\r\n\r\n\tpublic Result collect(@Param(\"kwd\") String arg1) {\r\n\t\tTwitterPojo twitterPojo = new TwitterPojo();\r\n\t\tList<String> tweets = twitterPojo.collect(arg1);\r\n\t\tMap<String, List<String>> map = new HashMap<>();\r\n\t\tmap.put(\"tweets\", tweets);\r\n\t\treturn Results.html().render(map).template(\"views\/ApplicationController\/collect.ftl.html\");\r\n\t}\r\n\r\n}\r\n<\/pre>\n

\u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u30fc\u30af\u30e9\u30b9\u3002Routes.java \u3067URL \u3054\u3068\u306b\u8a2d\u5b9a\u3057\u305f\u30e1\u30bd\u30c3\u30c9\u306e\u672c\u4f53\u3067\u3059\u3002
\nResults\u30af\u30e9\u30b9\u306e html() \u30e1\u30bd\u30c3\u30c9\u304c Result\u30af\u30e9\u30b9\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u8fd4\u3059\u306e\u3067\u753b\u9762\u306b\u5f15\u304d\u6e21\u3057\u305f\u3044\u5024\u304c\u683c\u7d0d\u3055\u308c\u305f\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3068\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u540d\u3092\u6e21\u3057\u307e\u3059\u3002Results\u30af\u30e9\u30b9\u306e json()\u30e1\u30bd\u30c3\u30c9\u3067 JSON \u5f62\u5f0f\u306e\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u751f\u6210\u3059\u308b\u4e8b\u304c\u51fa\u6765\u307e\u3059\u3002<\/p>\n

\u30e1\u30bd\u30c3\u30c9\u306e\u5f15\u6570\u306b @Param \u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3\u6307\u5b9a\u3059\u308b\u3068\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u30d1\u30e9\u30e1\u30fc\u30bf\u30fc\u3068\u3057\u3066\u53d6\u5f97\u3057\u307e\u3059\u3002
\n\u30a2\u30ce\u30c6\u30fc\u30b7\u30e7\u30f3\u306b\u306fValidation\u7528\u306e\u3082\u306e\u3082\u7528\u610f\u3055\u308c\u3066\u3044\u307e\u3059\u3002\uff08@Required \u3084 @isInteger \u7b49\uff09<\/p>\n

Validation \u3068\u3057\u3066JSR 303 Bean Validation<\/a>\u3092\u5229\u7528\u3059\u308b\u4e8b\u3082\u51fa\u6765\u307e\u3059\u3002\uff08\u4f7f\u3044\u65b9\u306f\u4e0b\u8a18\u306e\u30ea\u30f3\u30af\u5148\u53c2\u7167\uff09<\/p>\n