Spring Data REST——用法小结

Spring Data Rest设计的目的是消除curd的模板代码,减少程序员的刻板的重复劳动,尽管拥有强大的功能和精妙的设计,但它作为Spring Data系列产品,终究不能完全代替传统的SpringMVC,其特点也如Spring Data JPA之与Spring Data JDBC等低封装度的产品,高度封装了许多细节,但在用法上有它自己的一套规则。

〇、使用前提条件

此框架需配合其他ORM框架使用如SDJ,使用时给人的直观感受就是暴露了资源仓库。

一、普通的crud

这部分作为SDR的最大亮点,它的实现形式就是完全消除模板代码,我们需要做的就是访问对应的资源仓库地址实现相关操作

增删改查动作分别对应四种请求类型:post、delete、update/patch、get

增:直接携带请求体请求仓库地址;如有对应关系,一对多的多端的关联对象属性应为对应的关联对象的仓库地址(SDR和SDJ会将该链接转为相关对象储存),多对一的一端的关联对象集合属性应为要储存的关联对象集合

删:直接请求资源地址;若被删对象的关联对象类(一对多的“一”端)的关系注解处(如@OneToMany)写明了级联操作(如:CascadeType.REMOVE)则关联的对象将被一并删除。

改:直接请求资源地址,put将完全替换原对象,patch将修改指定了值的对象属性(忽略空值);然而只有patch请求能修改关联关系,put请求将忽略关联关系对象。


查:

Spring Data REST 在查询具有对象属性(已使用@ManyToOne等注解建立关联关系)的对象时,默认将对象属性用链接代替,这体现了REST服务概念中的“资源”的特点,但是当遇到需要同时查询多个具有关联关系的对象及其关联的对象的场景的时候,不免要发送多个请求来查询关联对象,Spring官方对这种场景的解决方案是使用@Projection注解自定义返回字段,此查询法适用于查询资源集合和需要显示指定属性的资源对象。

使用步骤:

0、创建实体类,使用@OneToMany等注解建立好对象的关联关系,并创建对应的Repository资源仓库

1、创建一个具有查询对象属性方法的接口,该接口内的所有查询方法返回的字段即为将来使用对应api查询时返回的Json属性;接口包含的查询方法名必须严格匹配getXXX格式(XXX即为对象属性名),否则查询结果无法映射,系统将报错;该接口使用

@Projection(name="X",types={“XX.class”})

注解以表明调用该api的projection参数(X)和它关联的类(XX)。例子如下

自定义的包含@Projection注解的接口

2、如需将该projection定义为默认的返回形式,则在对应的Repository仓库上使用

@RepositoryRestResource(excerptProjection = XXXX.class)

注解,但是这种方法将导致查询单个对象时默认返回projection定义的形式。例子如下

调用定义好的接口

3、当需要使用自定义api查询关联对象时,需要在仓库地址后加入projection=X参数

在地址后加参数


从源码结构中可以看出,其封装了部分mvc的相关功能,这体现了它最大的特点——“便捷”,然而这就不可避免地引入了额外的复杂度,我在使用时就必须根据它要求的用法、它自身特点并考虑项目需求,划分合适的项目结构,编写逻辑代码。

我这两天遇到一个业务场景:管理员可以新增、修改用户(密码)信息,本以为结合spring security一起使用是很方便的,然而在编写代码时发现以下需要注意的地方:

1、sdr默认的仓库权限配置不灵活:常用的仓库方法如GET users、GET user/{id}等,还有自定义的仓库方法,均无法直接在rest入口处配置鉴权检查(因为sdr 自带的mvc没有提供相关接口)

解决:根据官方文档信息得出折衷的解决办法就是在仓库方法上直接配置,然而这样做与我理解的传统mvc配置鉴权的方式有出入,优先级最高的,需要在“入口处”进行的权限检查工作转移到了持久层上。实际上,sdr在rest入口和持久层间有其他增强方法可配置(后面会讲到),这些地方常用来进行参数校验,并且我将部分权限检查移到了那里,但是不论权限配置在这些增强方法上进行还是在上述持久层进行,都不是如“传统的”mvc结构那样在rest入口处进行校验、检查工作

2、需要针对sdr封装的一系列功能进行额外配置:如对mvc配置的cors放行条件对sdr不起作用,(其他配置后续更新)

解决:


3、增强方法的使用上需要注意sdr对于对象的处理流程:我需要对修改密码的用户提交的新密码进行加密,在使用由 @HandleBeforeSave 注解标注的方法时,其传入的对象经过了以下处理:

1、从数据库用id查出对象user0;

2、将传入的对象与user0进行比对;

3、更新user0中与接收的对象不相同的字段

这样我不能简单地对用户的密码进行加密或不加密,这个字段有可能是用户设置的新密码,有可能是数据库中已加密的密码(用户未更新密码),我需要调用spring security提供的正则表达式判断这个密码到底是用户提供的还是数据库中原本 已加密的:

解决:


public void encodePassword(User user) {

Optional.of(user.getPassword())

            .filter(pw -> !BCRYPT_PATTERN.matcher(pw).matches())

.ifPresent(

pw ->user.setPassword(passwordEncoder.encode(pw))

);

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351