SAP学习笔记 - 开发49 - RAP开发 Managed App BDL(Behavior Definition Language) ,Mapping,Behavior Pool,ETag

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

上一章讲了BDL(Behavior Definition Language) 。

SAP学习笔记 - 开发48 - RAP开发 Managed App BDL(Behavior Definition Language) -CSDN博客

本章继续将RAP开发的知识。

- Mapping

- Behavior Pool Class

- V2 版本的Service Binding (V4 版的需要启用Draft才会显示Create按钮)

- ETag

目录

1,Mapping

1-1,mapping for zt04_travel_m

1-2,mapping for zt04_booking_m

1-3,mapping for zt04_booksuppl_m

2, Behavior Pool Class(RAP Handler Class)

2-1,主要用途

2-2,典型应用场景

2-3,技术特点

2-4,zcl_bp_04_dv_travel_m

2-5,zcl_bp_04_dv_booking_m

2-6,zcl_bp_04_dv_booking_m

3,为啥Create按钮没显示出来?

3-1,方法 1:直接在 CDS View 上使用 @odata.draft.enabled

3-2,方法 2:显式使用 @ObjectModel 注解(旧版方式,SAP 推荐使用 @odata 替代)

3-3,方法 3:在 Behavior Definition 中启用 Draft

3-4,总结

4,作成 Service Binding - Z04_UI_TRAVEL_M_V2

4-1,Create - Travel_M

4-2,Create - Booking_M

4-3,Create - BookSuppl_M 

4-4,Behavior Definition - Z04_DV_Travel_M 去掉Readonly

4-5,Behavior Definition - Z04_DV_Booking_M 去掉Readonly

4-6,Behavior Definition - Z04_DV_BookSuppl_M 去掉Readonly

5,ETag

5-1. ETag 的作用

5-2. ETag 在 SAP Fiori / OData 中的应用

5-3. ETag 的生成方式

5-4. 如何在 SAP CDS / RAP 中启用 ETag?

(1) 在 CDS View 中定义 ETag 字段

(2) 在 Behavior Definition 中启用 ETag 检查

5-5. ETag 的工作流程(示例)

5-6. 常见问题

Q1: 如果不加 ETag 会怎样?

Q2: ETag 和 Draft 模式有什么关系?

Q3: 能否自定义 ETag 生成逻辑?

5-7.总结

5-8,实战 - 在Data View(Interface层)加ETag

a),Data Definition - Z04_DV_Travel_M - @Semantics.systemDateTime.localInstanceLastChangedAt: true

b),Behavior Definition - Z04_DV_Travel_M - etag master LastChangedAt

c),Data Definition - Z04_DV_Booking_M - @Semantics.systemDateTime.localInstanceLastChangedAt: true 

d),Behavior Definition - Z04_DV_Booking_M - etag master LastChangedAt

e),Data Definition - Z04_DV_BookSuppl_M - @Semantics.systemDateTime.localInstanceLastChangedAt: true 

f),Behavior Definition - Z04_DV_BookSuppl_M - etag master LastChangedAt

5-9,实战 - 在Projection View(Consumption层)加ETag

5-10,实战 - 前端 ETag 不一致时的Check Error


下面是详细内容。

1,Mapping

Mapping就是下面这个东西,用于匹配View entity 里面的字段和最底层的表里的字段。

为啥需要这个东西呢?

想让Fiori Element(前端UI)输入的数据后端能认,能保存,就需要添加Mapping。

前面咱们在说Data Definition ( Data View /Projection View Entity)里面都是有 as 别名的,

一旦有了别名,那么后续的都要用别名,所以前端看到的很可能和数据库表里不一样。

1-1,mapping for zt04_travel_m

  mapping for zt04_travel_m
    {
      TravelId      = travel_id;
      AgencyId      = agency_id;
      CustomerId    = customer_id;
      BeginDate     = begin_date;
      EndDate       = end_date;
      BookingFee    = booking_fee;
      TotalPrice    = total_price;
      CurrencyCode  = currency_code;
      Description   = description;
      OverallStatus = overall_status;
      CreatedBy     = created_by;
      CreatedAt     = created_at;
      LastChangedBy = last_changed_by;
      LastChangedAt = last_changed_at;
    }

