栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何基于Spring在强类型语言中正确执行PATCH-示例

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何基于Spring在强类型语言中正确执行PATCH-示例

TL; DR

patchy
是我想出的一个很小的库,它照顾了

PATCH
在Spring中正确处理所需的主要样板代码,即:

class Request : PatchyRequest {    @get:NotBlank    val name:String? by { _changes }    override var _changes = mapOf<String,Any?>()}@RestControllerclass PatchingCtrl {    @RequestMapping("/", method = arrayOf(RequestMethod.PATCH))    fun update(@Valid request: Request){        request.applyChangesTo(entity)    }}

简单的解决方案

由于

PATCH
请求表示要应用于资源的更改,因此我们需要对其进行显式建模。

一种方法是使用普通的旧版本

Map<String,Any?>
,其中
key
客户提交的每个字段都代表对资源相应属性的更改:

@RequestMapping("/entity/{id}", method = arrayOf(RequestMethod.PATCH))fun update(@RequestBody changes:Map<String,Any?>, @PathVariable id:Long) {    val entity = db.find<Entity>(id)    changes.forEach { entry ->        when(entry.key){ "firstName" -> entity.firstName = entry.value?.toString()  "lastName" -> entity.lastName = entry.value?.toString()         }    }    db.save(entity)}

上面的内容很容易遵循:

  • 我们 没有验证 请求值

可以通过在域层对象上引入验证注释来缓解上述问题。尽管这在简单的场景中非常方便,但是一旦我们根据域对象的状态或执行更改的主体的角色引入条件验证,这往往是不切实际的。更重要的是,在产品使用了一段时间并引入了新的验证规则之后,很常见的是仍然允许在非用户编辑上下文中更新实体。在域层上强制不变量,但将验证保留在边缘似乎更为实用。

  • 在许多地方可能非常相似

这实际上很容易解决,在80%的情况下,以下方法将起作用:

fun Map<String,Any?>.applyTo(entity:Any) {    val entityEditor = BeanWrapperImpl(entity)    forEach { entry ->        if(entityEditor.isWritableProperty(entry.key)){ entityEditor.setPropertyValue(entry.key, entityEditor.convertForProperty(entry.value, entry.key))        }    }}

验证请求

感谢Kotlin中的委托属性,可以很容易地构建一个包装器

Map<String,Any?>

class NameChangeRequest(val changes: Map<String, Any?> = mapOf()) {    @get:NotBlank    val firstName: String? by changes    @get:NotBlank    val lastName: String? by changes}

使用

Validator
接口,我们可以过滤出与请求中不存在的属性相关的错误,如下所示:

fun filterOutFieldErrorsNotPresentInTheRequest(target:Any, attributesFromRequest: Map<String, Any?>?, source: Errors): BeanPropertyBindingResult {    val attributes = attributesFromRequest ?: emptyMap()    return BeanPropertyBindingResult(target, source.objectName).apply {        source.allErrors.forEach { e -> if (e is FieldError) {     if (attributes.containsKey(e.field)) {         addError(e)     } } else {     addError(e) }        }    }}

显然,我们可以简化

HandlerMethodArgumentResolver
我在下面所做的开发。

最简单的解决方案

我认为,这将是有意义搞什么名堂上述成一个简单易用的库来包装-看哪修修补补。使用 修补程序时,
可以具有强类型的请求输入模型以及声明性验证。您要做的就是导入配置

@import(PatchyConfiguration::class)
PatchyRequest
在模型中实现接口。

进一步阅读

  • spring同步
  • fge / json-patch


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/395469.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号