关于playframework
1 play关联数据库时,驱动需要手动依赖 libraryDependencies ++= Seq( guice, jdbc, "com.h2database" % "h2" % "1.4.199", "com.google.code.gson" % "gson" % "2.3", "postgresql" % "postgresql" % "9.1-901-1.jdbc4", "org.awaitility" % "awaitility" % "3.1.6" % Test, "org.assertj" % "assertj-core" % "3.12.2" % Test, "org.mockito" % "mockito-core" % "3.0.0" % Test, // To provide an implementation of JAXB-API, which is required by Ebean. "javax.xml.bind" % "jaxb-api" % "2.3.1", "javax.activation" % "activation" % "1.1.1", "org.glassfish.jaxb" % "jaxb-runtime" % "2.3.2", "org.projectlombok"%"lombok"%"1.16.18" ) 2 play中使用evolutions,通过脚本来同步数据库表。会自动在库中生成play_evolutions表来控制表版本的升降 数据库已经存在表时在application.conf中设置play.evolutions.enabled=false evolutionplugin=disabled来禁止同步数据库脚本 3 打印日志在application.conf中配置db.default.logSql = true <!-- 本地 数据库 log--> <logger name="org.jdbcdslog.ConnectionLogger" level="WARN"/> <root level="INFO"> <logger name="org.jdbcdslog.StatementLogger" level="INFO"/> <appender-ref ref="ASYNCFILE" /> <logger name="org.jdbcdslog.ResultSetLogger" level="WARN"/> <appender-ref ref="ASYNCSTDOUT" /> 4 数据库连接配置 </root> db.default.driver=org.postgresql.Driver db.default.url="jdbc:postgresql://localhost:port/postgres" db.default.user=xxx db.default.pass=xxx default为你设置的数据库名称 5 设置不同的数据库中的model ebean.default="models.ke.*" 6 设置JDBC连接池 连接池数量 fixedConnectionPool = 12 设置最大最小连接数 # Set Hikari to fixed size play.db { prototype { hikaricp.minimumIdle = ${fixedConnectionPool} hikaricp.maximumPoolSize = ${fixedConnectionPool} } } 用来处理IO阻塞的最简单的配置 # Job queue sized to HikariCP connection pool database.dispatcher { executor = "thread-pool-executor" throughput = 1 thread-pool-executor { fixed-pool-size = ${fixedConnectionPool} } } 7 页面设置引入css/js (1) css引入放入@main(){下<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/keb06010.css")"/> (2) js引入放入当前页面坐下边<script src="@routes.Assets.at("javascripts/keb06010.js")"></script> (3) 页面属性的使用 导入 @import helper._ @ inputText(后台传入的表单中的值相当于input中的name, Symbol("id") -> "imtAsyaCode", Symbol("_label") -> "") Symbol(属性)->"值" @ @select( selectForm("utiwakeCod1"), 表单属性 options(keGetTekiyoMap), 下拉框所有值为map Symbol("id") -> "cscTekiyo", Symbol("_label") -> "", Symbol("_default") -> "", Symbol("_showConstraints") -> false ) (4) 提交方式 POST需要添加CSRF认证:在form表单下添加 @CSRF.formField 在页面最上边添加隐式参数(implicit request: Http.Request) (5) 参数传递main(title) 页面最上边@(a:String ,b:int,map1: Map[String,String],map2: Map[String,String],row:SqlRow,selectForm: Form[DynamicForm.Dynamic],list:List[SqlRow]) 参数引用:@a,@b,@map1.get(""),@map2.get(""),@row.getString(""),@selectForm(""), @for(ke03 <- list){} 8 Session 后台添加session return ok(views.html.ke.keb06010.render(cboGyomuList,searchListData,searchFlag,sqlRowSizeFlag,request)) .addingToSession(request,"cboGyomu",cboGyomu) .addingToSession(request,"imdNyukinYmd0",imdNyukinYmd0) .addingToSession(request,"imdNyukinYmd1",imdNyukinYmd1); 页面接受session @request.session().get("") 后台接受session Optional<String> sCbo = request.session().get("cboGyomu"); String scbo = sCbo.get(); flash 如果您必须跨多个 HTTP 请求保存数据,您可以将它们保存在 Session 或 Flash 作用域中。Session 中存储的数据在整个用户会话期间都可用,而 flash 作用域中存储的数据仅在下一次请求时可用。 9 后台封装数据到动态表单 DynamicForm selectForm = formFactory.form().fill(keb6020InitMap); 10 查询多条数据 多表 List<SqlRow> searchListData = keb06010Service.getSearchListData(cboGyomu, imdNyukinYmd0, imdNyukinYmd1); sql = selectSql.toString(); SqlQuery sqlQuery = Ebean.createSqlQuery(sql); List<SqlRow> listData = sqlQuery.findList(); 11 更新操作 int updateRows1 = Ebean.update(Ke03Tbl.class) .set("denpyoMakFlg", Common.DENMAKE_FLG_NOMAKE) .where() .eq("denpyoMakFlg", Common.DENMAKE_FLG_MAKING) .eq("koushaSishaCod","01") .update(); 12 增删改查框架封装的引用 在model中添加 public static final Finder<Long, Model> finder = new Finder<>(Model.class); Model a = Model.db().find(Model.class).where().eq("1","1").findOne(); Ke07Tbl keb = new Ke07Tbl(); keb.update(); keb.delete(); keb.save(); 13 获取前台封装的JSON Map<String,String[]> getMap = request.queryString(); String jsonData = getMap.get("jsonData")[0]; JsonNode json = Json.parse(jsonData); json.findPath("col0").textValue() 14 playframework使用netty作为网络框架,不使用tomcat等第三方web容器的 需要部署到tomcat,获其他servlet容器的 需要打war包,方式如下 添加插件 addSbtPlugin("com.github.play2war" % "play2-war-plugin" % "1.2.1") 版本号:1.4.0 在build.bat中添加 import com.github.play2war.plugin._ Play2WarKeys.servletVersion := "3.1" jdk8 15 部署 生成应用程序机密命令: playGenerateSecret 配置添加机密: play.http.secret.key="QCY?tAnfk?aZ?iwrNwnxIlR6CTf:G3gf:90Latabg@5241AB`R5W:1uDFN];Ik@n" 16 打包 使用dist命令 默认情况下,该dist任务将在生成的包中包含 API 文档。如果这不是必需的,请将这些行添加到build.sbt: sources in (Compile, doc) := Seq.empty publishArtifact in (Compile, packageDoc) := false 对于带有子项目的构建,必须将上述语句应用于所有子项目定义。 17 application配置指定 HTTP 服务器地址和端口 play.server { http.port = 8000 http.address = 127.0.0.1 } 18 application信任所有代理 play.http.forwarded.trustedProxies=["0.0.0.0/0", "::/0"] 19 为了防止 Play 创建自己的 PID,您可以/dev/null在application.conf文件中设置路径 pidfile.path = "/dev/null" 20 过滤器 要手动启用过滤器,请将允许的主机过滤器添加到您的过滤器中application.conf allowed = [".example.com", "localhost:9000"] 设置允许访问的主机 play.filters.enabled += play.filters.hosts.AllowedHostsFilter play.filters.hosts { 允许所有主机访问 allowed = ["."] } 21 默认配置定义了一个anyhost路由标记,它可用于从过滤器中排除一个或多个路由 play.filters.hosts.routeModifiers.whiteList = [anyhost] +anyhost GET /healthcheck controllers.HealthController.healthcheck 如果白名单为空并且定义了黑名单,则允许的主机过滤器将仅应用于标记有黑名单配置中存在的标签的路由 play.filters.hosts.routeModifiers.whiteList = [] play.filters.hosts.routeModifiers.blackList = [external] +external GET / controllers.HomeController.index GET /healthcheck controllers.HealthController.healthcheck 22 日志级别 <!-- <root level="DEBUG">--> <!-- <appender-ref ref="STDOUT" />--> <!-- <appender-ref ref="FILE" />--> <!-- </root>--> 23 服务器中应用程序不允许访问 1.打开防火墙详细设置,找到受信规则中的共享的ICMPv4受信,并启用规则 2.新增受信规则,选择TCP,选择特定端口,起受信规则名,关闭应用重新启动