javaWeb快速开发框架之Play

        本篇希望在大家看过之后,能让大家对play的全貌有一个清晰的认识,如果感兴趣的话再去探究详细的操作步骤。无论是对于play的新手还是play的已经使用者,相信都会带来不同的收获,下面开始吧!

前置知识:一点Groovy、一些JPA

一、play简介

        play是国外的一家技术公司lightbend开发的一栈式web开发框架,同时支持java和scala两门语言。他通过高性能的底层技术,集成了Javaweb应用开发所需要的几乎所有的组件和API,并做了简单的封装,使得开发更加快速简洁,同时也提高了性能。正如他设计之初的目标一样——简化web开发工作,提高开发效率。

1、play的优点

1)开发效率高

自带热加载功能:

        因为基于Eclipse编译器实现了即时编译(JIT),省去了重启项目的时间。

大量封装和各种库:

        play在各个环节都做了封装和简化,并提供了多种功能开箱即用的类库,这一点下面会介绍。

强大的领域驱动模型层:

        play采用JPA做持久化框架,崇尚马丁。福乐提出的“充血模型”(就是主张实体类之间应该高内聚低耦合,将当前实体类相关的数据和行为全放在当前实体类中)。为了完成这一点,play提供了公共的实体类父类,继承该父类,即可拥有额外的属性和功能(比如实体类的CRUD操作)。

自带高效的模板引擎

        模板引擎的动态部分采用Groovy语法,不过很简单,就是基本的if-else、for循环、插值表达式、url表达式等基本的模板引擎功能。        

没有编译和打包的过程

        一般情况下,部署play项目时不需要手动编译和打包,直接copy源码文件夹,通过play的命令启动即可。play不讲究框架的分层处理,所以service层和DAO层显得不是很重要。

2)遵循服务端无状态的设计,便于水平扩展

3)设计思想值得借鉴

2、play的缺点

1)1版本没有较好的依赖控制工具,还是采用jar包放在类路径的方式,但是影响不大

2)数据层不够强大

3、play与spring的对比

相同点:

处理http请求的方式是一样的。

不同点:

1)play是一栈式web开发框架,可以说是五脏俱全;spring更多的是资源整合框架。

2)play不是基于servlet的,所以不具备servlet标准的servlet、filter、listener、session等api,但是有替代方案。

3)play不具备spring的IOC、AOP功能,使用别的类的方法需要new对象或者设计成static的

4)play一般不需要编译、打包等项目管理过程。

5)play通过提供的脚本命令来执行操作,例如创建项目、模块,运行,停止,测试,生成环境id等,具体可通过play help 查看所有命令及用法。而spring一般需要打包并放到web容器中运行,虽然都可以使用内嵌的容器。

4、play画像或参照物:

        SpringBoot+JPA+thymeleaf+UI框架+jquery这套组合,外加ActiveRecord模式、JRebel工具、很多功能类库、某个内置的高性能服务器、命令行解释器。

OK,相信看完以上简介后,你能对play有一个大体的认识。下面将展开来讲,看下play具体提供了哪些功能。

二、play的安装与项目初始化

 1、下载和安装

GitHub - playframework/play1: Play framework​​​​​​​z    这里有play在github上的源码。

你可以从该项目的tags中找play的历史版本,比如该文章用的play1.5.1版本 ​​​​​​​​​​​​​​Tags · playframework/play1 · GitHub

windows下开发,下载.zip包。之后解压到一个无空格非中文的路径下即可。

为了方便使用play的命令,最好将play的安装目录配置到windows下的path环境变量中,方便在任何地方使用play的命令。

然后shell中输入play,出现一下界面表示安装成功

 play框架也是用java写的,也需要依赖其他类库。这里重点关注两个文件%PLAY_HOME%/framework/play-1.5.1.jar%PLAY_HOME%/framework/lib文件夹,一个是play框架的核心源码,另一个是play所依赖的jar包。

2、初始化

在想要创建play项目的地方输入play的命令来创建和运行项目,如下:

// 创建并初始化一个play项目
play new appName
// 运行该项目
play run appName

就像创建Maven或springBoot项目一下,使用play new 可以快速生成标准化的play项目,具体生成的文件夹的作用,可以参考官方说明

3、IntelliJ Idea中开发play项目

可以将play项目交给idea来托管执行,就能使用idea的功能按钮来运行play项目了,但是需要一些配置,如下

1)先用如下命令生成一个.ipr 环境配置文件,就像.iml文件一样

play idealize appName

之后双击或用idea打开这个文件就能打开play项目了。

2)添加运行配置

  1. In IntelliJ IDEA, on the Run menu, select Edit Configurations.
  2. Right-click on Application under Defaults and select Add New Configuration.
  3. Under Main class, enter play.server.Server.
  4. Under VM parameters, enter -Dapplication.path=".".
  5. Under Working directory, enter the application path.
  6. Under Before launch, remove Make if exists.