1-2,mapping for zt04_booking_m

  mapping for zt04_booking_m
    {
      TravelId      = travel_id;
      BookingId     = booking_id;
      BookingDate   = booking_date;
      CustomerId    = customer_id;
      CarrierId     = carrier_id;
      ConnectionId  = connection_id;
      FlightDate    = flight_date;
      FlightPrice   = flight_price;
      CurrencyCode  = currency_code;
      BookingStatus = booking_status;
      LastChangedAt = last_changed_at;
    }

1-3,mapping for zt04_booksuppl_m

  mapping for zt04_booksuppl_m
    {
      TravelId            = travel_id;
      BookingId           = booking_id;
      BookingSupplementId = booking_supplement_id;
      SupplementId        = supplement_id;
      Price               = price;
      CurrencyCode        = currency_code;
      LastChangedAt       = last_changed_at;
    }

TODO:怪了,怎么还没有Create 按钮呢?? 

2, Behavior Pool Class(RAP Handler Class)

啥是 Behavior Pool 呢?

Behavior Pool Class 是 SAP Fiori Elements 和 RAP (Restful ABAP Programming) 模型中的一个重要概念,主要用于定义和实现业务对象的行为。

2-1,主要用途

  1. 集中管理业务逻辑:作为业务对象行为的集中存储库,包含所有与业务实体相关的行为实现。

  2. 定义标准操作:实现标准 CRUD 操作(Create, Read, Update, Delete)的自定义逻辑。

  3. 实现附加功能:包括:

    • 验证逻辑(Validations)

    • 授权检查(Authorizations)

    • 确定逻辑(Determinations)

    • 动作(Actions)

    • 特性控制(Feature Control)

  4. 提高代码复用:通过继承机制,多个业务实体可以共享相同的行为实现。

2-2,典型应用场景

  • 覆盖标准操作(如自定义保存逻辑)

  • 实现业务特定的验证规则

  • 定义实体间的交互行为

  • 控制UI元素的可见性和可用性

2-3,技术特点

  • 使用 ABAP 类实现(通常继承自标准行为池类)

  • 通过注解或配置与 CDS 视图关联

  • 在 RAP 框架中自动调用

Behavior Pool Class 是连接数据模型(CDS)和用户界面(Fiori Elements)的关键组件,使开发者能够在不修改UI框架的情况下定制业务逻辑。

下面在咱们的系统上建几个空的Behavior Pool Class。

2-4,zcl_bp_04_dv_travel_m

这里暂时啥也没有,咱们就是单纯的作成一个Class,将来有些实现可以放到这里来做

2-5,zcl_bp_04_dv_booking_m

2-6,zcl_bp_04_dv_booking_m

3,为啥Create按钮没显示出来?

查了半天,原因好像是OData V4,必须要启用 draft,才会显示该Create按钮/ Edit按钮也一样。

>With OData V4, create button becomes visible only if you enable draft.

Create button not visible - SAP Community

Solved: CAP Node.js Create Button missing in Odata preview - SAP Community

还有人问说那必须启用Draft功能了啊?我能不启用不?

好像不能,如果你实在不想用Draft功能,那你用V2嘛,它不强制你启用Draft。

那要如何启用Draft功能呢?

SAP CDS 提供了 @ 注解语法,可以直接在 CDS 视图上添加 OData 注解。

3-1,方法 1:直接在 CDS View 上使用 @odata.draft.enabled

在 CDS View 的 DEFINE VIEWENTITY 定义上,你可以直接添加 @odata.draft.enabled: true 来启用 Draft 模式:

abap

@AbapCatalog.sqlViewName: 'ZBOOKS'
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Books'
@odata.draft.enabled: true
define view ZBooks as select from book as Book {
    key Book.id as Id,
    Book.title as Title,
    Book.author as Author,
    Book.price as Price
}

📌 注意@odata.draft.enabled 是 SAP 推荐的 CDS 原生注解,它会自动转换为 OData 的 Common.DraftRootCommon.DraftNode 注解。


