play

来源:互联网 发布:搜客通软件下载 编辑:程序博客网 时间:2024/06/02 12:22
play基本命令    play new 项目名             创建新的play应用    play eclipsify 项目名       将play应用转化为Eclipse项目    play run                    启动当前路径下的play应用(需要在play应用的根目录下使用)(会打印输出信息,阻塞当前进程)    play start                  启动当前路径下的play应用(需要在play应用的根目录下使用)    play stop                   停止当前路径下的play应用(需要在play应用的根目录下使用)创建一个play应用    打开命令行,进入需要创建项目的路径    play new 项目名    What is the application name? [xxx] 回车就行    这样就在当前目录创建了一个play应用搭建一个play框架的eclipse项目    打开命令行,进入需要创建项目的路径    cmd --> play new 项目名    What is the application name? [xxx] 回车就行    cmd --> play eclipsify 项目名    打开eclipse,导入项目    问题:        解决调试错误            打开/eclipse/项目名称.launch            搜索并删除 -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n        修改引用的play.jar为相对路径(团队合作)            <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xdebug -Dplay.debug=yes -Dplay.id= -Dapplication.path=&quot;${project_loc:dosql}&quot; -Djava.endorsed.dirs=&quot;-javaagent:&quot;/lib/play-1.2.3.jar&quot;"/>            要注意项目名称(${project_loc:dosql})和play.jar包版本play应用目录规范    app                 应用文件夹        controllers         控制器所在包                    models              模型所在包        views               页面所在文件夹            Application         正常页面所在文件夹            errors              错误页面所在文件夹    test                测试文件夹,存放测试代码             conf                配置文件文件夹        application.conf    主配置文件        routes              路由配置文件        messages            国际化配置文件        dependencies.yml    lib                 依赖jar文件    public              静态文件文件夹        images              图片文件夹        javascripts         js文件夹        stylesheets         样式表文件夹    eclipse             eclipse启动文件(eclipse应用中存在)路由语法    配置        Play路由器使用的配置文件为conf/routes        路由配置总是从HTTP方法开始,URI作为中间部分,最后的元素是Java调用。在路由文件中可以使用#进行注释:        格式:   HTTP方法(大写)      URI表达式       要调用的方法        如:     GET                 /clients        Application.index    HTTP方法        HTTP协议支持GET,POST,PUT,DELETE,HEAD方法,用于指定客户请求服务器的动作        可使用*号匹配所有请求方式            *       /clients        Application.index    URI表达式        可使用{}匹配动态内容            /clients/{id}            匹配 /clients/12121  或 /clients/toto            并且匹配的部分,控制器可以在HTTP参数map中获取该值        可使用正则             格式: /clients/{<正则>id}            例: /clients/{<[0-9]+>id} 匹配 id为数字的值        ?            请求路径后的/的有无是有区别的,可使用?消除区别            例: /clients/?            注意: URI除了尾斜线不允许有其他可选的部分。    Java调用        控制器规则            控制器需作为play.mvc.Controller的子类定义在controllers包中            控制器中必须存在指定的Action方法            必须声明为public static void方法        一般格式            类的全限定名称.方法名            如果包名为controllers,则可以省略            例: Application.index 表示将执行 controllers.Application类中的无参方法index        404            表示匹配的url将被忽略        指定静态参数            GET     /home           Application.page(id:'home')            GET     /pages/{id}     Application.page            则如果路径为/home,则会调用page方法,并将参数id的值设为"home"        静态资源            文件夹                格式: staticDir:路径                例  GET     /public/        staticDir:public                当客户端请求/public/*路径时,Play会从应用的public文件夹中获取相应的静态资源。这些资源将直接响应给客户端,并不需要服务器做进一步加工处理            文件                格式: staticFile:路径                例  GET     /home           staticFile:/public/html/index.html                当客户端通过GET方法请求/home时,服务器将不做任何处理直接把/public/html目录下面的index.html文件返回给客户端。    变量和脚本        与模板中的使用方法类似,在routes文件中可以使用${...}作为变量表达式,使用%{...}作为脚本表达式        例            %{ context = play.configuration.getProperty('context', '') }%            GET    ${context}         Secure.login    优先级        从上往下进行匹配,将执行最先匹配到的方法控制层    概述        Play的控制层位于/app/controllers包中        控制器需要继承play.mvc.Controller        控制器中,每个以public static声明,返回值为void的方法称为Action        Play会自动将HTTP请求参数转化为与之相匹配的Action方法参数(路由)        Action以调用结果方法来终止执行,即render系列的方法    获取HTTP参数        保存参数            play会自动将请求中的参数保存起来            包括 路由中的动态部分,查询字符串 和 请求体中的参数和值        使用params字段获取            play.mvc.Controller超类中定义了params字段,可通过get和getAll方法获得请求中的值                public String get(String key)                public String get(String key,Class<?> clazz) //可进行类型转换                public String[] getAll(String key)        在Action中定义同名参数获取            play自动在调用Action时将值放入到同名参数中,        注意            如果Action与HTTP之间的参数无法匹配,Play会将该参数设置为默认值(通常情况下对象类型为null,原始数据类型为0)。    参数类型转换        简单类型            Play可以实现所有Java原生的简单数据类型的自动转换,            主要包括:int,long,boolean,char,byte,float,double,Integer,Long,Boolean,Char,String,Float,Double。        日期类型            如果HTTP参数字符串符合以下几种数据格式,框架能够自动将其转换为日期类型                yyyy-MM-dd'T'hh:mm:ss’Z' // ISO8601 + timezone                yyyy-MM-dd'T'hh:mm:ss" // ISO8601                yyyy-MM-dd                yyyyMMdd'T'hhmmss                yyyyMMddhhmmss                dd'/'MM'/'yyyy                dd-MM-yyyy                ddMMyyyy                MMddyy                MM-dd-yy                MM'/'dd'/'yy            可以通过@As注解,指定特定格式的日期,例如                public static void articlesSince(@As("dd/MM/yyyy") Date from)         文件类型(文件上传)            只需在Action方法添加一个File类型的参数,参数名称要和页面提交的表单名称相同即可            前台                <form action="/Application/save" method="post" enctype="multipart/form-data">                    <input name="imageFile" type="file"><br>                    <input type="submit" value="提交">                </form>            后台                public static void save(File imageFile) {                    File file = new File("lib/"+imageFile.getName());                    imageFile.renameTo(file);                }        数组和集合类型            需要注意的是Map类型,如果一个name提交了多个值,则多个值用逗号分隔        POJO对象            前台表单名称 参数名.属性名            则自动填充到指定参数的属性中            可以指定多层        注意            如果参数可以匹配但不能正确进行数据转换,那么Play会先生成错误并添加到验证器的error对象集合中,然后将参数设置为默认值。    结果返回        返回文本内容             renderText(CharSequence pattern, Object... args)                还可以通过Java标准的格式化语法对输出的文本进行处理                renderText("There are %s","张三")        返回JSON            renderJSON(Object o)        返回xml            renderXml(Object o)        返回二进制内容            不是作为附件                renderBinary(InputStream is)            作为附件                renderBinary(InputStream is,String fileName)        返回模板            render(Object... args)                如果一个参数的没有,则返回 app/views/当前控制器类名/当前action名称.html                第一个参数如果是字符串并且是局部变量(不是没有引用),则为模板地址,否则为传递的数据                后面的参数为传递的数据,只允许传递局部变量,否则被忽略                模板的地址为相对路径, 例 Application/index.html 表示 /app/viewx/下的Application/index.html            renderTemplate(String templateName, Object... args)            renderTemplate(String templateName, Map<String,Object> args)            renderTemplate(Map<String,Object> args) //使用默认模板        注意            当调用结果方法后,后面的代码不会被执行到    为模板传递数据        可以使用renderArg字段            renderArgs.put("client", "张三");            在页面获取 ${client}        可以追加到render的参数中            render();            传递的数据必须是局部变量,否则被忽略,模板中可访问的变量与Java局部变量的名称一致    重定向        redirect(String url)    设置编码(默认utf-8)        为当前响应设置编码            response.encoding = "ISO-8859-1"        为当前请求设置编码            1. 在form标签中添加属性 accept-charset="ISO-8859-1" 通知浏览器当form表单提交的时候采用何种编码格式            2. 在form标签中添加表单元素(隐藏域) name为"_charset_" 通知服务端的Play采用何种编码方式            <form action="@{application.index}" method="POST" accept-charset="ISO-8859-1">                <input type="hidden" name="_charset_" value="ISO-8859-1">            </form>        定义全局编码格式            在application.conf配置文件中修改application.web_encoding属性    Action链        Play的每次HTTP请求只能调用一个Action,如果需要调用其他的Action,那么必须将浏览器重定向到相应的URL        调用控制器中其他Action方法也可以实现重定向,框架会拦截该调用并生成正确的HTTP重定向。    拦截器        概述            控制器中可以定义拦截方法(也可称之为拦截器),为控制器及其子类的所有Action提供服务            拦截器方法不能定义为public,但必须是static,并通过有效的拦截标记进行注解        @Before            使用@Before注解的方法会在每个Action调用之前执行            属性                unless 使用unless参数列出需要排除的方法                only 使用only参数把需要拦截的方法列举出来                unless和only参数对@After,@Before以及@Finally注解都适用            例:                @Before(unless="login")                static void checkAuthentification() {                    if(session.get("user") == null) login();                }        @After            使用@After注解的方法会在每个Action调用之后执行        @Catch            如果有Action方法抛出了异常,那么使用@Catch注解的方法就会执行            抛出的异常会以参数的形式传递到@Catch注解的方法中            例:                @Catch(IllegalStateException.class)                public static void logIllegalState(Exception e) {                    System.out.print(e);                }            属性                value       拦截的异常类型的Class对象                priority    多个@Catch指定优先级        @Finally            @Finally注解的方法总是在每个Action调用之后执行(无论Action是否成功执行)        @with            使用@with注解调用其他控制器中已经定义好的拦截方法            在类声明上使用,相当于本类定义了那么多拦截方法    Session和Flash作用域        在Play开发中,如果需要在HTTP请求之间保存数据,可以将数据保存在Session或者Flash内。        保存在Session中的数据在整个用户会话中都是有效的,而保存在Flash的数据只对下一次请求有效。        Session和Flash作用域中的数据都是采用Cookie机制添加到随后的HTTP响应中的(并没有存储在服务器上的),所以数据大小非常有限(不能超过4K),而且只能存储字符串类型的数据。        如果需要在特定的会话中缓存一些数据,那么可以使用Play内置的缓存机制模板    模板语法        概述            表达式      ${…}            标签        #{tagName /}            引用        @{…} 或者 @@{…}            国际化      &{…}            注释        *{...}*            脚本        %{...}%        表达式 ${…}            例: ${client.name}            首先需要向模板注入对象client,之后就可以在模板中输出client对象的name属性            如果不能确定向模板注入的client对象是否为null,可以使用如下Groovy快捷语法:                <h1>Client ${client?.name}</h1>            此时,只有client不为null的情况下,才进行client.name的输出。        标签 #{tagName /}            概述                标签是能够附带参数调用的模板片段                如果标签只有一个参数,按照约定,参数的名称为arg,并且该参数名是可以省略的                例如,可以使用#{script}标签加载JavaScript文件                    #{script 'jquery.js' /}                Play模板中的标签必须是闭合的                    #{script 'jquery.js'/}  或                    #{script 'jquery.js'}#{/script}            内置标签                #{script}       引入外部js文件                    参数                        arg         要引入的js文件                    例                        #{script 'jquery.js' /}                #{list}         迭代集合                    参数                        items       要遍历的集合                        as          变量的名称                    例                        #{list items:client.accounts, as:'account' }                            <li>${account}</li>                        #{/list}        引用 @{…}或者@@{…}            在模板中使用@{…}引用 可以通过路由器逆向生成URL                <a href="@{Clients.showAccounts(client.id)}">All accounts</a>                调用了Clients控制器中的showAccounts Action方法,并传递了client.id参数            @@{…}引用的使用语法与@{…}相同,只不过生成的是绝对URL(尤其适用于邮箱)        国际化 &{…}            首先需要在conf/messages文件中进行国际化定义                clientName=The client name is %s            之后在模板中就可以通过&{...}显示该国际化信息了                <h1>&{'clientName',client.name}</h1>        注释 *{…}*            使用*{…}*标记的内容会被模板引擎忽略        脚本 %{…}%            脚本是更加复杂的表达式集合,能够声明一些变量或者定义一些语句            也可以直接使用out内置对象输出动态内容                %{                    fullName = client.name.toUpperCase()+' '+client.forname;                    out.print('<h1>'+fullName+'</h1>');                }%                <h1>Client ${fullName}</h1>        转义            模板引擎默认对所有的动态表达式进行转义                如果模板中变量${title}的内容为<h1>Title</h1>,在页面输出时会自动进行转义                ${title} --> &lt;h1&gt;Title&lt;/h1&gt;            可以通过调用扩展方法raw(),以非转义的形式在页面中输出                ${title.raw()} --> <h1>Title</h1>            如果需要显示大量的非转义HTML内容,可以使用#{verbatim /}标签                #{verbatim}                    ${title} --> <h1>Title</h1>                #{/verbatim}    模板继承        #{extends /} 和 #{doLayout /}标签进行继承        #{get} 和 #{set}标签在模板与父模板之间进行参数传递        例             父模板simpledesign.html                <html>                    <head>                        <title>#{get 'title' /}</title>                        <link rel="stylesheet" type="text/css" href="@{'/public/stylesheets/main.css'}" />                    </head>                    <body>                        <h1>#{get 'title' /}</h1>                        #{doLayout /}                        <div class="footer">Built with the play! framework</div>                    </body>                </html>            说明                #{get 'title' /}    表示在子模板中设置值                #{doLayout /}       起到占位的作用,其他所有继承于此模板的页面内容都将显示在#{doLayout /}所占的页面区块            子模板                #{extends 'simpledesign.html' /}                #{set title:'A decorated page' /}                This content will be decorated.            说明                #{extends 'xxx' /}      继承与某个模板                #{set title:'xxx' /}    向父模板传递值    内置标签        常用            #{extends}                子模板可以通过#{extends}标签继承已经定义好的装饰模板                示例                    #{extends 'main.html'/}                    <h1>Some code</h1>            #{doLayout /}                表示父模板中在标签处可以插入子模板的内容                示例                    <div id="content">                        #{doLayout /}                    </div>            #{set},#{get}                #{set}标签用于设置可以在模板中使用的变量。                #{get}标签的作用是获取由#{set}标签定义的值                在Play的模板中,通过get/set机制,可以使父模板和子模板间进行通信                示例                    #{set email:'china@oopsplay.org'}   设置了模板变量email的值                    #{get 'email'}                      获取email的值                可以在#{set}标签体内定义变量的值                示例                    #{set 'title'}                        Profile of ${user.login}                    #{/set}                可以在#{get}标签体内设置当变量不存在时的缺省值,如下例当title变量不存在时,会显示Homepage。                示例                    <head>                        <title>#{get 'title'}Homepage #{/}                     </head>            #{script}                用于生成一个<script>元素,可以引入/public/javascripts目录下的JavaScript文件。无需在地址前加上默认父目录/public/javascripts。                示例                    #{script 'jquery-1.5.1.min.js' /}            #{stylesheet}                可以引入/public/stylesheets目录下的CSS文件                示例                    #{stylesheet 'default.css' /}            #{if},#{ifnot}                #{ifnot}执行时具体的作用与#{if !condition}等价                示例                    #{if user.countryCode == 'en' }                        Connected user is ${user}                    #{/if}            #{else},#{elseif}                #{else}标签通常与#{if}标签配合使用                示例                    #{if user}                        Connected user is ${user}                    #{/if}                    #{else}                        Please log in                    #{/else}                #{else}标签也可以与#{list}标签一起使用,当使用#{list }标签进行迭代的集合为空时,可以执行#{else}标签中的内容                示例                    #{list items:task, as:'task'}                        <li>${task}</li>                    #{/list}                    #{else}                        Nothing to do...                    #{/else}            #{list}                遍历集合                示例                    <ul>                        #{list items:products, as:'product'}                            <li>${product}</li>                        #{/list}                    </ul>                    #{list items:0..10, as:'i'}                        ${i}                    #{/list}                预定义变量,名称为 循环变量_XXX,下面用note代表循环变量                    note_index:表示当前对象在集合中的序号。                    note_isFirst:表示是否是集合中的第一个对象。                    note_isLast:表示是否是集合中的最后一个对象。                    note_parity:表示当前对象在集合中序号的奇偶值,可能是even或odd。            #{include}                在当前模板中导入另一个模板,并且当前模板中的所有变量对导入的模板透明。                示例                    <div id="tree">                        #{include 'tree.html' /}                    </div>            #{verbatim}                使输出内容不转义(默认转义)                示例                    #{verbatim}${'&amp;'}#{/verbatim}        表单            #{authenticityToken /}                可以防止跨站请求伪造,同时也能消除刷新提交和后退提交所带来的困扰                会为服务器和客户端表单生成相同的随机令牌,并以隐藏的input输入域的形式嵌入表单,一起提交到服务器                在表单中加入即可,相当于<input type="hidden" name="authenticityToken" value="1c6d92fed96200347f06b7c5e1a3a28fa258ef7c">        验证错误信息            #{ifError},#{ifErrors}                #{ifError}标签可以判断指定的作用域中是否有action添加的验证错误的信息                #{ifErrors}只要模板中有任何的验证错误信息,都可以将其输出                示例                    #{ifError 'user.name'}                      <p>                        User name is invalid:                         #{error 'user.name' /}                      <p>                    #{/ifError}                    --------------------------------                    #{ifErrors}                      <p>Error(s) found!</p>                    #{/ifErrors}            #{error},#{errorClass},#{errors}                #{error}标签的作用是输出验证后的错误消息                示例                    #{error 'user.name'/}                #{errorClass}标签的作用是如果存在指定的验证错误消息,则标签在解析时将被替换为文本hasError,一般在class中使用                示例                    <input name="name" class="#{errorClass 'name'/}">                    相当于<input name="name" class="${errors.forKey('name') ? 'hasError' : ''}">                #{errors}标签可以遍历当前的验证错误对象集合,其使用方式与 #{list}非常类似,循环体中使用的对象变量名称是${error}                示例                    <ul>                        #{errors}                            <li>${error}</li>                        #{/errors}                    </ul>    内置函数        格式化日期            ${new Date(1275910970000).format('dd MMMM yyyy hh:mm:ss')}        格式化数字            ${42.format('000.00')}        字符串转义            escape(),escapeHtml()   对字符串进行转义处理            raw()                   跳过模板对字符串的自动转义处理            urlEncode()             将URL查询字符串中用到的特殊符号转义输出        数组操作(字符串数组)            contains(string)        判断数组中是否包含指定元素    内置对象        所有添加到renderArgs作用域的对象,都会以变量的形式注入模板。        默认的内置对象            errors      验证错误信息结果集,对应play.data.validation.Validation.errors()            flash       Flash作用域,对应play.mvc.Scope.Flash            lang        当前使用的语言,对应play.i18n.Lang            messages    消息映射变量,对应play.i18n.Messages            out         引用页面输出流,对应java.io.PrintWriter            params      当前参数变量,对应play.mvc.Scope.Params            play        Play框架类,对应play.Play            request     当前请求对象,对应play.mvc.Http.Request            session     Session作用域,对应play.mvc.Scope.Session域模型    属性模拟        在Play中把属性变量声明为public,并可以不提供set/get方法,可以使用等号为属性赋值        运行时Play会自动生成相应的getXxx/setXxx方法(将声明为public的字段都视为属性)        使用等号为属性进行赋值,也会在程序加载时自动转换为set方法        如果存在自己定义的get/set方法,则play会优先选择手动编写的方法    数据库配置        在conf/application.conf文件中添加            db.url=jdbc:mysql://localhost/test            db.driver=com.mysql.jdbc.Driver            db.user=root            db.pass=123456        可选配置方言            jpa.dialect=<dialect>        获取Connection对象            Connection conn = play.db.DB.getConnection();            conn.createStatement().execute("select * from products");    数据持久化        Play的持久层框架采用的是Hibernate,使用Hibernate(通过JPA)自动地将Java对象持久化到数据库        在实体类上增加@javax.persistence.Entity注解后,Play会自动为其开启JPA实体管理器。        得到实体管理器            EntityManager em = JPA.em();        Play提供的play.db.jpa.Model类提供了对模型自己进行增删改查的便捷方法,可以使用实体类继承Job异步处理    概述        Job就是需要在指定的时刻或者时间段内执行的任务,通常由作业调度程序来执行调度和管理。        需要继承play.jobs.Job类,没有返回值就重写doJob方法,有返回值就重写doJobWithResult方法        job必须在单独的一个文件中,不能有同级的类,job不能访问其它类的方法?    在类声明上添加注解(开发模式先访问一下才会开始执行)        @OnApplicationStart     在应用程序启动时执行        @OnApplicationStop      在应用程序停止时执行        @Every                  周期性执行任务,例@Every("1h"),可选单位d,h,min,mn,s (min和mn都为分钟)        @On                     在具体的某个时间点执行,例@On("0 0 12 * * ?")    CRON表达式        @On标签中使用的是Quartz库的CRON表达式。        CRON表达式是由7个子表达式组成的字符串,每个子表达式都描述了单独的日程细节。        这些子表达式用空格分隔,分别表示:            Seconds 秒            Minutes 分钟            Hours 小时            Day-of-Month 一个月中的某一天            Month 月            Day-of-Week 一周中的某一天            Year 年(可选)        具体CRON表达式的例子:"0 0 12 ? * WED",表示“每周三的中午12:00”。    手动调用job        创建实现类的对象,并使用now()方法即可,可返还一个结果,默认为异步执行,如果想阻塞线程,可以调用结果的get方法        every(str)可手动启动job,并指定间隔时间JPA支持    启用JPA实体管理        Play会自动查找标记为javax.persistence.Entity注解的类        @javax.persistence.Entity注解的作用是通知Play对当前实体类进行管理    获得JPA实体管理器        JPA.em()    事务管理        Play会自动进行事务管理,在每次发送HTTP请求时自动开启事务,发送HTTP响应完毕后提交事务。        Play为事务管理控制提供了注解的支持。        如果需要将Action声明为只读事务,可以在Action方法上标记@play.db.jpa.Transactional(readOnly=true)注解;        如果执行当前方法时无需开启事务,可以在Action方法上标记@play.db.jpa.NoTransaction;        如果当前控制器中所有方法都无需开启事务,可以直接在控制器上标明@play.db.jpa.NoTransaction。        数据验证    使用验证器进行数据验证        框架为每个请求绑定了验证器。应用代码中可以通过以下三种方式对数据进行验证            1.使用API                public static void hello(String name) {                     validation.required(name);  //验证name参数是否被赋值                }            2.在方法中添加注解                public static void hello(@Required String name){                }            3.在定义域模型时添加注解                public class User extends Model {                   @Required                   public String name;  //为User的name属性添加@Required验证                }                 //直接使用@Valid注解对POJO参数进行验证                public static void save(@Valid User user) {                 }        当验证不通过时,验证器会将错误以play.data.validation.Error的形式保存,因此每个验证器以集合的形式维护了一系列的error对象。每个error对象有key和message两个属性:            key:该属性帮助我们标识引起错误的元素。key的值可以任意设定,默认与验证的数据同名。            message:验证消息,用于描述验证不通过的错误信息。message可以是纯文本或指向消息包(message bundle)的key(通常为了支持国际化)。        在验证结束后我们可以检查是否有error产生,并将验证消息打印出来            public static void hello(String name, Integer age) {                 validation.required(name);                 validation.required(age);                 validation.min(age, 0);                 if(validation.hasErrors()) {                                     for(Error error : validation.errors()) {                         System.out.println(error.message());                     }                 }            }        方法说明            error.message()     返回此error对象的message            error.message(str)  设置此error对象的key,然后返回此对象的message(如果没有在配置文件中找到指定key,则直接返回key)    设置错误消息提示        如果validation.required(name);校验失败,则error.message()的值为"Required",可以自定义错误消息提示        Play提供了三种方式自定义错误消息提示:            在项目的conf/messages文件中自定义某一类错误校验的提示消息            在项目的conf/messages文件中自定义错误校验的提示消息,并为error设置key            直接为error设置message        自定义某一类错误校验的提示消息            在conf/messages中修改                不带参数: validation.required=Please enter a value                      含有参数: validation.required=%s is required                # %s自动替换为 error.key        自定义错误验证消息(手动使用)            在conf/messages中添加                validation.required.em = You must enter the %s!            使用(三种方法都可以)                1.使用API设置key                    validation.required(manualKey).message("validation.required.em")                2.使用注解设置key                    public static void hello(@Required(message="validation.required.em") String name) {                     }                 3.JavaBean的属性中设置key                    public class Person extends Model {                        @Required(message = "validation.required.em")                       public String name;                     }                     public static void hello(@Valid Person person) {                    }         直接为error设置message            使用方法与自定义错误验证消息相同,只是不在conf/messages文件中添加配置            原因                error.message(str)方法的作用为 返回此对象的message,如果没有在配置文件中找到指定key,则直接返回key                所以,通过error.message(str)方法设置key的值,并且不在配置文件中添加配置.相当于直接设置了message的值        注意            在conf/message文件中配置时,如果消息提示中,需要获取 验证方式的参数                使用 %2$s  %3$s 依次获取(数字为 %2$d  %3$d)            如范围验证                validation.range=Not in the range %2$d through %3$d    在页面显示错误消息提示        示例            #{ifErrors}               <h1>Oops...</h1>               #{errors}                   <li>${error}</li>               #{/errors}            #{/ifErrors}            #{else}               Hello ${name}, you are ${age}.            #{/else}    完整示例        控制器            提供两个action方法,一个用于返回表单(index),一个用于接收提交的表单内容(hello)                public static void index() {                    render();                }                public static void hello(String name, Integer age) {                    validation.required(name);                    validation.required(age);                    validation.min(age, 0);                    if(validation.hasErrors()) {                        params.flash();     // 将HTTP参数保存在Flash作用域中                        validation.keep();  // 在下一个请求中保持错误信息的集合                        index();                    }                    render(name, age);                }        页面            #{form @Application.hello()}               <div>                  Name: <input type="text" name="name" value="${flash.name}" />                  <span class="error">#{error 'name' /}</span>               </div>               <div>                  Age: <input type="text" name="age" value="${flash.age}" />                   <span class="error">#{error 'age' /}</span>               </div>               <div>                  <input type="submit" value="Say hello" />                </div>            #{/form}    内置验证方式        required        验证是否为空        equals          验证两个值是否相等        range           验证是否在给定的两个数值范围内        phone           验证是否为合法的电话号码        email           验证E-mail地址是否合法        url             验证是否为合法的URL        match           验证是否匹配给定的正则表达式                max             验证数值大小是否大于给定的值        min             验证数值大小是否小于给定的值        maxSize         验证字符串长度是否大于给定的值        minSize         验证字符串长度是否小于给定的值                future          验证是否为相对未来的时间        past            验证是否为相对过去的时间        ipv4Address     验证是否为符合ipv4规则的IP地址        ipv6Address     验证是否为符合ipv6规则的IP地址        isTrue          验证String或者Boolean类型变量是否为true    自定义验证        步骤            自定义实现类,继承Check类,重写isSatisfied方法            使用@CheckWith注解,在注解中传递实现类的class对象        示例            public class User {                @Required                @CheckWith(MyPasswordCheck.class)                public String password;                                static class MyPasswordCheck extends Check {                    public boolean isSatisfied(Object user, Object password) {                        return notMatchPreviousPasswords(password);                    }                }            }        缓存    概述        缓存是用来避免频繁到服务器端获取数据而建立的一个存取更快的临时存储器。缓存的容量相对较小,但执行速度非常快,其主要作用为:            存储系统经常访问的数据。            存储耗时较长的计算结果。        当我们在使用缓存时,必须明确其自身特性:            缓存存在于内存中(不进行持久化),只是用于存放暂时性的数据,时间一到就会过期。            因此缓存并不是一个安全的存储器,不能保证数据可以永久存在。            如果发现数据在缓存中已过期,需要重新获取数据,并再次放入缓存        与Session对象不同,缓存中的内容是独立的,不会绑定任何特定的用户。所以一般使用session.getId作为key将数据存入缓存    API        Cache.get(id, Product.class)        Cache.set("product_"+id, product, "30mn");        Cache.delete("product_"+id);                Cache.safeGet(id, Product.class)        Cache.safeSet("product_"+id, product, "30mn");        Cache.safeEelete("product_"+id);        注意:            带safe前缀的方法是阻塞的,而标准方法是非阻塞的            delete方法会立即返回结果,并没有等待缓存对象是否被真正地物理删除。            因此,如果程序执行期间发生了错误(例如IO错误),缓存对象可能仍然存在,并没有被删除。            如果操作需要确保缓存对象被删除,可以使用safeDelete方法,该方法是阻塞式的,并返回一个布尔值标识对象是否被成功删除。        示例            public static void showProduct(String id) {                Product product = Cache.get(id, Product.class);                if(product == null) {                    product = Product.findById(id);                    Cache.set("product_"+id, product, "30mn");                }                render(product);            }                         public static void addProduct(String name, int price) {                Product product = new Product(name, price);                product.save();                showProduct(id);            }                         public static void editProduct(String id, String name, int price) {                Product product = Product.findById(id);                product.name = name;                product.price = price;                Cache.set("product_"+id, product, "30mn");                showProduct(id);            }                         public static void deleteProduct(String id) {                Product product = Product.findById(id);                product.delete();                Cache.delete("product_"+id);                allProducts();            }    配置Memcached        如果项目要启用Memcached,需要在application.conf中打开Memcached开关,并设置Memcached的守护进程地址:            memcached=enabled            memcached.host=127.0.0.1:11211        我们还可以指定多个守护进程地址,使之连接到同一个分布式缓存:            memcached=enabled            memcached.1.host=127.0.0.1:11211            memcached.2.host=127.0.0.1:11212常用    Play.applicationPath.getPath()      获得项目路径    Request.current()                   获取request对象    Response.current()                  获取response对象
0 0
原创粉丝点击