ps:如果想只使用命令的方式启动,也可以不添加以上配置。

OK,介绍也介绍了,安装也安装了,启动也启动了,接下来就看一下如何使用play进行开发吧!

三、使用play快速开发

3.1 play的运行流程

        如果你熟悉SpringMVC开发的话,你会发现play的运行流程和SpringMVC是一样的,同样是M(模型)-V(视图)-C(控制)的开发模式,同样可以基于模板进行后端渲染视图,或是返回json数据让前端通过js脚本渲染视图。

 3.2 领域模型对象

        实体类继承Model类,即可拥有单表的crud功能,也可以用JPA或JPQL功能。

        play中约定,所有public的、非static的、非final的变量都是实体类的属性,通过对象.属性的方式编写。在编译后会play自动转换成对应的getter和setter。当然如果用户自定义了getter和setter,play在编译时就会使用用户自定义的了。

3.2.1 DB访问

a、继承Model或GenericModel类

        play提供了一组程序让用户对JPA实体的操作更加简便,只需要继承Model类或GenericModel类即可完成CURD操作,还可以使用简化查询(类似springData的自定义方法查询)、JPQL查询。

b、使用JPA的EntityManager

        直接通过实体类.em() 或 JPA.em()获取EntityManager,然后就可以使用原生JPA的方式进行操作了

c、原生JDBC操作

        play提供了一个DB工具类,能让用户使用原生JDBC的方式操作数据库。直接DB.getConnection() 获取JDBC连接,就能用JDBC的方式操作数据库了。

3.2.2 事务

        默认情况下,play对每一个action方法都开启了事务,意味着事务会自动提交和回滚。play提供了两个注解来改变默认的行为:

// 变成只读的事务
@Transactional(readOnly = true)  
// 关闭事务
@NoTransaction                   

// 强制执行事务回滚
JPA.setRollbackOnly();

特别的:play要求所有对对象的更改都要显示调用save()方法进行更新才行。

​​​​​​​

3.3 Controller 父类

面向http协议,定义了很多Controller层通用的功能方法和对象,所有controller都要继承它。

例如:

3.3.1 参数接收

a、自动解析并映射

        和SpringMVC一样,play会自动解析Http请求中的参数,并赋值给controller层方法的入参。

        默认会从以下地方解析http请求中的数据,query string、request body、url path(适用于rest风格的url)。

        play将尝试转换成action方法入参中声明类型,转化不了就使用默认值,所以action方法的入参可以是 基本数据类型及其包装类、对象(支持嵌套对象的解析)、map、List、Date、File(对于文件上传,play会先存到一个临时目录,并在请求结束时删除该文件)等

特殊的:JPA实体类作为入参,如果提供了实体类的id,play会先查询出来该实体类,再用http中的参数更新该实体类;如果没id就不查询了直接赋值,支持嵌套对象的查询和修改。

b、params 对象

        能直接获取http请求中的数据,作用和request.getParameterMap() 一样,但是做了封装,例如params.getBigDecimal("money")

3.3.2 参数验证

play提供了一个Validation类,用于对数据进行验证,并在内部封装了错误信息errors。

提供了三种验证方法:

1)类似断言 :使用Validation.xxx方法直接验证

2)校验注解:将注解直接标记在action方法的入参上即可。

3)类似JSR303的注解的验证方式:实体类的属性上加入校验注解,action方法的参数前标记@valid 注解即可像JSR303一样验证多个参数。

还能自定义错误信息

官网:validation - 1.5.x

 

3.3.3 临时数据存储

        play提供了session和flash域,用于在跨两个或多个http请求中共享数据,全都是采用Cookie机制来回传的数据(因为play想要让服务端无状态,使用cookie可以跨服务器共享数据),因此数据量非常有限。

》》session:并非servlet中的session,准确来说应该叫会话,数据保存在http的cookie中,而不是服务端。能跨多个http共享数据,需要使用play的配置 application.session.maxAge 配置才能实现数据的持久化。

》》flash域:也是用cookie保存的数据,仅在下一个http请求中共享数据。一般用来返回错误信息。

特别的:若想使用Java servlet中的session,可以用play中的Cache来存储数据,然后将唯一key放到会话或者flash中即可。​​​​​​​

 

3.3.4 http响应

Controller父类提供了多种renderxxx()方法,用于返回不同格式的数据,如

renderJson

renderXml

renderText

renderHtml

renderBinary(二进制流,文件下载)

render(渲染html模板,默认的视图解析器规则是views文件夹下面和当前action方法所在的包名-类名-方法名 同名的html文件)​​​​​​​

renderTemlate:当然可以指定要渲染的模板。