3-2,方法 2:显式使用 @ObjectModel 注解(旧版方式,SAP 推荐使用 @odata 替代)

如果你使用的是较旧的 SAP 版本,可能会看到 @ObjectModel 注解方式:

abap

@AbapCatalog.sqlViewName: 'ZBOOKS'
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Books'
@ObjectModel.modelCategory: #BUSINESS_OBJECT
@ObjectModel.writeActivePersistence: 'ZBOOK_DB'
@ObjectModel.draftRootEnabled: true
define view ZBooks as select from book as Book {
    key Book.id as Id,
    Book.title as Title,
    Book.author as Author,
    Book.price as Price
}

⚠️ 注意@ObjectModel 注解方式在较新的 SAP BTP / RAP 开发中已被 @odata 替代,但仍然可用。


3-3,方法 3:在 Behavior Definition 中启用 Draft

如果你使用 ABAP RESTful Application Programming (RAP),还需要在 Behavior Definition 里启用 Draft:

abap

managed implementation in class ZBP_BOOKS unique;
strict ( 2 );

define behavior for ZBooks alias Books
// 启用 Draft 支持
draft table ZBOOKS_DRAFT
lock master
authorization master ( instance )
{
  // 定义操作
  create;
  update;
  delete;
}

📌 关键点

  • draft table ZBOOKS_DRAFT 表示 Draft 数据存储的表(需要提前创建)。

  • 必须定义 create, update, delete 操作,否则 Draft 功能可能无法正常工作。


3-4,总结

方式适用场景代码示例
CDS @odata.draft.enabled推荐方式(SAP BTP / RAP)@odata.draft.enabled: true
CDS @ObjectModel.draftRootEnabled旧版方式(兼容性)@ObjectModel.draftRootEnabled: true
Behavior DefinitionRAP 必须配置draft table ZBOOKS_DRAFT

如果你的项目是 SAP Fiori Elements + RAP,建议:

  1. 在 CDS View 上使用 @odata.draft.enabled: true

  2. 在 Behavior Definition 里配置 draft table

  3. 不需要额外写 Metadata Extension(除非有特殊 UI 注解)

这样就能完整支持 Draft 功能了! 🚀

我合计这里是RAP,那咱们用上面 方法3 不就OK了吗?

结果我发现 draft table ZBOOKS_DRAFT,这个Draft 用Table要单独做。

那倒也是,草稿嘛,虽然是临时数据,也是数据啊,总得有地方存嘛。

TODO:那就先这样,以后再说。

上面V4 需要启用Draft 才会显示Create按钮,等学到Draft的时候再回归V4。

这里咱为了实验作成/编集,咱们这里先用一下不受推荐的 V2。

4,作成 Service Binding - Z04_UI_TRAVEL_M_V2

作成方法参照如下文章,作成完之后,点一下Publish 发布服务

SAP学习笔记 - 开发45 - RAP开发 Managed App New Service Definition,Metadata Extension-CSDN博客

4-1,Create - Travel_M

然后再Preview,这回就显示 Create(登录)了吧。

点作成按钮

TODO:这个Travel ID咋还不能输入了呢?

先输入其他字段值,然后点作成(Save)

Travel_M 数据看来是作成成功了

4-2,Create - Booking_M

点Booking 一览 的 Create(作成)按钮

输入各字段值,点 作成按钮

这样就作成了

4-3,Create - BookSuppl_M 

咱们再点 Booking Supplement 一览的作成按钮

输入各字段值,然后点作成按钮

这个也作成好了

看一下数据,作成的是Travel ID 是 00000000

看页面,应该就是这条数据了哈

ID 有点儿怪哈,我再做几条试试看。 

出错了,说Key重复,可见这个Travel ID什么的,应该也要可以输入的吧

下面来看一下如何修改成可以手动输入Key。

4-4,Behavior Definition - Z04_DV_Travel_M 去掉Readonly

然后再试试,好像就好了哈

好,输入,点 作成

这不就作成了嘛

4-5,Behavior Definition - Z04_DV_Booking_M 去掉Readonly

但是注意这里的Travel ID必须要设为Readonly,因为咱们和Travel_M设置了父子关系了嘛

如此就可以输入Booking ID了 

