
рд╢реБрдн рджрд┐рди, рдкреНрд░рд┐рдп Kravravchiansред
рд╣рдо,
рдкреЛрдЧреНрд░реЛрдо рдкреНрд░реЛрдЧреНрд░рд╛рдорд░, рдмрд╣реБрдд рдмрд╛рд░ рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрдм рдПрдХ рдирдИ рднрд╛рд╖рд╛ рдПрдХреНрд╕ рдпрд╛ рдлреНрд░реЗрдорд╡рд░реНрдХ рд╡рд╛рдИ рд╕реАрдЦрддреЗ рд╣реИрдВ - рдкрд░рд┐рдЪрдпрд╛рддреНрдордХ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рдмрд╛рдж рдХреНрдпрд╛ рд▓рд┐рдЦрдирд╛ рд╣реИ рдлрд┐рд░ рднреА рдПрдХ рдФрд░ рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб? рдХреБрдЫ рдРрд╕рд╛ рдЬреЛ рдПрдХреНрд╕ / рд╡рд╛рдИ рдХреЗ рдХреБрдЫ рдлрд╛рдпрджреЗ рдФрд░ рдиреБрдХрд╕рд╛рди рджрд┐рдЦрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдЬреНрдпрд╛рджрд╛ рд╕рдордп рдирд╣реАрдВ рд▓рдЧреЗрдЧрд╛ред
рдореЗрд░реЗ рд╕рд╛рдерд┐рдпреЛрдВ рдиреЗ рдЕрдХреНрд╕рд░ рдПрдХ рд╕рдорд╛рди рдкреНрд░рд╢реНрди рдкреВрдЫрд╛ред рдирддреАрдЬрддрди, рдПрдХ рд╕рд░рд▓ рд╡рд┐рдЪрд╛рд░ рдкреИрджрд╛ рд╣реБрдЖ - рдПрдХ рдЖрд░рдПрд╕рдПрд╕ рд░реАрдбрд░ рд▓рд┐рдЦреЗрдВред рдпрд╣рд╛рдВ рдЖрдк рдиреЗрдЯрд╡рд░реНрдХ, рдФрд░ XML рдкрд╛рд░реНрд╕рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЛ рджреЗрдЦреЗрдВред рд╣рд╛рдБ рдЖрдк рдХрднреА рдирд╣реАрдВ рдЬрд╛рдирддреЗ
рддреЛ, рдпрд╣рд╛рдВ рдмреИрдХрдПрдВрдб рдкрд░
рдкреНрд▓реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ 2.2 + рд╕реНрдХрд╛рд▓рд╛ + рдореЛрдВрдЧреЛрдмреАрдбреА рд╕реНрдЯреИрдХ рдореЗрдВ рдПрдХ рд░реЛрдорд╛рдВрдЪрдХ рдпрд╛рддреНрд░рд╛ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ рдФрд░
рдлреНрд░рдВрдЯ рдкрд░
рдПрдВрдЧреБрд▓рд░рдЬреЗрдПрд╕ + рдХреЙрдлреАрд╕реНрдХреНрд░рд┐рдкреНрдЯ ред
рдЯреАрдПрд▓, рдбреЙрдкреВрд░реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЛ рдкреНрд░рд▓реЗрдЦрди рдХреЗ рд╕рд╛рде рд╕реНрдХрд╛рд▓рд╛ рдкрд░ ~ 250-300 рд▓рд╛рдЗрдиреЛрдВ рдФрд░ рд╕реАрдПрд╕ рдкрд░ 150 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рдерд╛ред рдЦреИрд░, рдХреБрдЫ рдПрдЪ.рдЯреА.рдПрдо.рдПрд▓.
Bitbucket рдкрд░ рдЙрдкрд▓рдмреНрдз рдХреЛрдб
рдФрд░ рдкрд╣рд▓рд╛ рдкрдбрд╝рд╛рд╡ рд╕рд╡рд╛рд▓ рд╣реЛрдЧрд╛ - рд╕реНрдХреИрд▓рд╛, рдЬрд╛рд╡рд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ? рдФрд░ рдХреНрдпреЛрдВ рдЦреЗрд▓рддреЗ рд╣реИрдВ, рдФрд░ рдПрдХ рд╣реА рд▓рд┐рдлреНрдЯ рдирд╣реАрдВ?
рдЙрддреНрддрд░ рдмрд╣реБрдд рд╣реА рд╕рд░рд▓ рдФрд░ рд╡реНрдпрдХреНрддрд┐рдкрд░рдХ рд╣реИрдВред
рд╕реНрдХрд╛рд▓рд╛ рдХреЛрдб рдХреЗ рд▓рд┐рдП рдЙрдЪреНрдЪ рд╕реНрддрд░ рдХреА рдЕрдореВрд░реНрддрддрд╛ рдФрд░ рдХрдо рдХреЛрдб рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЬрдм рдореИрдВрдиреЗ рд╕рднреА рдЕрд╡рд╕рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ 200 рддрд░реАрдХреЛрдВ рдХреЗ рд╕рд╛рде рдорд╛рдирдХ
рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦрд╛ ... рдЧрдВрднреАрд░рддрд╛ рд╕реЗ, рдЗрд╕реЗ рд╕реНрд╡рдпрдВ рдЖрдЬрд╝рдорд╛рдПрдВред
рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреА рдкрд╕рдВрдж рдХреЗ рд▓рд┐рдП - рд▓рд┐рдлреНрдЯ рдкрд░ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдиреЗ рдореБрдЭреЗ
~ 150 рдПрдордПрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдерд╛рдиреАрдпрд╣реЛрд╕реНрдЯ рдкрд░ рдПрдХ рдкреГрд╖реНрда рджрд┐рдпрд╛, рдФрд░ рдпрд╣ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рдПрдХ рд╣реА рдорд╢реАрди рдФрд░ рдПрдХ рд╣реА JVM Play рдкрд░, рдпрд╣ ~ 5-10 рдПрдордПрд╕ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛ред рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛, рд╢рд╛рдпрдж рд╕рд┐рддрд╛рд░реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣реИрдВред
рдФрд░ рдкреНрд▓реЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкреНрдпрд╛рд░рд╛ рд╣реИред
рдореБрдЭреЗ рдкреНрд▓реЗ рдХреЗ рд╕рд╛рде рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдФрд░ рдЖрд░рдВрдн рдХрд░рдиреЗ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдпрд╛рдж рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рджрд╕реНрддрд╛рд╡реЗрдЬ рдореЗрдВ рд╕рдм рдХреБрдЫ
рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЪрдмрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдЕрдкрдиреЗ
рдкрд╕рдВрджреАрджрд╛ рдЖрдИрдбреАрдИ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╣реИ), рдФрд░ рд╣рдо рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗред
рдЕрдиреБрд░реЛрдз рдкрде
рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХрд╛ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдЕрдиреБрд░реЛрдз рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рд╣реИред
рдЖрдЬ рдлреНрд░реЗрдорд╡рд░реНрдХ рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд░реЛрдз рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдмреНрд▓реИрдХ рдмреЙрдХреНрд╕ рдХреЛ рдЫреЛрдбрд╝рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЬрдм рд╕реЗ рдЗрд╕реЗ рдиреЗрдЯреНрдЯреА рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реЛрдЧрд╛ рдЧрд╣рд░реА рдЦреБрджрд╛рдИред рд╢рд╛рдпрдж рдЪреАрди рдХреЛред
рдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдирджреА рдПрдХ рдмреНрд░реБрдХ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП Play рдореЗрдВ рдХреЛрдИ рднреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд░реВрдЯрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдХрд╛рдлреА рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд░реНрдгрд┐рдд рд╣реИ
conf / рдорд╛рд░реНрдЧреЛрдВ # рд░реВрдЯ
# рдпрд╣ рдлрд╛рдЗрд▓ рд╕рднреА рдЖрд╡реЗрджрди рдорд╛рд░реНрдЧреЛрдВ (рдкрд╣рд▓реЗ рдЙрдЪреНрдЪ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╡рд╛рд▓реЗ рдорд╛рд░реНрдЧреЛрдВ) рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреА рд╣реИред
# ~~~~
# рдЬрд╛рдУ
GET / рд╕рдорд╛рдЪрд╛рд░ рдирд┐рдпрдВрддреНрд░рдХреЛрдВред NewsController.news (рдЯреИрдЧ: рд╕реНрдЯреНрд░рд┐рдВрдЧ? = "", рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд░реЗрдВ: Int? = (System.currentTimeMillis () / 1000) .toInt)ред
# рдкрд╛рд░реНрд╕ рдЦрдмрд░
GET / рдкрд╛рд░реНрд╕ рдХрдВрдЯреНрд░реЛрд▓рд░ред NewsController.parseRSS
# рдЬрд╛рдУ
GET / рдЯреИрдЧ рдХрдВрдЯреНрд░реЛрд▓рд░ .agsController.tags
# рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдлрд╝реЛрд▓реНрдбрд░ рд╕реЗ / рд╕рдВрдкрддреНрддрд┐ URL рдкрде рдкрд░ рд╕реНрдереИрддрд┐рдХ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдореИрдк рдХрд░реЗрдВ
GET / рдЖрд╕реНрддрд┐рдпреЛрдВ / * рдлрд╝рд╛рдЗрд▓ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ.рдПрд╕реЗрдЯреНрд╕ (рдкрде = "/ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ", рдлрд╝рд╛рдЗрд▓)
# рд╣реЛрдо рдкреЗрдЬ
рдкреНрд░рд╛рдкреНрдд / рдирд┐рдпрдВрддреНрд░рдХреЛрдВред рдЖрд╡реЗрджрдиред рд╕реВрдЪрдХрд╛рдВрдХ
рдорд╛рд░реНрдЬрд┐рди рдореЗрдВ рдорд╛рд░реНрдЬрд┐рди:
рдореИрдВ рдЕрд▓рдЧ рд╕реЗ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкрджреНрдзрддрд┐ рдХреЗ рд▓рд┐рдП рджрд┐рдП рдЧрдП рддрд░реНрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдмрд╣реБрдд рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд░реНрддрдорд╛рди рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ред
рд╡реИрд╕реЗ, рдкреНрд▓реЗ рдореЗрдВ рд░рд╛рдЙрдЯрд┐рдВрдЧ рдХрд╛рдлреА рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╣реИ, рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╕рдордп regexp рддрдХред
рдЯрд┐рдХрдЯ рдкреЗрд╢ рдХрд░реЗрдВ!
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╢реАрд░реНрд╖рдХ рд╕реЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ - рдХрд╣рд╛рдиреА рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рд╕рд╛рде рдЬрд╛рд░реА рд╣реИред рдкреНрд▓реЗ рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рдпрдВрддреНрд░рдХ
controllers
рдкреИрдХреЗрдЬ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреЗ рд╣реИрдВ,
Controller
рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╡реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд┐рдирдХреЗ рддрд░реАрдХреЗ рд░реВрдЯрд┐рдВрдЧ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддреЗ рд╣реИрдВред
рдЪреВрдВрдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди AJAX рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рд░реНрд╡рд░ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдореБрдЦреНрдп рдкреГрд╖реНрда рдХреЛ рд░реЗрдВрдбрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдВрддреНрд░рдХ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рддреБрдЪреНрдЫ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ HTML / CS / JS рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдЯрд╛рдЗрдкреНрдб рдФрд░ 20 рд▓рд╛рдЗрдиреЗрдВ рдирд╣реАрдВ package controllers import play.api.mvc._ object Application extends Controller { def index = Action { Ok(views.html.index()) } }
Ok
play.api.mvc.SimpleResult
рдЙрджрд╛рд╣рд░рдг рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкреЗрдЬ рдХреЗ рд╣реЗрдбрд░ рдФрд░ рдмреЙрдбреА рд╣реЛрддреЗ рд╣реИрдВред рд╕рд░реНрд╡рд░ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдмрд░рд╛рдмрд░ рд╣реЛрдЧреА, рдХреНрдпреЛрдВрдХрд┐ рд╕рдмрд╕реЗ рдЪреМрдХрд╕ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдЧрдпрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, 200
OK
ред
рдордЧрд░
рдпрджрд┐ рдкреВрд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдкреВрд░реНрдг рдирд┐рдпрдВрддреНрд░рдХ 20 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдлрд┐рдЯ рдмреИрдарддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдмрд╣реБрдд рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЖрдк рд░реВрдмрд▓ рдореЗрдВ рд▓рд┐рдЦ рд░рд╣реЗ рд╣реИрдВред
рддреЛ, AJAX рдЧреНрд░рд╛рд╣рдХ рдХреЛ рд╕рдорд╛рдЪрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз рджреЗрдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдХреНрдпрд╛ рд╣реИ? рд░рд╛рдЗрдЯ, JSONред
NewsController
рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ
NewsController
рдСрдмреНрдЬреЗрдХреНрдЯ рдиреНрдпреВрдЬрд╝рдХрдВрдЯреНрд░реЛрд▓рд░ package controllers import play.api.mvc._ import scala.concurrent._ import models.News import play.api.libs.concurrent.Execution.Implicits.defaultContext import models.parsers.Parser import com.mongodb.casbah.Imports._ object NewsController extends Controller { def news(tag: String, pubDate: Int) = Action.async { val futureNews = Future { try { News asJson News.allNews(tag, pubDate) } catch { case e: MongoException => throw e } } futureNews.map { news => Ok(news).as("application/json") }.recover { case e: MongoException => InternalServerError("{error: 'DB Error: " + e.getMessage + "'}").as("application/json") } } def parseRSS = Action.async { val futureParse = scala.concurrent.Future { try { Parser.downloadItems(News.addNews(_)) News asJson News.allNews() } catch { case e: Exception => throw e } } futureParse.map(newsJson => Ok(newsJson).as("application/json")).recover { case e: MongoException => InternalServerError("{error: 'DB Error: " + e.getMessage + "'}").as("application/json") case e: Exception => InternalServerError("{error: 'Parse Error: " + e.getMessage + "'}").as("application/json") } } }
Future
ред
Async
ред рдпрд╣рд╛рдВ рдкрд╣рд▓реА рдмрд╛рд░ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд▓реЗ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд╣реИ рдФрд░, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдЖрдкрдХреЛ рдзрд╛рд░рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдЬрдм рд╣рдореЗрдВ
рддрддреНрдХрд╛рд▓ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ
рд▓рд┐рдП we
рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА
рд╣реИ , рддреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝реЗрдВ рдпрд╛ рдПрдХ рдФрд░ рдзреАрдореА рдЧрддрд┐ рд╕реЗ I / O рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░реЗрдВ,
Future
рдмрдЪрд╛рд╡ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдореБрдЦреНрдп рдзрд╛рд░рд╛ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд┐рдП рдмрд┐рдирд╛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
Future
рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╕рдВрджрд░реНрдн рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдереНрд░реЗрдбреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЪрд┐рдВрддрд╛ рдирд╣реАрдВ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред
рдЪреВрдВрдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдЕрдм
Future[SimpleResult]
рдирд╣реАрдВ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди
Future[SimpleResult]
,
ActionBuilder
рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛
async
рд╡рд┐рдзрд┐ рдХрд╛
ActionBuilder
(рдЬреЛ
Action
рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ)
рдкрд░рд┐рджреГрд╢реНрдп
рдЖрдЗрдП рдЗрд╕ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рджреБрдГрд╕реНрд╡рдкреНрди рдХреЗ рд╕рд╛рде рд░реБрдХреЗрдВ рдФрд░ рдЙрди рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЛ рдЪрд╛рд▓реВ рдХрд░реЗрдВ рдЬреЛ рд╣рдорд╛рд░реА рдЖрдВрдЦ рдХреЗ рд▓рд┐рдП рд╕реБрдВрджрд░ рд╣реИрдВред Play рдирд┐рдпрдорд┐рдд HTML рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рд╕реНрдХрд╛рд▓рд╛ рдХреЛрдб рдЖрд╡реЗрд╖рдг рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рдиреНрдп HTMLред рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдирд┐рдпрдорд┐рдд рдлрд╝рдВрдХреНрд╢рди рд╣реЛрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдЖрдк рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЕрдиреНрдп рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХрдиреЗрдХреНрдЯ (рдХреЙрд▓) рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡реИрд╕реЗ, рдХрдИ HTML рдореЗрдВ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рдзреАрдореА рд╕рдВрдХрд▓рди рд╕рдордп рдХреЗ рдХрд╛рд░рдг рдХреЛрдб рдореЗрдВ рдирдП рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЛ рдирд╛рдкрд╕рдВрдж рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдареАрдХ рд╣реВрдВред
index.scala.html <!DOCTYPE html> <html> <head> <title> playRSS </title> <link rel="shortcut icon" href='@routes.Assets.at("images/favicon.png")' type="image/png"> <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"/> <link rel="stylesheet" href='@routes.Assets.at("stylesheets/main.css")'> @helper.requireJs(core = routes.Assets.at("javascripts/require.js").url, module = routes.Assets.at("javascripts/main").url) </head> <body> <div class="container" id="container" ng-controller="MainCtrl"> <a href="/"><h1>playRSS</h1></a> @control() <div class="row"> <div class="col-lg-12"> @news() </div> </div> </div> </body> </html>
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╕реНрд░реЛрдд рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ - рдереЛрдбрд╝рд╛ рдЬрд╛рджреВред
@helper
рдХрдиреЗрдХреНрдЯ
@helper
рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдлреНрд░реЗрдорд╡рд░реНрдХ рджреНрд╡рд╛рд░рд╛ рдЖрдкреВрд░реНрддрд┐ рдХреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдореЗрди.рдЬреЗрдПрд╕ рдХреЗ рд▓рд┐рдП рдкрде рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдлреНрд░рдВрдЯреЗрдВрдб рдХреЛ рдЖрд░рдВрднреАрдХреГрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
@news()
рдФрд░
@control()
рдХреНрд░рдорд╢рдГ news.scala.html рдФрд░ control.scala.html рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИрдВред рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╡рд░реНрддрдорд╛рди рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдВрджрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдорд┐рд▓реЛред
рдФрд░ рднреА
рдЫреЛрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдЧрд░ / рдФрд░, рдЖрджрд┐ред рд╡рд┐рд╕реНрддреГрдд рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣реИ
рдкрд░реНрд╡рдд рдХрд╕рд╛рдм
рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдЬрд╛рд░реА рд░рдЦреЗрдВред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдорд╛рдирдЧреЛ рдХреЛ рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛ред
рдЪреВрдВрдХрд┐ рдореИрдВ рдЯреЗрдмрд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЖрд▓рд╕реА рд╣реВрдВред :)Casbah рдПрдХ рд░реЛрд▓рд┐рдВрдЧ рдкрд┐рди рдореЗрдВ MongoDB рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдбреНрд░рд╛рдЗрд╡рд░ рд╣реИ ред рдЗрд╕рдХрд╛ рд▓рд╛рдн рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд╕рд╛рджрдЧреА рдФрд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реИред рдФрд░ рдореБрдЦреНрдп рджреЛрд╖ рдХреЛ рдЕрдВрдд рдореЗрдВ рдорд╛рдирд╛ рдЬрд╛рдПрдЧрд╛ред
рдЪрд╛рд▓рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ:
libraryDependencies
рдЕрдВрджрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреА libraryDependencies
рд▓рд┐рдП рд▓рд╛рдЗрди рдЬреЛрдбрд╝реЗрдВ:
"org.mongodb" %% "casbah" % "2.6.3"
- рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
import com.mongodb.casbah.Imports._
- рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рд╣реА рдЕрдкрд╕реНрдлреАрддрд┐ рд╣реЛрдЧреА
- ???
- рд▓рд╛рдн
рдФрд░ рдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ред рдЪреВрдБрдХрд┐ рдкрд╛рдардХ рдХреЛ рд╕рд░рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬреЛ рдХрд┐ MongoDB рд╕реЗ рдЬрд░реВрд░рддрдордВрдж рд╕рдВрдЧреНрд░рд╣ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред DAO рдпрд╛ DI рдХреЛ рдмрд╛рдбрд╝ рджреЗрдиреЗ рдХрд╛ рд╕рд╣реА рд╢рдмреНрдж рдмрд╕ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╣реИред
рдСрдмреНрдЬреЗрдХреНрдЯ рдбреЗрдЯрд╛рдмреЗрд╕ package models import com.mongodb.casbah.Imports._ import play.api.Play object Database { private val db = MongoClient( Play.current.configuration.getString("mongo.host").get, Play.current.configuration.getInt("mongo.port").get). getDB(Play.current.configuration.getString("mongo.db").get) def collection(collectionName:String) = db(collectionName) def clearCollection(collectionName:String) = db(collectionName).remove(MongoDBObject()) }
рдорд╛рд░реНрдЬрд┐рди рдореЗрдВ рдорд╛рд░реНрдЬрд┐рди:
рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ, рд╡рд╕реНрддреБрдПрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд┐рдВрдЧрд▓рдЯрди рд╣реИрдВред рдпрджрд┐ рдЖрдк рдЙрдмрд╛рдК рдореЛрдб рдХреЛ рд╕рдХреНрд╖рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдерд┐рд░ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдирд╛рдо рд╡рд░реНрдЧ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рддрд╛рддреНрдХрд╛рд▓рд┐рдХ (рдЬрд╛рд╡рд╛ / рдЬреЗрд╡реАрдПрдо рджреГрд╢реНрдп рдореЗрдВ)ред рддреЛ рд╣рдорд╛рд░рд╛ рдХрдиреЗрдХреНрд╢рди рддрдм рдмрдврд╝реЗрдЧрд╛ рдЬрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдкреВрд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЪрдХреНрд░ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реЛрдЧрд╛ред
рдпрд╣ рд╕реНрдХрд╛рд▓рд╛ рдФрд░ рдХреИрд╕рдмрд╛рд╣ рдХреЗ рдЖрдзрд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ:
рд╡рд╕реНрддреБ рд╕рдорд╛рдЪрд╛рд░ case class News(val id: String = "0", val title: String, val link: String, val content: String, val tags: Seq[String], val pubDate: Long) /** * News object allows to operate with news in database. Companion object for News class */ object News { .... def addNews(news: News) = { val toInsert = MongoDBObject("title" -> news.title, "content" -> news.content, "link" -> news.link, "tags" -> news.tags, "pubDate" -> news.pubDate) try { col.insert(toInsert) } catch { case e: Exception => } } .... def getNews(filter: MongoDBObject, sort: MongoDBObject = MongoDBObject("pubDate" -> -1), limit: Int = newsLimit): Array[News] = { try { col.find(filter). sort(sort). limit(limit). map((o: DBObject) => { new News( id = o.as[ObjectId]("_id").toString, title = o.as[String]("title"), link = o.as[String]("link"), content = o.as[String]("content"), tags = o.as[MongoDBList]("tags").map(_.toString), pubDate = o.as[Long]("pubDate")) }).toArray } catch { case e: MongoException => throw e } } }
MongoDB, рдПрдкреАрдЖрдИ рдФрд░ рдХреЗрд╕ рдХреНрд▓рд╛рд╕ рдиреНрдпреВрдЬрд╝ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреА рддреБрдЪреНрдЫ рдлрд┐рд▓рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдЪрд┐рддред рдЕрдм рддрдХ, рд╕рдм рдХреБрдЫ рдкреНрд░рд╛рдердорд┐рдХ рд╣реИред рдмрд╣реБрдд рдЕрдзрд┐рдХред
рдХреБрдЫ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдЪрд╛рд╣рд┐рдПред
рдПрдХрддреНрд░реАрдХрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕реЗ?
рдЯреИрдЧ рдирд┐рдХрд╛рд▓ рд░рд╣реЗ рд╣реИрдВ case class Tags(name: String, total: Int) /** * Tags object allows to operate with tags in DB */ object Tags { private val col: MongoCollection = Database.collection("news") def allTags: Array[Tags] = { val group = MongoDBObject("$group" -> MongoDBObject( "_id" -> "$tags", "total" -> MongoDBObject("$sum" -> 1) )) val sort = MongoDBObject("$sort" -> MongoDBObject("total"-> -1)) try { col.aggregate(group,sort).results.map((o: DBObject) => { val name = o.as[MongoDBList]("_id").toSeq.mkString(", ") val total = o.as[Int]("total") Tags(name, total) }).toArray } catch { case e: MongoException => throw e } } }
.aggregate
рдЖрдкрдХреЛ рдмрд┐рдирд╛ рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдЪрдорддреНрдХрд╛рд░ рдХрд░рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рджреЗрддрд╛ рд╣реИред рдФрд░ рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдХрд╛рдо рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрдВрд╕реЛрд▓ рд╕реЗ рд╣реА рд╣реИред рдПрдХ рддрд░рд╣ рдХрд╛ рдкрд╛рдЗрдкрд▓рд╛рдЗрди-рд░рд╛рд╕реНрддрд╛, рдХреЗрд╡рд▓ рдХреЙрдорд╛ рджреНрд╡рд╛рд░рд╛ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдЯреИрдЧ рджреНрд╡рд╛рд░рд╛ рд╕рдореВрд╣реАрдХреГрдд, рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░ рд╕рдорд╛рди рдФрд░ рд╕рдВрдкреВрд░реНрдг рдЪреАрдЬрд╝ рдХреЛ рдХреНрд░рдордмрджреНрдз рдХрд░рддрд╛ рд╣реИред рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛ред
рд╡реИрд╕реЗ,
рдХреЗрд╕рдмрд╛рд╣ рдПрдХ рдЧрдврд╝ рд╣реИрдЖрдк JSON-XMLed рд╣реИрдВ
рдЖрдкрдХреЛ рдХрднреА рд╣рд╛рд░ рдирд╣реАрдВ рдорд╛рдирдиреА рдЪрд╛рд╣рд┐рдП
рдЖрдкрдХреЛ рдХрднреА рдирд┐рд░рд╛рд╢ рдирд╣реАрдВ рд╣реЛрдиреЗ рджреЗрдВрдЧреЗ
рдХреНрдпреЛрдВрдХрд┐ рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХреА рдЧрдИ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ XML / JSON рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдПрдХ рдзреЛрдЦрд╛ рдЬреИрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИред рд╕рдВрджреЗрд╣ рд╕реЗ рд╕рдВрдХреНрд╖рд┐рдкреНрддред
рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ XML рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдореЗрд░реА рдЖрдВрдЦреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЦреБрд╢реА рд╣реИ (рдЬрд╛рд╡рд╛ рдореЗрдВ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдХрд╛рд░рдЦрд╛рдиреЛрдВ рдХреЗ рдмрд╛рдж)ред
XML рдкрд╛рд░реНрд╕рд░ package models.parsers import scala.xml._ import models.News import java.util.Locale import java.text.{SimpleDateFormat, ParseException} import java.text._ import play.api.Play import collection.JavaConversions._ object Parser { val urls = try { Play.current.configuration.getStringList("rss.urls").map(_.toList).getOrElse(List()) } catch { case e: Throwable => List() } def downloadItems(cb: (News) => Unit) = { urls.foreach { (url: String) => try { parseItem(XML.load(url)).foreach(cb(_)) } catch { case e: Exception => throw e } } } def parseDateTime(s: String): Long = { try { new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH).parse(s).getTime / 1000 } catch { case e: ParseException => 0 } } def parseItem(xml: Elem): List[News] = (xml \\ "item").map(buildNews(_)).toList def buildNews(node: Node) = new News( title = (node \\ "title").text, link = (node \\ "link").text, content = (node \\ "description").text, pubDate = parseDateTime((node \\ "pubDate").text), tags = Seq((node \\ "category").text)) }
рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдлреЙрд░реНрдо \ рдпрд╛ \\ рдХреЗ рдирд╛рдо рд╡рд╛рд▓реА рд╡рд┐рдзрд┐рдпрд╛рдВ рдПрдХ рд╕реНрдЯреВрдкрд░ рдореЗрдВ рд╕рдВрдЪрд╛рд▓рд┐рдд рд╣реЛрддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдХреБрдЫ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ рдЬрдм рдЖрдк рдЬрд╛рд╡рд╛ рд╕реЗ BigInteger рдХреЛ рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВред
JSON рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рджреЗрд╢реА JSON рдЕрдм рддрдХ рдХреЛрдИ рднреА рд╡реНрдпрдХреНрддрд┐рдкрд░рдХ рдирд╣реАрдВ рд╣реИред рдзреАрдорд╛ рдФрд░ рдбрд░рд╛рд╡рдирд╛ред
рдореБрд╢реНрдХрд┐рд▓ рд╕рдордп рдореЗрдВ, Play and its Writes / Reads from
play.api.libs.json
рдкреИрдХреЗрдЬ
play.api.libs.json
ред рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЛ PHP 5.4 рд╕реЗ
JsonSerializable
рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрддрд╛ рд╣реИ? рддреЛ рдкреНрд▓реЗ рдореЗрдВ рдЕрднреА рднреА рдЖрд╕рд╛рди рд╣реИ!
JSON рд▓рд┐рдЦрддреЗ рд╣реИрдВ case class News(val id: String = "0", val title: String, val link: String, val content: String, val tags: Seq[String], val pubDate: Long) /** * News object allows to operate with news in database. Companion object for News class */ object News { implicit def newsWrites = Json.writes[News] def asJson(src: Array[News]) = { Json.stringify(Json.toJson(src)) } }
рдПрдХ-рд▓рд╛рдЗрди рдкрджреНрдзрддрд┐
someObjectWrites
рд╕рд░рд▓ рдХреНрд░рдорд╛рдВрдХрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╕рднреА рдореБрджреНрджреЛрдВ рдХреЛ рд╣рдЯрд╛ рджреЗрддреА рд╣реИред рд╕реНрдХрд╛рд▓рд╛ рдореЗрдВ рдирд┐рд╣рд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЙрдкрдХрд░рдг рд╣реИред
рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рд╣реА рд╕рдВрдЧреАрди рдорд╛рдорд▓рд╛ рд╣реИред рдЬрдм рдЖрдк рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рдпрд╛ рдЬрдЯрд┐рд▓ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ
рдлрдВрдХреНрд╢рдирд▓рд┐рдЬреНрдо рдФрд░ рдХреЙрдореНрдмрд┐рдиреЗрдЯрд░ рдмрдЪрд╛рд╡ рдореЗрдВ рдЖрддреЗ рд╣реИрдВред
рддрд╛рд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдВрдЯреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ
рдЬрдмрдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдКрдм рд░рд╣рд╛ рд╣реИ рдФрд░ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреНрд╡рд╛рд░рд╛ рд╕рд░реНрд╡рд░ рдХреЛ рднреЗрдЬреЗ рдЧрдП рдЕрдиреБрд░реЛрдз рдХреЗ рдЬрд╡рд╛рдм рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ ... рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред рдПрдХ рдФрд░ рджреГрд╢реНрдпред
рдЬреИрд╕рд╛ рдХрд┐ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, CoffeeScript рдФрд░ AngularJS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЗрд╕ рдмрдВрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рдкреАрда рдХреЗ рдареАрдХ рдиреАрдЪреЗ рджрд░реНрдж рдХреА рд╕рдВрдЦреНрдпрд╛ 78.5% рдХрдо рд╣реЛ рдЧрдИред рдХреЛрдб рдХреА рд░рд╛рд╢рд┐ рдХреА рддрд░рд╣ред
рдпрд╣ рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдкрд╛рдардХ рдореЗрдВ рдЗрди рд╕реНрдЯрд╛рдЗрд▓рд┐рд╢, рдлреИрд╢рдиреЗрдмрд▓ рдФрд░ рдпреБрд╡рд╛ рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдФрд░ рдЗрд╕рд▓рд┐рдП рднреА рдХрд┐ рдореЗрд░реА рдкрд╕рдВрдж рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рдмреЛрд░реНрдб рдкрд░ рдХреЙрдлреАрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рд▓реЗрд╕ рдХрдВрдкрд╛рдЗрд▓рд░ рд╣реИрдВред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЕрдиреБрднрд╡реА рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреБрдЫ рдирдпрд╛ рдФрд░ рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╕реАрдЦреЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдХреЗрд╡рд▓ рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдЯреНрд░рд┐рдХреНрд╕ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ред
рдЕрдХреНрд╕рд░ рдХреЛрдгреАрдп рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддрд╛ рд╣реИред рдФрд░ рдХреЗрд╡рд▓ рдкрд░рд┐рд╖реНрдХрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рдЬреНрдЬрди рд╣реА рдирд╣реАрдВ рдЬрд╛рддреЗ (рдЬреИрд╕реЗ рдХрд┐ рд▓реЛрдХрд▓рд╕реНрдЯреЛрд░реЗрдЬ рдХреЛ рд▓рд┐рдЦрдирд╛) ...
рдФрд░ рдХрд╛рд╕реНрдХреЗрдЯ рдмрд╕ рдЦреБрд▓ рдЬрд╛рддрд╛ рд╣реИред
рд╕реЗрд╡рд╛ рдХреЛ рдмрдирд╛рдирд╛ рдФрд░ рдЖрд╡рд╢реНрдпрдХ рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдореЗрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИрдкреНрд░рдЪрд╛рд░ define ["angular","ngInfinite"],(angular,infiniteScroll) -> newsModule = angular.module("News", ['infinite-scroll']) newsModule.factory 'broadcastService', ["$rootScope", ($rootScope) -> broadcastService = message: {}, broadcast: (sub, msg)-> if typeof msg == "number" then msg = {} this.message[sub] = angular.copy msg $rootScope.$broadcast(sub) ] newsModule
рд╣рдо рднреЗрдЬрддреЗ рд╣реИрдВ define ["app/NewsModule"], (newsModule)-> newsModule.controller "PanelCtrl", ["$scope", "$http", "broadcastService", ($scope, $http, broadcastService)-> $scope.loadByTag = (tag) -> if tag.active tag.active = false broadcastService.broadcast("loadAll",0) else broadcastService.broadcast("loadByTag",tag.name) ]
рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ define ["app/NewsModule","url"], (newsModule,urlParser)-> newsModule.controller "NewsCtrl", ["$scope", "$http", "broadcastService", ($scope, $http, broadcastService)->
рдХреЛрдгреАрдп рдореЗрдВ
рд╕реЗрд╡рд╛рдПрдБ рд╕рд┐рдВрдЧрд▓рдЯрди рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдмрдирд╛рдП рдмрд┐рдирд╛ рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рдЖрдЧреЗ рдФрд░ рдкреАрдЫреЗ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред
рд╕рднреА рдЖрддреЗ рд╣реИрдВ
рдЖрдВрддреНрд░ рдФрд░ рдкреАрда рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреА рдЕрд░рд╛рдЬрдХ рдпрд╛рддреНрд░рд╛ рдХреЗ рдмрд╛рдж, рдпрд╣ рдпреЛрдЧреНтАНрдп рд╣реИред
рдлрд╛рдпрджреЗ рдФрд░ рдиреБрдХрд╕рд╛рди, рдШрд╛рддрдХ рдФрд░ рдмрд╣реБрдд рдЬреНрдпрд╛рджрд╛ рдирд╣реАрдВ, рд╣рд░ рдХрд┐рд╕реА рдХреЛ рдЕрдкрдиреЗ рд▓рд┐рдП рдЪреБрдирдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдо рдЕрднреА рднреА рдЙрд╕ рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдпрд╣ рдХрд╛рд░реНрдЧреЛ рдХреА рдЦреЗрддреА рдХреЗ рдмрдЬрд╛рдп, рд╕рд╣реА рдмреИрдарддрд╛ рд╣реИ?
рдореБрдЭреЗ рдкрд╕рдВрдж рдЖрдпрд╛:- рдЬрд╛рд╡рд╛ рд╕реЗ рдкрд╣рд▓реЗ Brevity Scalaред рд╕рд╛рдВрдЦреНрдпрд┐рдХреАрдп рд░реВрдк рд╕реЗ рдЯрд╛рдЗрдк рдХреА рдЧрдИ рднрд╛рд╖рд╛ рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рддрд░рд╣ рдереЛрдбрд╝рд╛ рдХреЛрдб рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рд╕рдВрдХрд▓рди рд╕рдордп рдореЗрдВ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдкрдХрдбрд╝реА рдЬрд╛рддреА рд╣реИрдВред рдкрд░реАрдХреНрд╖рдг, рдЖрджрд┐ рдФрд░ рдЧрддрд┐рд╢реАрд▓ рдЯрд╛рдЗрдкрд┐рдВрдЧ рднрд╛рд╖рд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╡реЗ рдЬреЛ рднреА рдХрд╣рддреЗ рд╣реИрдВ, рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ рд╣реАрди рд╣реИрдВред
- рд╕реНрд╡рдпрдВ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛, рдЬреЛ рдХрдИ рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрд░рдЪрдирд╛ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддреА рд╣реИред
рдкрд╕рдВрдж рдирд╣реАрдВ рдЖрдпрд╛:- рдлрд┐рд░ рднреА, рд╕рдВрд╢реЛрдзрд┐рдд рддрд╛рдЬрд╝рд╛ рд╡рд░реНрдХрдлрд╝реНрд▓реЛ рд╕рдВрд╢реЛрдзрд┐рдд рд╕реНрд░реЛрддреЛрдВ рдХреЗ рд▓рдЧрд╛рддрд╛рд░ рдкреБрдирд░реНрд╕рдВрдпреЛрдЬрди рдХреЗ рдХрд╛рд░рдг рддрдВрдЧ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдШрд╛рддрдХ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рд╡рд┐рдЪрд╛рд░ рдХреА рдЙрдбрд╝рд╛рди рдХреЛ рдзреАрдорд╛ рдХрд░ рджреЗрддрд╛ рд╣реИ
- рдЬреЗрд╡реАрдПрдо рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреА рд╣рд╡рд╛ рдХреА рд╕рдорд╕реНрдпрд╛рдПрдВ (\\ рдмрдирд╛рдо /) рд╡рд┐рди рд╕рд┐рд╕реНрдЯрдо рдХреЗ рддрд╣рдд рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдФрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддреА рд╣реИрдВред рдХреЗрд╡рд▓ рджреЗрд╡ рд╡рд┐рдзрд╛ рдореЗрдВред рдФрд░ рдпрд╣рд╛рдБ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрд╛ рдирд╣реАрдВ рдЧрдпрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╣рд╛рде рдореЗрдВ рдХрдИ рдирд┐рдХреНрд╕ рд╕рд░реНрд╡рд░ рд╣реИрдВ
- рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдХреЛрдИ рд▓реЙрдЧрд┐рдВрдЧ рдирд╣реАрдВред рд▓рдХрдбрд╝рд╣рд╛рд░реЗ рдореЗрдВ рдЬрдВрдЧрд▓реА рд╕реНрдореГрддрд┐ рд▓реАрдХ рдХреЗ рдХрд╛рд░рдг рдХрдерд┐рдд рд░реВрдк рд╕реЗред рдЦреИрд░, рдореИрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрд╕ рдкрд░ рдЙрдард╛ рд░рд╣рд╛ рд╣реВрдБред
рд╕рд╛рде рд╣реА, рд╡рд┐рдХрд╛рд╕ рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ рднрд╡рд┐рд╖реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдЕрд╡рд░реБрджреНрдз рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рд╕рд╛рд╡рдзрд╛рди рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдПрдХ рд╣реИ рд▓реЗрдХрд┐рдиред рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдореБрдЦреНрдп рдзрд╛рдЧрд╛ рдЕрд╡рд░реБрджреНрдз рдирд╣реАрдВ рд╣реЛрдЧрд╛, рджреВрд╕рд░реЗ рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реИ рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдкрд░реНрдпрд╛рдкреНрдд рдзрд╛рдЧреЗ рд╣реИрдВ рдФрд░ рдХрдИ рдкреНрд░рддрд┐рд╕реНрдкрд░реНрдзреА рдЕрдиреБрд░реЛрдз рдирд╣реАрдВ рд╣реЛрдВрдЧреЗред рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░? рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд▓реЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рд╕рдорд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХреГрддрд┐ рдбреНрд░рд╛рдЗрд╡рд░реЛрдВ рдореЗрдВ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Casbah рдХреЗ рдмрдЬрд╛рдп ReactiveMongoред рдпрд╛ рдХрдо рд╕реЗ рдХрдо рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдФрд░ рдереНрд░реЗрдб рдкреВрд▓ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдХрд╣рд╛рдиреА рд╣реИ ...
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред
рдкреБрдирд╢реНрдЪ
рдпрджрд┐ рдпрд╣
рд╕реНрдХреНрд░рд┐рдмрдмрд▓ рдереЛрдбрд╝рд╛ рд╕рд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛ - рддреЛ рдпрд╣рд╛рдВ
рдмрд┐рдЯрдмрдХреЗрдЯ рдкрд░ рднрдВрдбрд╛рд░ рд╣реИ ред