3.3.5 重定向redirect

        play中没有请求的转发,但是支持“曲折的”重定向。很简单只需要一个action方法中调用另一个action方法即可。但是play规定一个http请求只能调用一个action方法,所以当想要调用另一个action方法进行重定向时,play其实先返回一个302响应,然后要求浏览器再次发送要重定向的请求,并不是在服务端直接重定向的。

3.3.6 http请求拦截

        play提供了@Before(方法之前被调用)、@After(方法正确返回之后被调用)、@Catch(方法抛出异常后被调用)、@Finally(方法执行结束后调用,无论成功还是失败),将这几个注解标记在某个action方法上,就能对该action方法所在controller以及后代controller中所有的action方法生效。这几个注解可以完成AOP和全局异常处理器或拦截器的功能

@with注解:该注解标记在一个类上,可以让该类额外继承目标类,实现java多继承的特点,定义拦截器等时可以使用上这个注解。

参考: controllers - 1.5.x

3.4、模板语法

        play的模板引擎基于基本的Groovy语法,不过很简单,和JSP大同小异,所以可在模板中使用java代码。关于UI框架,play没做要求,想Bootstrap、layUI都可以,但是不知道像elementUI、antDesign这样的行不行,有没有老铁在评论区给解答一下?

        不得不承认,小项目采用前后端不分离的开发模式,确实比前后端分离采用JS渲染DOM的方式,在开发速度上确实快很多。虽然后来前后端分离后,前端的JS框架也使用了模板引擎,JS框架负责从后端API接收数据和渲染模板,但也只是加快了前端的开发速度,对于整个项目的开发速度还是不如前后端不分离时,后端渲染模板来的快。

参照官网: templates - 1.5.x

 

3.5 异步作业

        play提供了一个Job类,用来执行异步任务。继承Job类并重写他的doJob()、doJobWithResult()即可创建一个任务。

基于创建的任务,我们有三种方式来使用他:

1)引导任务(Bootstrap task)

只需要在任务类上添加 @OnApplicationStart (在应用启动时执行)或者 @OnApplicationStop(在应用关闭时执行) 即可

2)定时调度任务(Scheduled task)

在任务类上添加 @Every("间隔时间") 间隔时间的单位可以有如1h、10mn、30s

或者使用@on("cron表达式6位") 注解使用cron表达式来完成

3)手动触发异步任务

        通过某个任务对象的now方法(立即执行)、in方法(延迟执行)、afterRequest方法(http响应之后执行) 手动触发自定义的任务。

3.6 单元测试

play中测试只能在测试模式中进行,通过play test 启动测试模式

步骤:

1)编写自己的单元测试类继承UnitTest或FunctionalTest,

2)编写单元测试方法

3)通过ip:port/@tests访问测试界面,点击需要测试的方法即可

3.7 辅助工具

3.7.1 缓存

缓存是高性能应用必备的组件。play提供了两种使用缓存的方式,基于注解的缓存和基于编码的缓存。

基于注解的缓存

只需要将@CacheFor("5s")标记在action方法上,就能缓存方法返回的接口,这点和spring的缓存注解是一个道理。

基于编码的缓存

play提供了Cache类用于编码的缓存,并提供了常用的缓存操作如get、set、delete、incr、expire等

ps:Cache 一个缓存抽象类,聚合了一个缓存实现接口,并提供了多种缓存实现,方便用户切换

参考:cache - 1.5.x

3.7.2 集成了发送邮件的功能

参考:emails - 1.5.x

3.7.3 web安全问题

提供了如何避免常见的web安全问题:跨站脚本、跨站请求伪造、sql注入都是需要避免的问题。

参考:security - 1.5.x

3.7.4 代码热加载提高开发效率

        play利用Eclipse提供的编译器,对代码进行了即时编译,并给予HotSpot做了热加载,所以不需要重启项目。

3.7.5 多种开箱即用的类库或工具

         play有个强大的类库,提供了诸如OAuth2.0、异步http通信、安全、邮件、国际化等web开发的常用功能,在这里就不细说了,如果你对play感兴趣的话可以到他的官网去看看。 

传送门: libs - 1.5.x

3.8 生产部署

3.8.1 多环境配置

        通过play id 命令定义不同的环境前缀,然后将这些前缀配置的application.conf目录中,运行的时候指定要运行的环境即可,如下:

例如:
%dev.log.level=debug
%production.log.level=error

通过 play run --%production  ,即可以production环境运行

四、该总结啦

优点:

1、高度封装的web框架,开发速度快。

2、因为是用的JPA访问数据库,不同数据库迁移方便。

3、适合敏捷开发,做后台管理系统很合适。

缺点:

1、感觉dao层不够强大,复杂的查询和统计,就得使用本地sql了。

2、项目构建和依赖管理不太方便。play2好像更换成了sbt了。

适用:

个人感觉适合前后端不分离的小项目会更好一些,短平快追求!

最后说一句,动起手来实践一下,你会收获很大!

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值