4-6,Behavior Definition - Z04_DV_BookSuppl_M 去掉Readonly

但是注意这里的Travel ID/Booking ID 必须要设为Readonly,因为咱们和Booking_M设置了父子关系了嘛,而且为了数据的连贯性,Travel ID也不能让手动改,都保持Readonly。

这样改一下,Booking Supplement ID 也就可以改了哈。

做完数据之后,然后回到一览,这回就完事儿OK了吧。

5,ETag

咱们先看一下ETag是啥,和干啥用的。

ETag(实体标签)是 HTTP 协议OData 服务 中用于 资源版本控制 的机制,主要用于 乐观锁(Optimistic Locking),防止并发修改导致的数据冲突。


5-1. ETag 的作用

  • 检测资源是否被修改:客户端请求数据时,服务器返回 ETag(通常是哈希值或版本号),客户端后续修改数据时需带上该 ETag,服务器会检查 ETag 是否匹配,如果不匹配则拒绝更新(返回 412 Precondition Failed)。

  • 减少不必要的数据传输:客户端可通过 If-None-Match 头(携带 ETag)询问服务器资源是否变化,若无变化,服务器返回 304 Not Modified,节省带宽。


5-2. ETag 在 SAP Fiori / OData 中的应用

SAP Fiori ElementsOData 服务 中,ETag 通常用于:

  • 防止并发修改:多个用户同时编辑同一条数据时,只有第一个提交的能成功,后续提交会因 ETag 不匹配而失败。

  • 支持 Draft(草稿)模式:在 RAP(ABAP RESTful Application Programming)中,ETag 确保草稿和激活的实例版本一致。


5-3. ETag 的生成方式

ETag 的值通常由服务器生成,可以是:

  • 数据库记录的 last_changed_timestamp

  • 哈希值(如 MD5、SHA1)

  • 自定义版本号(如 UUID 或递增数字)

SAP CDS / RAP 中,ETag 通常基于 @odata.etag 注解 定义的字段自动生成。


5-4. 如何在 SAP CDS / RAP 中启用 ETag?

(1) 在 CDS View 中定义 ETag 字段

abap

@AbapCatalog.sqlViewName: 'ZBOOKS'
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Books'
@odata.draft.enabled: true
define view ZBooks as select from book as Book {
    key Book.id as Id,
    Book.title as Title,
    Book.author as Author,
    Book.price as Price,
    // 定义 ETag 字段(通常用最后修改时间或版本号)
    Book.last_changed as LastChanged 
    // 使用 @odata.etag 注解标记该字段用于 ETag
    @odata.etag: true
}

📌 说明last_changed 可以是 UTCLONG 类型(时间戳),每次数据修改时自动更新。

(2) 在 Behavior Definition 中启用 ETag 检查

abap

managed implementation in class ZBP_BOOKS unique;
strict ( 2 );

define behavior for ZBooks alias Books
draft table ZBOOKS_DRAFT
lock master
authorization master ( instance )
{
  // 启用 ETag 检查(乐观锁)
  use etag;
  
  // 定义操作
  create;
  update;
  delete;
}

5-5. ETag 的工作流程(示例)

  1. 客户端请求数据

    http

GET /odata/v4/AdminService/Books(1)

服务器返回

http

  • HTTP/1.1 200 OK
    ETag: "2024-05-20T14:30:00Z"
    {
      "ID": 1,
      "Title": "SAP RAP Guide",
      "Author": "John Doe",
      "Price": 49.99
    }

  • 客户端尝试修改数据(携带 ETag)

    http

  1. PATCH /odata/v4/AdminService/Books(1)
    If-Match: "2024-05-20T14:30:00Z"
    {
      "Price": 59.99
    }
    • 如果 ETag 匹配 → 更新成功(返回 200 OK)。

    • 如果 ETag 不匹配(数据已被其他人修改)→ 返回 412 Precondition Failed


5-6. 常见问题

Q1: 如果不加 ETag 会怎样?
  • 数据可能被覆盖:多个用户同时编辑时,后提交的会覆盖先提交的修改("last write wins")。

  • Fiori App 可能报错:某些 SAP Fiori Elements 应用(如 Object Page)要求必须启用 ETag。

