使用Spring Roo构建项目
- 使用Spring Roo构建项目
- 结构概述 Architectural Overview
- 关键技术 Critical Technologies
- 实体层 Entity Layer
- 1 初始化项目
- 2 安装持久化工具
- 3 创建实体
- 4 创建字段
- 网络层 Web Layer
- 1 建立Web层
- 2 创建控制器
- 服务层 Services Layer
- 库层 Repository Layer
- Maven
- JSON Add-On
使用Spring Roo构建项目
1. 结构概述 Architectural Overview
Spring Roo
专注于Java
企业应用的开发。在当前的应用版本2.0.0.M1
中,构建的应用将以关系数据库为基础,采用JPA
标准对数据持久化,并大量使用了Spring
框架中的依赖注入和事务管理,以及JUnit
测试,利用Maven
进行项目的配置,以Spring MVC
为基础将JSP
作为视图。
使用Roo
创建的项目和传统项目相比,Roo
创建的项目去掉了一些不必要的的抽象层。大多数的Java
企业应用都包含DAO
层、domain
层和controller
层。而在一个使用Roo
构建的典型项目中,你将只会用到entity
层(这有点类似于domain
层,但似乎又结合了DAO
层和Services
层)和web
层。当然,如果你的应用的确需要,你可以添加一个services
层,但是,几乎是不会添加DAO
层的。
2. 关键技术 Critical Technologies
2.1. AscpectJ
2.2. Spring
3. 实体层 Entity Layer
大家在使用Roo
时,都应该遵循如下的几个步骤:
3.1. 初始化项目
3.2. 安装持久化工具
3.3. 创建实体和字段
3.1. 初始化项目
> mkdir demo
> cd demo
roo> project setup --topLevelPackage cn.edu.cqupt.demo
3.2. 安装持久化工具
roo> jpa setup --database MYSQL --provider HIBERNATE
roo> database properties set --key database.url --value jdbc:mysql://localhost:3306/cblog?useUnicode=true&characterEncoding=utf-8
roo> database properties set --key database.username --value root
roo> database properties set --key database.password --value root
打印信息(仅列出一部分信息)
Updated SPRING_CONFIG_ROOT\applicationContext.xml
Created SRC_MAIN_RESOURCES\META-INF\persistence.xml
Updated SPRING_CONFIG_ROOT\database.properties
路径常量:
SPRING_CONFIG_ROOT
-> src\main\resources\META-INF\spring
SRC_MAIN_RESOURCES
-> src\main\resources\META-INF
jpa setup
命令指定了使用MYSQL
数据库、HIBERNATE
映射工具。database properties
命令修改的是database.properties
文件中的信息。数据源的相关配置是在applicationContext.xml
文件中,使用的是dbcp
。HIBERNATE
的配置是在persistence.xml
文件中。
3.3. 创建实体
entity jpa --class ~.domain.Admin
打印信息(部分)
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin.java
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin_Roo_Configurable.aj
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin_Roo_Jpa_Entity.aj
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin_Roo_Jpa_ActiveRecord.aj
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin_Roo_ToString.aj
路径常量:
SRC_MAIN_JAVA\cn
-> src\main\java
从打印的信息中可以看出,有创建如下几个文件:
- Admin.java
基础类文件
- Admin_Roo_Configurable.aj
不知道干嘛用的
- Admin_Roo_Jpa_Entity.aj
包含实体的version
和id
属性,注意,version
和id
属性是和@RooJpaActiveRecord
有关,而不是@RooJavaBean
- Admin_Roo_Jpa_ActiveRecord.aj
主要是实体的CRUD
操作,对应实体中@RooJpaActiveRecord
注解
- Admin_Roo_ToString.aj
实体的toString()
方法,对应实体类中@RooToString
注解
The generated method takes care to avoid circular references that are commonly seen in bidirectional relationships involving collections
这个方法(toString)需要注意避免循环引用,尤其是在涉及集合的双向关系时。
3.4. 创建字段
roo> field string --fieldName username --class ~.domain.Admin --notNull --sizeMax 30 --unique
roo> field string --fieldName passwd --class ~.domain.Admin --notNull --sizeMax 60 --sizeMin 6
打印信息
Updated SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin.java
Updated SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin_Roo_Jpa_ActiveRecord.aj
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin_Roo_JavaBean.aj
创建文件Admin_Roo_JavaBean.aj
,包含实体的setter
和getter
,对应实体类中@RooJavaBean
注解。
创建的这些实体将会采用JPA
注解的标准一一映射到数据库中的表,而你无需关心具体使用了哪些注解。
The first time you use one of these Roo field commands, Roo will add required JavaBean Validation API libraries to your project (i.e. these libraries will not be in your project until you decide to first use JavaBean Validation).
尚未读到
JavaBean Validation
。
这些AscpectJ ITDs
中声明的方法将会添加到Admin.class
内。
所以,总结一下
注解名称 | 作用 |
---|---|
@RooJpaActiveRecord
|
实体的version 和id 属性、CRUD 操作
|
@RooToString
|
实体的toString() 方法
|
@RooJavaBean
|
实体的setter 和getter
|
Admin_Roo_Jpa_ActiveRecord.aj中方法概览:
方法名称 | 描述 |
---|---|
entityManager()
|
获取entityManager
|
countAdmins()
|
获取admin 的记录总数
|
findAllAdmins()
|
查询所有的admin 记录
|
findAllAdmins(String sortFieldName, String sortOrder)
|
查询admin 记录,sortFieldName 为排序属性,sortOrder 为升序或降序
|
findAdmin(Long id)
|
通过id 查找admin
|
findAdminEntries(int firstResult, int maxResults)
|
firstResult 指定查找的第一个记录,maxResult 指定查找的最大记录
|
findAdminEntries(int firstResult, int maxResults, String sortFieldName, String sortOrder)
|
同上,分页并排序 |
persist()
|
持久化某实体 |
remove()
|
移除某实体 |
flush()
|
将持久化的上下文内容同步到底层数据库 |
clear()
|
清除持久化上下文内容,是所有管理的实体都处于游离状态 |
merge()
|
合并给定的实体的状态到当前的持久化上下文 |
4. 网络层 Web Layer
Scaffolded web controllers always delegate directly to methods provided on an @RooJpaActiveRecord class.
网络层的控制器总是直接将操作委派给
@RooJpaActiveRecord
标注的类。接下来生成的AdminController
内部的方法都是直接调用Admin
中持久化的方法。If you write a web controller by hand (perhaps with the assistance of the web mvc controller command), it is recommended you also use the methods directly exposed on entities.
所以当你自己需要定义一个controller时,也建议直接使用实体中持久化的方法。
Most Roo applications will place their business logic between the entities and web controllers, with only occasional use of services layers.
大多数的
Roo
应用将他们的业务逻辑放在Entity
层和Controller
层之间,因此偶尔会使用到Service
层。
4.1. 建立Web
层
命令:
roo> web mvc setup
打印信息(部分):
Created ROOT\src\main\webapp\WEB-INF\spring\webmvc-config.xml
Created ROOT\src\main\webapp\WEB-INF\web.xml
Created ROOT\src\main\webapp\WEB-INF\i18n\messages.properties
这个命令将一个普通的Java
项目转变成了一个Web
项目,同时为项目添加了必要的依赖。
4.2. 创建控制器
命令:
roo> web mvc all --package ~.web
打印信息(部分):
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\web\AdminController.java
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\web\ApplicationConversionServiceFactoryBean.java
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\web\AdminController_Roo_Controller.aj
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\web\ApplicationConversionServiceFactoryBean_Roo_ConversionService.aj
这个命令会自动检测项目中的实体,为每个实体创建控制器。ApplicationConversionServiceFactoryBean
是定义的各种转换器。
AdminController_Roo_Controller.aj
中定义的请求映射:
方法名 | URL | 参数 | 参数说明 | 请求方式 | 返回的视图 |
---|---|---|---|---|---|
create
|
/admins
|
admin
|
待创建实体的属性
|
POST
|
参数错误:admins/create 创建成功:redirect:/admins/{id}
|
createForm
|
/admins?form
|
无
|
无
|
GET
|
admins/create
|
show
|
/admins/{id}
|
无
|
无
|
GET
|
admins/show
|
list
|
/admins
|
page size sortFieldName sortOrder
|
roo 自动生成分页参数 均非必需
|
GET
|
admins/list
|
update
|
/admins
|
admin
|
待修改实体的属性
|
PUT
|
参数错误:admin/update 修改成功:redirect:/admins/{id}
|
updateForm
|
admin/{id}?form
|
无
|
无
|
GET
|
admins/update
|
delete
|
/admins/{id}
|
page size
|
需删除的页数和页宽 均非必需
|
DELETE
|
redirect:/admins
|
5. 服务层 Services Layer
大多数Roo
构建的应用很少需要Services
层的,因为大多数的逻辑都可以放在web
层或实体的方法中。但像如下的几种情况可能会用到services
层:
- 业务逻辑跨越了多个实体
- 你需要调用web
请求之外的业务逻辑,如定时器任务
- 远程客户端访问,通过一个远程协议直接提供方法(这个我还没读到)
- 降低web
层的耦合,使web
层只用于HTTP
相关的管理,而services
层只处理业务逻辑
- 需将事务边界和安全认证的元数据放在services
层
命令:
roo> service all --interfacePackage cn.edu.cqupt.demo.service
打印信息(部分):
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\service\AdminService.java
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\service\AdminServiceImpl.java
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\service\AdminService_Roo_Service.aj
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\service\AdminServiceImpl_Roo_Service.aj
AdminService_Roo_Service.aj
中定义了接口,AdminServiceImpl_Roo_Service.aj
是接口中方法的实现。
方法概览:
Services 层中的方法
|
调用了实体层的方法 |
---|---|
countAllAdmins()
|
Admin.countAdmins()
|
deleteAdmin(Admin admin)
|
admin.remove()
|
findAdmin(Long id)
|
Admin.findAdmin(id)
|
findAllAdmins()
|
Admin.findAllAdmins()
|
findAdminEntries(int firstResult, int maxResults)
|
Admin.findAdminEntries(firstResult, maxResults)
|
saveAdmin(Admin admin)
|
admin.persist()
|
updateAdmin(Admin admin)
|
admin.merge()
|
6. 库层 Repository Layer
在当前版本,Roo
暂不支持不同的库层。
7. Maven
这一层的东东也不太会使。还是用工具导吧,shell
容易报错。
8. JSON Add-On
命令:
> json all
打印信息:
Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\domain\Admin_Roo_Json.aj
Roo
是使用FlexJSON
实现实体与JSON
格式的数据之间的转换的。
Admin_Roo_Json.aj
中方法概览:
方法名称 | 描述 |
---|---|
toJson()
|
将admin 转为JSON 字符串,去除*.class 属性
|
toJson(String[] fields)
|
同上,包含属性fields ,去除*.class 属性
|
fromJsonToAdmin(String json)
|
JSON 字符串转为admin
|
toJsonArray(Collection<Admin> collection)
|
admin 集合转为JSON 字符串,去除*.class 属性
|
toJsonArray(Collection<Admin> collection, String[] fields)
|
同上,包含属性fields ,去除*.class 属性
|
fromJsonArrayToAdmins(String json)
|
JSON 格式字符串转为admin 集合
|
命令:
> web mvc json all
打印信息:
> Created SRC_MAIN_JAVA\cn\edu\cqupt\demo\web\AdminController_Roo_Controller_Json.aj
AdminController_Roo_Controller_Json.aj
中定义的请求映射,请求头均包含Accept=application/json
:
方法名 | URL | 参数 | 参数说明 | 请求方式 | 返回的结果 |
---|---|---|---|---|---|
showJson
|
/admins/{id}
|
无
|
无
|
GET
|
ResponseEntity<String>
|
listJson
|
/admins
|
无
|
无
|
GET
|
ResponseEntity<String>
|
createFromJson
|
/admins
|
admin
|
JSON格式的admin
|
POST
|
ResponseEntity<String>
|
createFromJsonArray
|
/admins/jsonArray
|
admins
|
JSON格式的admin数组
|
POST
|
ResponseEntity<String>
|
updateFromJson
|
/admins/{id}
|
admin
|
JSON格式的admin
|
PUT
|
ResponseEntity<String>
|
deleteFromJson
|
/admins/{id}
|
无
|
无
|
DELETE
|
ResponseEntity<String>
|
对第三个新建admin
的这个接口我测试了一下,不返回任何结果表示成功创建了:
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://localhost:8080/cblog/admins");
httpPost.addHeader("Accept", "application/json");try {StringEntity entityParam=new StringEntity("{\"passwd\":\"123456\",\"username\":\"xiaofeig\"}");httpPost.setEntity(entityParam);
} catch (UnsupportedEncodingException e1) {e1.printStackTrace();
}CloseableHttpResponse response=null;
InputStream instream=null;
try {response = httpclient.execute(httpPost);HttpEntity entity = response.getEntity();if (entity != null) {instream = entity.getContent();byte[] b = new byte[200];int len = -1;StringBuilder strBuilder = new StringBuilder();while ((len = instream.read(b)) > 0) {strBuilder.append(new String(b, 0, len));}System.out.println(strBuilder.toString());}
} catch (ClientProtocolException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
}finally{if(instream!=null){try {instream.close();} catch (IOException e) {e.printStackTrace();}}if(response!=null){try {response.close();} catch (IOException e) {e.printStackTrace();}}if(httpclient!=null){try {httpclient.close();} catch (IOException e) {e.printStackTrace();}}
}
由于admin
的username
属性是unique
,所以当我再次运行上面的代码时,返回了如下的结果:
{"ERROR":org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement"}
大家仔细看,就会发现上面的信息JSON
格式有点不标准,value
部分左边少了个引号,回到Roo
自动生成的代码部分,的确是少写了一个引号。
return new ResponseEntity<String>("{\"ERROR\":"+e.getMessage()+"\"}", headers, HttpStatus.INTERNAL_SERVER_ERROR);
使用Spring Roo构建项目相关推荐
- spring boot: 构建项目时报错Not a managed type
今天在学习使用Spring Data JPA的时候,将bean和JpaRepository放在了不同的package中,导致无法构建项目,报以下错误: org.springframework.bean ...
- Spring Roo 简介
一直以来,Java/Spring开发被认为是笨重的代表,无法快速生成项目原型和骨架.所以,Spring推出了Spring Roo这个项目,帮助我们快速生成项目原型.本文参考自Spring Roo的官方 ...
- Spring ROO初体验
准备工作: 从Spring官网下载STS(如果没有STS). 体验步骤: 创建Spring Roo基础项目 生成持久层 根据ROO的提示输入jpa setup再按ctrl+space,很遗憾这个快捷键 ...
- spring boot构建基础版web项目(一)springboot、thymeleaf控制层基础构
原文作者:弥诺R 原文地址:http://www.minuor.com/147852147/article 转载声明:转载请注明原文地址,注意版权维护,谢谢! 写前说明 根据个人在各篇博文中看到的信息 ...
- spring cloud构建互联网分布式微服务云平台-docker部署spring cloud项目
一.docker简介 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机). ...
- Spring Boot 从入门到精通(一)HelloWorld(构建项目,热部署,测试)
文章目录 一.使用idea构建项目 二.项目结构 三.编写第一个程序Hello World 四.配置项目的热部署 五.单元测试 一.使用idea构建项目 1.选择 File -> New -&g ...
- Spring Boot+Vue项目 微博系统(2):构建前端Vue项目
系列目录 Spring Boot+Vue项目 微博系统 目录 系列目录 前言 一.安装Vue CLi 二.构建一个前端项目 三.启动测试 四.项目结构 五.配置 前言 前端项目可以借助 Vue CLi ...
- 关于SpringCloud微服务云架构构建B2B2C电子商务平台之- Spring Cloud集成项目简介(三)...
2019独角兽企业重金招聘Python工程师标准>>> Spring Cloud集成项目有很多,下面我们列举一下和Spring Cloud相关的优秀项目,我们的企业架构中用到了很多的 ...
- Spring Roo开发初评
Spring Roo开发初评 我们广泛使用Spring MVC 和 SpringSource 的其他产品, 来 构建企业Web 应用. 作为一家外包 公司 ,我们在前端开发严重地依赖于 Flex,我们 ...
最新文章
- nginx重新编译安装mysql_Centos 6.5编译安装Nginx+php+Mysql
- python基础语法手册format-python基础_格式化输出(%用法和format用法)
- OpenCV中findContours函数的使用
- android 判断手机为小米
- MyBatis 实际使用案例-dataSource
- 在朋友圈求助的NTP问题~
- Repeater控件绑定数据、分页、数据操作,最佳代码
- 项目添加GPUImage
- Python常见问题解决记录1-Non-ASCII character ‘\xe7‘错误
- 每日一个机器学习算法——机器学习实践
- 美团外卖返利小程序-饿了么外卖返利公众号系统– 程序侠
- 线性代数:03 向量空间 -- 向量空间的基与维数,坐标,过渡矩阵
- Flixel 横板游戏制作教程(一)— HelloFlixel ...
- 电影级视频剪辑PR调色/FCP调色/达芬奇调色预设LUTs
- 网络安全涉及到的知识积累(1)
- mysql netcdf_NetCDF Overview
- ESPIDF开发ESP32学习笔记【SPI与片外FLASH基础】
- 红楼梦人物出场统计python_用Python分析《红楼梦》:见证贾府的兴衰
- 图片大小/像素/分辨率之间有什么关系
- Java如何输入一个不知道长度的数组