PlayFramework 使用帮助列表
http://playcheatsheet.appspot.com/show/ArtemMedeu/armed/play-cheatsheets
?
?
PlayframeworkLoginPlay! Framework cheat sheetController/link?i=32&n=patrick
public static void link(int i, String n)
public static void link(Integer i, String n)
public static void link(Long i, String n)
Controller/show?id[0]=1&id[1]=2&id[2]=3&id[3]=4
public static void show(Long[] id)
public static void show(List?id)
public static void show(Set?id)
Controller/get?date=02-18-1972
public static void get(@As("MM-dd-yyyy") Date date)
(@As(binder=MyCustomStringBinder.class))
Custom parameter binder
Send File as multipart/form-data encoded post request
public static void create(String comment, File attachment)
?client.name=paul&client.email=contact@crionics.com
public static void create(Client client) POJO binding
@NoBinding
Marks a non bindable field
@OnApplicationStart
@On("0 0 12 ? ? ?")
@Every("1h")
public class Bootstrap extends Job {public void doJob() {...} }
Logger.info("Action executed ...");
Logger.debug("A log message");
Logger.error(ex, "Oops");
Logging configuration lives in application.conf
@CacheFor("1h") public static void index() { ... }
Caches the result of the action for 1h
Play.configuration.getProperty("blog.title");
Access to the configuration file
Query query = JPA.em().createQuery(“query”);
Access the persistence manager
${ client.name }
Evaluates and outputs a variable
${ client?.name }
Displays client.name only if client not null
@{ Controller.action() }
Calculates url relative path to action
@@{ Controller.action() }
Calculates url absolute path to action
&{ message.key }
Message are maintained in conf/messages, supports i18
?{ this is a comment }?
What else to say?
%{ out.print(“HelloWorld”) }%
Groovy scripts for UI logic
#{ my.custom.tag /}
A typical custom tag – page context not shared
#{extends ?page.html?/}
#{doLayout /}
Master template decorators
#{get 'title'}Used if title not set#{/get}
#{set title:?Home Page?}
Shared variables between page and master templates
#{include 'tree.html'/}
Includes fragment – page context is shared
#{script id:'myscript' , src:?script.js', charset:'utf-8' /}
#{stylesheet id:'main', media:'print', src:'print.css' /}
Imports script & styles in the page
#{a @Application.logout() }Disconnect#{/a}
#{form @Client.create() , id:'form' enctype:'multipart/form-
data' } ... #{/form}
Handy tags to create anchors and forms
#{verbatim}${'&'}#{/verbatim}
Disables HTML escaping
#{i18n /}
Exports localized msgs in Javascript
#{ifErrors} <p>Error(s) found!</p> #{/ifErrors}
Checks for validation errors
#{ifError 'user.name'} #{error 'user.name' /} #{/ifError}
Checks a given error
#{errors} <li>${error}</li> #{/errors}
Iterates over the current validation errors
#{if cond}...#{/if}#{elseif cond}...#{/elseif}#{else}...#{/else}
#{ifnot cond}...#{/ifnot}
Conditional constructs
#{list items:0..10, as:'i'}${i}#{/list}
#{list items:'a'..'z', as:'l'}${l} ${l_isLast ?'':'|' }#{/list}
#{list users}${_}#{/list}
Loop constructs
#{list items:task, as:'task'}${task}#{/list}
#{else}No tasks on the list#{/else}
Tip: Else can be used along with list
#{cache ?key?, for:?15min?}...#{/cache}
Caches content for 15 minutes
@Entity(name=”sql_tbl”) public class Post extends Model
Specifies that the class is persistent
@Embedded
Defines this field as being embedded
@EmbeddedId
Defines this field as being (part of) the identity for the class,
and being embedded into this class
@Embeddable
Specifies that the class is persistent embedded in another
persistent class
@MappedSuperclass
Specifies that this class contains persistent information to be
mapped in a child
Convenient way to implement database independent trigers
@PrePersist
Defines this method as being a callback for pre-persist events
@PostPersist
Defines this method as being a callback for post-persist
events
@PreRemove
Defines this method as being a callback for pre-remove events
@PostRemove
Defines this method as being a callback for post-remove
events
@PreUpdate
Defines this method as being a callback for pre-update
events
@PostLoad
Defines this method as being a callback for post-load events
@NamedQuery(name=”q1”, “jpql_query”);
Defines a named JPQL query to use in the persistence unit
@NamedNativeQuery(name=”q2”,”sql_query”)
Defines a native SQL query for use in the persistence unit
@SqlResultSetMapping
Used to map a native sql query result to the object model
THIS IS ONLY A SUBSET OF THE JPA2
ANNOTATIONS, HIBERNATE ALSO COMES WITH ITS
OWN NON STANDARD SET
public class ApplicationTest extends FunctionalTest
Functional test are unit tests with an http orientation
newRequest()
newResponse()
GET(request, url)
PUT(request, url)
POST(request,url)
DELETE(request,url)
assertStatus(404, response)
assertHeaderEquals(headerName, value, response)
assertContentEquals(content, response)
assertContentType(type,response)
clearCookies()
%test.db=mem
%test.jpa.ddl=create-drop
# Dev configuration
%dev.http.port=8080
%dev.application.log=DEBUG
%dev.application.mode=dev
# Production configuration
%prod.http.port=80
%prod.application.log=INFO
%prod.application.mode=prod
play run --%prod or play run --%dev or play test
Will pick the appropriate configurations
@Required String lastname
@IsTrue String agree
@Max(7500) Integer wordCount
@Min(18) Long age
@MaxSize(2083) String value
@MinSize(42) String value
@Email String address
@Equals("passwordConfirmation") String password
@InFuture String dueDate
@InFuture("1979-12-31") String birthDate
@Match("[A-Z]{3}") String abbreviation
@Match("(directDebit|creditCard|onReceipt)")
@Past String actualDepartureDate
@Past("1980-01-01") String birthDate
@Range(min = 17500, max = 40000) String wordCount
@URL String address
@Valid Person person
Pojo validation – class Person needs validation annotations
render(params...);
Renders template with given parameters, text/html
renderXML(params...);
Renders parameters as application/xml
renderJson(params...);
Renders parameters as application/json
renderText(params...);
Renders parameters as text/plain
renderTemplate(“Clients/showClient.html”, id, client);
Bypasses default template
redirect(“http://www.crionics.com”);
Http redirect to the given URL
From an action, calling another Controller.action()
The framework transparently generates a REDIRECT!
errors
The validation errors raised in the controller
flash
Flash scope
lang
The negotiated language
messages
The messages map, i18
out
The output stream writer
params
Current parameters
play
Main framework class
request
The current http request
session
The session scope
@FastTags.Namespace("crionics")
public class RecaptchaTag extends FastTags {
public static void _recaptcha(Map<?, ?> args, Closure body,
PrintWriter out, ExecutableTemplate template, int fromLine)
/app/view/tag/domain/mytag.tag
Custom tag can be called as {#domain.mytag/}
${ ['red', 'green', 'blue'].join('/') }
red/green/blue
${ (["red", "green", "blue"] as String[]).add('pink').join(' ') }
red green blue pink
${ (['red', 'green', 'blue'] as String[]).contains('green') }
true
${(['red', 'gr', 'blue'] as String[]).remove('gr').join(' ')}
red blue
${ ['red', 'green', 'blue'].last() }
blue
${ new Date(new Date().getTime() - 1000000).since() }
16 minutes ago
${new Date(1275910970000).format('dd MMMM yyyy
hh:mm:ss')}
07 June 2010 01:42:50
${ 1275910970000.asdate('dd MMMM yyyy hh:mm:ss') }
07 June 2010 01:42:50
${726016L.formatSize()}
709KB
${ 42.formatCurrency('EUR').raw() }
€ 42.00
${ 42.page(10) }
5
journ${ ['cnn', 'c+', 'f2'].pluralize('al', 'aux') }
journaux
${ "lorum ipsum dolor".capAll() }
Lorum Ipsum Dolor
${ "lorum ipsum dolor".camelCase() }
LorumIpsumDolor
${ "lorum ipsum dolor".capFirst() }
Lorum ipsum dolor
${ "lorum ipsum dolor".cut('um') }
lor ips dolor
${ "The <blink>tag</blink> is evil".escape().raw() }
The <blink>tag</blink> is evil
${ "one\ntwo".nl2br() }
one<br/>two
${ '<' } ${ '<'.raw() }
< <
${ " (') (") ".escapeJavaScript().raw() }
(\') (")
${ "".yesno('yes', 'no') }
no
${ "not empty".yesno('yes', 'no') }
yes
${"Stéphane épardaud".noAccents()}
Stephane Epardaud
${ "The Play! framework?s manual".slugify() }
the-play-framework-s-manual
${ "x".pad(4).raw() }
x
@OneToOne(entity, fetch=[LAZY,EAGER], nullable=true)
Defines this field as being a 1-1 relation with another
persistent entity
@OneToMany(mappedBy="remote_attribute")
Defines this field as being a 1-N relation with other persistent
entities
@ManyToMany(cascade=[ALL, PERSIST, MERGE,
REMOVE, REFRESH, DETACH])
Defines this field as being a M-N relation with other persistent
entities
@ManyToOne
Defines this field as being a N-1 relation with another
persistent entity
@JoinColumn(name = "id_connector")
Defines a column for joining to either a join table or foreign key
relation.
@JoinTable(name = "nm_table", joinColumns =
{ @JoinColumn(name = "id_coupon", nullable = false) },
inverseJoinColumns = { @JoinColumn(name =
"id_campaign", nullable = false) })
Used to map ManyToMany relationships
#{selenium}
clearSession()
open(‘/admin’)
assertTextPresent(‘Login’)
type(‘login’, ‘admin’)
type(‘password’, ‘secret’)
clickAndWait(‘signin’)
// Verify that the user in correctly logged in
assertText(‘success’, ‘Welcome admin!’)
#{/selenium}
classpath
Display the computed classpath
id
Define the framework ID, used for multi environment config
secret
Generate a new secret key, used for encryption
install
Install a module
list-modules
List modules available from the central modules repository
modules
Display the computed modules list
new
Create a new application
new-module
Create a module
build-module
Build and package a module
eclipsify
Create all Eclipse configuration files
netbeansify
Create all NetBeans configuration files
idealize
Create all IntelliJ Idea configuration files
javadoc
Generate your application Javadoc
auto-test
Automatically run all application tests
clean
Delete temporary files (including the bytecode cache)
test
Run the application in test mode in the current shell
precompile
Precompile all Java sources and templates to speed up
application start-up
war
Export the application as a standalone WAR archive
run
Run the application in the current shell
start
Start the application in the background
stop
Stop the running application
restart
Restart the running application
status
Display the running application’s status
out
Follow logs/system.out file
pid
Show the PID of the running application
check
Check for a release newer than the current one
help
Display help on a specific command
WARNING: Play Session is NOT the J2EE session
session and flash use cookies! 4kb limit/20 cookies max
session.getId();
Returns the session Id – in most cases: a must have!
session.put(String key, String value);
session.get(“user_flag”);
Values are limited to Strings, 4kb max
flash.put(String key, String value);
flash.get(String key);
Flash entries are discarded at end of next call
Cache.set(“key_” + id, product, “30mn”);
Set cache value for 30 minutes
Cache.get(“key_” + id, Product.class);
Get cache value, may return null
Cache.delete(“key_” + id);
Non blocking cache delete
Cache.safeDelete(“key_” + id);
Blocking cache delete
@Before ? action ? @After ? template ? @Finally
Interceptions evaluation order
@Before static void checkAuthentification()
@After static void log()
@Finally static void audit()
You get the idea
@With(Secure.class)
public class Admin extends Application
Custom interceptors at the controller scope
WS.url(“http://s.com/posts”).get().toJSON();
HTTP get request to JSON
WS.url(“http://s.com/”).post().toXML();
HTTP post request to XML
XML.getDocument(String);
String to XML
XML.serialize(Document);
XML to String
XPath.selectNodes(String xpath, Object node);
XPath expression evaluator
Files.copy(File,File);
File copy
Files.copyDir(File,File);
Recursive directory copy
Files.delete(File);
Files.deleteDirectory(File);
Deletes file/directory
IO.readLines(File);
IO.readContentAsString(File);
IO.readContent(File);
IO.write(byte[],File);
Read/Write file contents
Images.crop(File orig,File to, int x1, int y1, int x2, int y2);
Images.resize(File orig, File to, int w, int h);
Images.toBase64(File image);
Handy methods!
Crypto.encryptAES(String);
Crypto.decryptAES(String);
Encryption using the application secret key
Crypto.passwordHash(String);
Create an MD5 password hash
Codec.UUID();
Generates unique IDs
Codec.byteToHexString(byte[] bytes);
Write a byte array as hexadecimal String
Codec.encodeBASE64(byte[] value);
Codec.decodeBASE64(String base64);
Encode/Decode a base64 value
Codec.hexSHA1(String);
Build a hexadecimal SHA1 hash for a String
Query query = JPA.em().createQuery(“jpql_query”);
Access the persistence manager
Post post = Post.findById(id);
List?posts = Post.findAll();
Finder methods
post.save();
Saves the object to the persistent store
boolean post.validateAndSave();
true if object validates and saved, see validation annotations
List?posts = Post.all().from(50).fetch(100);
Read records 50 to 100, if any
Post.find("select p from Post p, Comment c where c.post
= p and c.subject like ?", "%hop%");
Parametrized lookup using a join
long userCount = Post.count("author=?", connectedUser);
long postCount = Post.count();
Counting records
JPAPlugin.startTx(boolean readonly);
JPAPlugin.closeTx(boolean rollback);
Custom transaction control methods
JPA.setRollbackOnly();
Forces a transaction rollback
@GeneratedValue(strategy = [NONE, TABLE, SEQUENCE,
IDENTITY, AUTO])
Used to generate auto indexes
@SequenceGenerator
Defines a generator of values using sequences in the
datastore for use with persistent entities
@TableGenerator
Defines a generator of sequences using a table in the
datastore for use with persistent entities
@Table(name=”sql_tbl”, catalog=””, schema=””)
Defines the table where this class will be stored
@Id
Defines this field as being (part of) the identity for the class
@Version
Defines this field as storing the version for the class
@Basic
Defines this field as being persistent, can be omitted
@Transient
Defines this field as being transient (not persisted)
@Lob(fetch=[LAZY, EAGER], type=[BLOB,CLOB])
Defines this field as being stored as a large object
@UniqueConstraint(primary=false, String columns[])
Used to define secondary indexes
@Temporal(DATE,TIME,TIMESTAMP)
Should only be used on java.util.Date and Calendar fields
@Enumerated(ORDINAL, STRING)
Defines this field as storing an enumerated class
@Column(name=”sql_column_name”)
Should the table column name be different from the field name
@Test public void getRental() { ... }
@Test (expected = NumberFormatException.class )
@Ignore
Ignore any errors
@Test (timeout=400)
Test will fail after 400 milliseconds
@Before public void prepareRecords();
Run before each unit test
@After public void cleanupJunk()
Run after each unit test
@BeforeClass void whenTestClassInstanciated();
Run once, when the test class gets instantiated
@AfterClass void whenTestClassCompleted()
Run once when the test class is dismissed
Assert.assert
There are tons of assertions, look it up
@Before public void setUp() { Fixtures.deleteAll();
Fixtures.load("data.yml");}
Fixtures is used to initialize the datastore ahead of a unit test
#{fixture delete:'all', load:'data.yml' /}
#{selenium} ... #{/selenium}
Same idea using a selenium test