Q2: ETag 和 Draft 模式有什么关系?
  • Draft 模式 下,ETag 用于确保:

    • 用户编辑的是最新的草稿版本。

    • 激活操作时检查数据未被其他人修改。

Q3: 能否自定义 ETag 生成逻辑?
  • 可以,通过 Behavior Implementation 类中的 get_etag 方法自定义:

    abap

  • CLASS zbp_books DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zbooks.
    PUBLIC SECTION.
      METHODS get_etag REDEFINITION.
    ENDCLASS.
    
    CLASS zbp_books IMPLEMENTATION.
      METHOD get_etag.
        " 自定义 ETag 计算逻辑(如 MD5 哈希)
        etag = compute_custom_etag( keys ).
      ENDMETHOD.
    ENDCLASS.


5-7.总结

关键点说明
ETag 的作用乐观锁机制,防止并发修改冲突
SAP 中的实现通过 @odata.etag 注解 + Behavior Definition 的 use etag
Draft 模式依赖 ETag确保草稿和激活版本的一致性
客户端交互通过 If-Match 请求头传递 ETag

如果你的 SAP Fiori Elements 应用涉及 数据编辑,强烈建议启用 ETag 以避免数据竞争问题! 🚀

下面来看一下实例。

5-8,实战 - 在Data View(Interface层)加ETag

a),Data Definition - Z04_DV_Travel_M - @Semantics.systemDateTime.localInstanceLastChangedAt: true

b),Behavior Definition - Z04_DV_Travel_M - etag master LastChangedAt

这个和上面的 a 是配套的。

c),Data Definition - Z04_DV_Booking_M - @Semantics.systemDateTime.localInstanceLastChangedAt: true 

d),Behavior Definition - Z04_DV_Booking_M - etag master LastChangedAt

这个和上面的 c 是配套的。

e),Data Definition - Z04_DV_BookSuppl_M - @Semantics.systemDateTime.localInstanceLastChangedAt: true 

f),Behavior Definition - Z04_DV_BookSuppl_M - etag master LastChangedAt

这个和上面的 e 是配套的。

上面在Data Definition(Interface层)上加了ETag,是不是就完事儿了呢?

不是的,在Data Definition(Interface层)之上,还有一层Projection View(Consumption层),

那里 不加也是不好用的。

咱们在Projection View里面也加一下,然后看一下在前端的表现形式。

5-9,实战 - 在Projection View(Consumption层)加ETag

Projection View里面就简单了,只需加 use etag即可。

按下 Ctrl+F3 激活,然后刷新 V2 版的Preview

点编集,然后点F12 > Network Tab

 

就是这样的,修改任意字段,然后点一下保存按钮

 

就是这个If-Match,它后面的长长的那个串,就是LastChangedAt 的值,咱们就是用它做ETag的

> If-Match: W/"'SADL-202507231327073360130C~20250723132707.3360130'"

这样ETag就算是准备好了,咱们来看一下如果ETag不一致的时候,会发生什么事儿。 

5-10,实战 - 前端 ETag 不一致时的Check Error

打开2个相同的Travel Detail Browser Tab,分别点编集按钮

- Tab1,当然这个也可以理解为User 1,因为谁会没啥事儿打开俩Tab啊,多数时俩User同时编集

- Tab2

 

- Save Tab1 的内容

- Save Tab2 的内容,显示如下错误,基本上达到了咱们的目的

无法保存您的更改。有较新版本可用。请刷新您的数据,以使更改生效到最新版本。

変更を保存できませんでした。より新しいバージョンがあります。最新バージョンに変更を加えるには、データをリフレッシュしてください。

Your changes could not be saved. A newer version is available. Please refresh your data to make your changes to the latest version.

咱们直接点 Refresh 按钮,这样就可以显示最新数据

 

然后再点编集按钮,再最新的基础上修改

 

然后点保存,就OK了

 

以上就是本篇的全部内容。

更多SAP顾问业务知识请点击下面目录链接或东京老树根的博客主页

https://blog.csdn.net/shi_ly/category_12216766.html

东京老树根-CSDN博客

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值