DEX455

Metadata、Platform Cache、Knowledge 与 Files 完全指南

课程介绍

Metadata/Platform Cache/Knowledge/Files完整指南:Metadata.Operations.retrieve同步检索+enqueueDeployment异步部署(仅创建更新/组件全名格式/自定义元数据类型+布局/API40.0+/安装脚本可检索部署+卸载仅检索)、安全(安装类可访问公开元数据/受保护仅同命名空间/非认证包需组织首选项/包描述必须声明通知)、测试(DeployCallbackContext子类重写getCallbackJobId/构造DeployResults测试handleResults)、Permission Set Groups(Test.calculatePermissionSetGroup/CPU限制/复杂PSG+大量用户→失败)、Platform Cache(Session最长8h+Org最长48h/Enterprise10MB+Unlimited30MB+3MB Provider Free/不持久化+类修改失效+不加密+事务回滚+Flow限制)、Session/Org类(键格式+local前缀+put重载+Visibility枚举)、Org并发(per-key而非per-transaction选择)、分区(一个默认+分配≥5整数+不能打包默认分区+运行时验证)、Visualforce全局变量($Cache.Session/$Cache.Org+点符号+CacheBuilder_B_后缀)、CacheBuilder接口(doLoad String/非static/null不缓存/自动处理缺失)、内部机制(本地缓存+LRU淘汰+请求成功提交可变操作)、最佳实践(大项优于小项/分组请求/避免contains+get+getKeys+clear)、Knowledge(KbManagement.PublishingService+SearchPromotionRule+Search.suggest+KnowledgeSuggestionFilter+hasMoreResults分页)、Files(Sfc.ContentDownloadHandlerFactory+ContentDownloadHandler+isDownloadAllowed+redirectUrl+多文件ContentPack+SOAP API异常替代重定向)。

课程章节

本课程共有 12 个章节

  • 1

    Metadata, Platform Cache, Knowledge & Files

    第 301 页

    同学们,我们这节课来看一个非常实用的部分, 就是Apex开发中经常碰到的几个高级能力: 元数据、缓存、文章管理和文件下载。 这些内容能帮你做出更智能、更灵活的应用。 首先,什么是元数据? 在Salesforce里,你建的对象、字段、页面布局, 这些配置都是以“元数据”的形式保存的。 以前我们要手动点鼠标去改, 但现在,我们可以用Apex里的Metadata命名空间, 直接在代码中读取或调整这些配置。 举个例子: 你开发了一个App,安装后需要自动创建几个自定义字段。 那你就可以写上Apex,让它去检查字段存不存在, 不存在就调用Metadata API自动建好。 或者你要做一个自定义的配置向导, 让管理员通过界面调整设置,你背后用代码去改元数据。 而且这样操作,权限都是受控的, 能安全地访问那些受保护的元数据, 不用担心把关键配置搞乱。 接下来是平台缓存。 你有没有遇到过查询数据太慢的情况? 比如每次都要去数据库取同样的记录。 平台缓存就是来解决这个问题的, 它把常用数据暂存起来,下次再取就特别快。 它有两种类型: 一种是会话缓存,数据跟着用户会话走, 用户一退出就没,适合存临时的东西; 另一种是组织缓存,我这边Slide里叫“收件箱缓存”, 你可以理解成“组织级缓存”,一个地方存了, 整个公司的用户都能共享, 非常适合存那些很少变化、但是很多人会用到的配置数据。 再说说Salesforce Knight, 其实这个就是指用程序来管理知识库文章。 比如你们公司有个知识库,里面有各种产品的帮助文档。 你可以写Apex自动创建文章、 设定发布流程、或者根据条件批量翻译。 这样就不需要人工逐条去点了, 尤其是在文章数量很大的时候特别省力。 最后是文件下载的自定义处理。 通常用户点下载按钮,就直接拿到文件了。 但有些场景,你得在下载前做点事情: 比如先检查权限、加上水印, 或者动态把几个文件打包成一个ZIP。 这个时候,Salesforce File支持我们用回调的方式, 让Apex在后台准备好文件流, 再把文件推给用户。 这样整个下载过程我们就有完全的控制权。 你看,把元数据、缓存、知识文章、文件下载这几个点结合起来, 就能做出体验很好、而且很自动化的企业应用。 大家课后可以打开开发者文档, 搜一下Metadata命名空间、Platform Cache、Knowledge和ContentVersion这些关键字, 自己跑一跑例子,感受会更深。 今天就到这里,下节课我们继续深入。

    查看详情
  • 2

    Metadata Operations — Retrieve & Deploy

    第 302 页

    同学们,咱们今天来看一看Apex里一个非常实用的功能,就是,Metadata.Operations类,。这个类主要帮我们用代码来操作元数据,不需要手动去设置界面点来点去。特别是当你在写安装后的自动化脚本,或者做配置工具时,它特别管用。 先说,检索元数据,。我们可以用 `Metadata.Operations.retrieve()` 方法,你只要传进去一个,组件名称的列表,,它就会同步地去查询并返回匹配的组件数据。注意,这里是同步的,调用了马上就拿到结果。返回的数据是一些Metadata实例,比如你查自定义元数据类型记录,就会返回对应记录的结构。这个组件名称它不是简简单单一个名字,而是,完整的名称,,这个完整名称包含三部分:命名空间、类型和组件名。举个例,如果你有一个自定义元数据记录,在命名空间 `MyApp` 下,类型是 `Config__mdt`,记录名字是 `DefaultSettings`,那么完整的名称就是 `MyApp.Config__mdt.DefaultSettings`,一种把命名空间、类型和名字用点连接起来的写法。 再说说,部署元数据,。我们可以用 `Metadata.Operations.enqueueDeployment()` 方法,它是一个异步的操作,用来部署(也就是创建或者更新)元数据。注意是异步,调用后不会立即完成,你后面可能要通过回调或查询部署状态来确认。这个方法,只能创建和更新,,不能拿来删除元数据。而且它接受的参数也包括完整的组件名称和组件内容,同样要遵循那个命名规则。 那么这些功能通常用在哪些场景呢?第一个就是,自定义应用的安装或升级,,你可以在安装后脚本里自动创建一些必要的自定义元数据记录或布局。第二个是,通过UI做安装后配置,,用户点了某个按钮后,后台用Apex去检索并修改配置。第三个,有些受保护的元数据普通用户没法通过UI安全访问,但是通过Apex的 `Metadata.Operations.retrieve()`,在系统模式下可以安全读取。还有一点,如果你想写一个,自定义的管理工具,,用代码去批量管理布局或者自定义元数据,也离不开这两个方法。 不过有一点要特别记住:在,安装后脚本里,,你可以既检索又部署。但是,卸载脚本里,,你只能检索元数据,不能去部署任何东西。因为卸载时系统要清理安装的内容,不允许你再新增或更新。 目前,Metadata.Operations支持的类型主要是,自定义元数据类型记录,和,布局,。也就是说,你暂时不能拿它去操作自定义对象、字段这种大块的元数据,但管理自定义元数据和布局已经能满足很多自动化需求了。 总结一下,这一页Slide的关键点就是:用 `retrieve` 同步检索,用 `enqueueDeployment` 异步部署(只能增改),记住完整的组件名称由命名空间、类型和组件名组成,了解典型用例,区分安装与卸载脚本的权限,并知道当前支持的类型。这样你以后在写自动化配置相关的代码时,心里就有谱了。

    查看详情
  • 3

    Metadata — Security & Testing

    第 303 页

    同学们,咱们今天来聊聊元数据部署中涉及的安全控制和测试方法,这部分内容虽然简短,但在实际开发中非常关键,大家一定要跟上。 先说第一点,关于元数据的访问权限。在Salesforce里,我们有些元数据组件可以被标记为“公共”或者“受保护”的。公共元数据很简单,任何Apex类都能直接访问它;而受保护的元数据呢,只能被同一个命名空间下的代码访问,也就是同一个包里的类才能碰。如果你开发的是一个还没经过安全认证的包,想要去

    查看详情
  • 4

    Permission Set Groups & Platform Cache Intro

    第 304 页

    同学们,今天咱们聊两个比较进阶但很实用的技巧:怎么在测试里处理权限集组,还有怎么用好平台缓存。先看权限集组。你要是在 Apex 里需要测试权限集组的逻辑,会碰到一个问题——权限集组的计算通常是异步的,测试等不起。这时候就用 `System.Test` 类里的 `calculatePermissionSetGroup()` 方法,它能强制立刻完成权限计算,让你马上验证结果。但是,这个方法会吃处理器资源,所以不要到处乱调,最好只放在 `@TestSetup` 方法里运行一次,给整个测试类共享,这样既高效又不会超限。 接下来重点说说缓存。缓存就像是提前把很难拿到的数据放在手边,随用随取,速度飞快。Salesforce 提供了两种缓存:一种是会话缓存,每个用户独享自己的一份,最多能存 8 小时;另一种叫组织缓存,是整个公司的所有用户都能看到,最长可以活 48 小时。只要你是通过安全审查的托管包,就有 3MB 的免费缓存空间,别浪费。需要特别记住的是,缓存的操作是事务性的——如果 Apex 事务中途失败了,比如因为异常回滚了,那这次事务里对缓存做的一切改动也会跟着回滚,这样数据就不会乱。 最后,什么样的数据最适合塞进缓存?记住三个特征:第一,在用户整个会话里会被反复用到的数据,比如用户的个性化配置;第二,基本上不会变动的静态数据,像国家代码列表;第三,获取成本特别高的数据,比如需要跑复杂运算、调用好几次外部接口才得到的。这些放进缓存之后,你的应用响应速度能提升不少。 好了,这两块内容先理解到这里,下次课上我们会动手写几个例子,会更清楚。有什么问题随时问。

    查看详情
  • 5

    Platform Cache — Features & Considerations

    第 305 页

    同学们,今天我们来讲讲 Salesforce 平台缓存。这个东西很有用,但也有一些坑,咱们得弄明白。 首先,平台缓存主要靠这么几个类来操作:缓存.会话、缓存.、缓存.SessionPartition 和缓存.OrgPartition。听起来有点绕,其实就是区分是跟着用户会话走,还是跟着整个组织走。 那怎么找到缓存里的东西呢?靠一个键,这个键的格式是“命名空间.分区.key”。比如你的应用在某个命名空间下,分区名字你自己起,最后是具体的 key。不过,如果你用的是默认分区,那前面的命名空间和分区这部分就可以省略掉。还有一个小提示,本地前置这个说法,指的就是当前组织自己的命名空间。 接下来是几个非常重要的注意事项,千万要记住: 第一,缓存里的数据没有持久化。也就是说,服务器重启或者出问题,数据就可能没了,没法保证一定不丢数据。 第二,数据是没加密的,所以别把密码、密钥这类敏感信息直接塞进去。 第三,并发写入的时候,它只管 key 这一层的冲突,谁最后写谁生效,但不会在整个事务上加锁。所以可能出现先后覆盖的情况。 第四,缓存未命中是常事儿,要么是数据过期了,要么是没存进去。所以你的代码必须能处理空值,或者你主动用 Cache Builder 模式来重新生成数据。 最后,在流程卸载元素里,或者计划作业之类的异步操作之后,千万别用会话缓存,因为那时候用户会话可能已经结束了,数据根本拿不到。 再说说限制,不同版本不一样: 企业版,缓存总共只有 10 MB; 无限版和性能版稍微宽裕点,有 30 MB。 单个 key 最长 50 个字符。 一个缓存项最大 100 KB。 按分区看,会话本地缓存每个分区最多 500 KB,组织本地缓存每个分区最多 1 MB。 这些数字心里要有个数,设计缓存方案的时候才不容易超限。 好,平台缓存的基本要点就是这些,大家如果有问题随时提。

    查看详情
  • 6

    Platform Cache — Partitions

    第 306 页

    同学们,今天我们来看平台缓存里的分区,它是用来分配和管理缓存空间的。 你可以用 Salesforce 安装程序里的“平台缓存”工具,很方便地创建、编辑、删除分区,还能给每个分区分配容量。注意,你只能设定一个默认分区,并且随时可以查看整个缓存的容量细分情况。 每个分区都会分成两个独立的段:一个是会话缓存段,另一个是组织缓存段,它们互相隔离,互不影响。 有一点要特别记住:当你把代码打包成包时,分区不会自动包含进去,你必须显式地把它们添加到包里。验证是否包含也是在运行时进行的。另外,绝对不要在包里使用那个默认分区,这很容易出问题。 在内部呢,平台缓存为了提高性能,会使用本地缓存机制。它还支持原子事务——意思就是,如果一次事务失败了,里面所有的缓存操作都会自动回滚,确保数据一致性。 当缓存容量达到上限,系统要根据 LRU,也就是“最近最少使用”策略来驱逐旧数据。这里有两种驱逐行为:对于会话缓存,它是在多个实例之间均匀驱逐的;而本地缓存则是在每个分区内部,独立地按 LRU 来清理数据。 好了,这块内容就是这些,理解了以后,大家再去操作的时候就会更顺手。

    查看详情
  • 7

    Session Cache — Store & Retrieve

    第 307 页

    同学们,今天我们来讲一讲Salesforce平台缓存里的一个重要用法——,会话缓存,。别担心,我会用大白话把这几个要点拆解清楚。 先记住一个总则:会话缓存可以操作任何分区,但前提是你得用,完全限定键,,这个东西格式就是 ,“命名空间.分区.key”,。比如你有自己的命名空间 `myapp`,分区叫 `UserData`,键是 `profile`,那完全限定键就是 `myapp.UserData.profile`。但如果你操作的是默认分区,就可以省掉前缀,只写分区和键就行。 ,本地前缀,又是什么?它指的是当前组织的命名空间。比如你在自己开发的组织里,这个命名空间就是你自己设置的那个。如果不加命名空间,系统就会自动帮你加上本地前缀。 接下来看 `put()` 方法,它有几个重载版本,允许你传入更多控制参数: - ,TLR,,单位是秒,就是“生存时间”,控制这条缓存数据能活多久。 - ,可见性,,用 `Cache.Visibility` 枚举,可以选 `ALL`(所有用户可见)或 `NAMESPACE_ONLY`(仅同一命名空间可见)。 - ,不可变性,,如果要存的数据以后不再修改,可以标记为不可变,这样读取性能会更好。 对于操作单一分区的情况,我们推荐直接用 `Cache.SessionPartition`,它更简单 —— 你只要先拿到分区对象,然后存数据时就不用再写命名空间,直接给键和值就好。比如: ```apex Cache.SessionPartition part = Cache.Session.getPartition('local.UserData'); part.put('profile', myData, 3600, Cache.Visibility.ALL, false); ``` 看到没有,分区对象拿到之后,不用重复写 `local.UserData` 了。 接下来注意一个托管的坑:如果代码是安装在订阅者组织里的托管包,那么,本地后缀,(就是刚才说的“local”前缀)实际指的是,订阅者组织的命名空间,,而不是你包自己的命名空间。也就是说,即使代码在包里面,存取缓存时如果用了本地前缀,它访问的是客户组织的命名空间,这样不同客户的缓存就隔离开了。 最后一条硬性规定:,不允许在调用类不拥有的分区中执行 Put 调用,。什么意思呢?就是说一个类只能往自己有权操作的分区里放数据。如果你试图往别的命名空间或别的包创建的分区里写东西,系统会直接报错。这条是为了保护数据安全。 好,总结一下:会话缓存用全限定键可以通吃所有分区,但推荐单分区场景下用 `SessionPartition` 简化;`put` 可以控制生存时间、可见性和不可变性;小心托管包里的本地前缀指的是客户组织;还有,千万别往不属于你的分区里写数据。 这样讲是不是清晰多了?后面在开发中多用几次就熟练啦。

    查看详情
  • 8

    Org Cache — Store & Retrieve

    第 308 页

    今天我们来聊聊Salesforce里的缓存,特别是两种比较特殊的缓存:`SYS`和`OrgPartition`。 你之前可能接触过`Session`缓存,它和用户的一次会话绑定,会话结束缓存就没了。而`SYS`和`OrgPartition`呢,基本原理跟会话缓存很像,都是用来临时存一些数据,让访问更快,但它们适用的范围和限制不一样。 首先说一下它们的限制:数据最多能存,1000 KB,,也就是1兆左右;存活时间最长是,48小时,。默认情况下,如果你用组织级别的缓存,它的寿命是,24小时,,除非你手动改了设置。最重要的是——它们可以,跨会话、跨用户、甚至可以跨配置文件共享,。也就是说,不同人在不同时间登录,都能拿到同一份缓存数据,非常适合存一些不经常变动的公共信息。 接下来,在Visualforce页面里怎么用这些缓存呢?很简单,你可以直接用全局变量`$Cache.Session`和`$Cache.SYS`,然后用点号像访问对象一样,读出里面的属性和方法。比如你要取一个存好的值,直接写`$Cache.SYS.myNamespace.MyPartition.myKey`就行了。 这里有个区别要特别注意:如果你用的是,Cache Builder,这种方式来管理缓存,那键的名字要用实现类的名称,并且后面要跟上`_B`这个后缀,作为限定。这样才能正确找到。 另外,跟Apex代码里不一样,你在Visualforce的全局变量中,不能省略命名空间,和,分区的前置,。也就是说,你必须写全路径:命名空间.分区.具体的键名,少一个都不行。 总结一下:`SYS`和`OrgPartition`是一种长生命周期的、共享程度更高的缓存,适合放一些公共数据;在页面上使用它,记住路径要写完整,用点号访问,如果是Cache Builder生成的,键名要加`_B`。 好了,这部分内容就到这里,有什么问题可以随时提问。

    查看详情
  • 9

    CacheBuilder Interface — Safe Caching

    第 309 页

    各位同学,咱们今天来聊一个能让缓存代码变得又简单又安全的好东西,叫 Cache Builder。平时你要是写过缓存,肯定知道那种手动 `put` 的麻烦劲儿,而且一不小心就会漏掉缓存未命中的处理,搞得代码又乱又容易出错。那 Cache Builder 就是专门来解决这个痛点的。 它的思路特别巧妙:你只需要告诉平台“怎么构建这个缓存值就行”,剩下的自动处理全都交给系统。怎么做到的呢?很简单,就两步。 第一步,你定义一个类,这个类要实现 `Cache.CacheBuilder` 接口。接口里只有一个最核心的方法—— `doLoad`,注意没有 `doBoot` 哈,官方叫 `doLoad`。这个方法接收一个 `String` 类型的参数,通常我们把它当成缓存项的“钥匙”,也就是 key。在这个方法里,你就可以写构建缓存值的逻辑,比如去查数据库、调用外部服务什么的,最后把结果返回去。要是返回 `null`,系统就会明白“噢,这次不缓存,下次再问还得重新调 `doLoad`”。另外提醒一下,这个类必须是非静态的,也就是说 `doLoad` 是个实例方法,不是静态方法,因为系统会自动帮你创建这个类的实例来调用它。 第二步,读取缓存的时候,你不再需要自己 `put` 了,只要调一个 `Cache.Session.get` 或者 `Cache.Org.get`,把刚才那个类的 `Class` 对象和你的 key 传进去就行。比如 `Cache.Session.get(MyCacheBuilder.class, 'myKey')`。 整个过程特别顺:第一次调用 `get` 的时候,平台发现缓存里没有这个 key,就会自动帮你创建 `MyCacheBuilder` 的实例,执行你的 `doLoad('myKey')` 方法,拿到结果以后缓存起来,然后返回给你。之后再用同一个 key 去取,就直接从缓存拿,根本不会再走 `doLoad` 了。如果缓存因为超时或者被清理了,也就是“未命中”,那么下一次 `get` 又会自动触发 `doLoad`,重新构建再缓存。你看,是不是全程不需要你手动去 `put`,也不用担心忘记处理未命中,代码干净多了。 咱们举个特别简短的例子,比如说要缓存一个客户的信息。你可以这么写: ```apex public class AccountCacheBuilder implements Cache.CacheBuilder { public Object doLoad(String acctId) { // 根据传入的 acctId 查数据库 Account acc = [SELECT Name, Industry FROM Account WHERE Id = :ac

    查看详情
  • 10

    Platform Cache — Best Practices

    第 310 页

    今天我们来聊聊在Salesforce里使用平台缓存的一些最佳做法,这些技巧能让你的代码跑得更快、更稳。 首先,衡量性能一定要用`System.currentTimeMillis()`,前后打时间戳。别凭感觉,数字才最诚实。 接着,处理缓存未命中时最好利用Cache Builder模式。也就是在`get`的时候,如果发现缓存里没有,不是粗暴地返回null,而是用`Cache.CacheBuilder`接口去自动构建并存入缓存,这样逻辑更清晰,还能把同一类key的构建请求自动分组,避免重复计算。 说到分组,用`get(键)`方法时,同一个分区里的相同key的请求会被平台自动合并,只构建一次,这在高并发下特别重要。所以设计key的时候要有意识地去利用这个特性。 缓存项目的大小也有讲究:少存几个大的,比存一堆零碎的小项要好。你可以把相关记录包装成一个列表或一个Apex类,然后一次性缓存。这样能减少`get`调用的次数,开销更小。 但别忘了平台的限制:单个缓存项不能超过100KB,会话缓存整个分区最多500KB,组织缓存最多1,000KB。规划缓存时要留个心眼,别超了。 诊断页面确实方便,但调用它非常昂贵,生产环境里千万别随便在代码里触发,只在真正排查问题时谨慎使用。 类似地,`getKeys()`和`getCapacity()`这类查询方法也比较重,尽量少用。如果要判断一个键存不存在,千万别先`contains()`再`get()`,这样会多一次往返。直接`get()`,然后判断返回值是不是null就好,既简单又省资源。 最后,清除缓存要克制,只在数据真的变了、必须刷新时才调用`remove`或者`clear`。不要为了“保险”而动不动清空整个缓存。 我举个反例加深印象:如果你有一个列表要缓存,千万别在循环里一条一条地`put`。正确做法是把整个列表一次性`put`进去,这样是一次大的写入,比上百次小写入高效得多,也符合“缓存更大项目”的原则。 记住这些要点,你的缓存代码就能又快又稳,给用户流畅的体验。好,这节课就到这里。

    查看详情
  • 11

    Salesforce Knowledge — Article Management

    第 311 页

    同学们,我们来看看怎么用Apex代码来管理Salesforce知识库里的文章,也就是生命周期管理。 首先,Salesforce给我们提供了一个命名空间,叫`KbManagement`,里面呢,有一个核心的类叫`PublishingService`。这个服务可以帮我们编程实现很多操作。比如,直接发布文章、更新文章内容、检索文章、删除文章,还能帮我们提交翻译请求、设置翻译状态、把文章存档,甚至分配审阅任务。是不是很方便?这样就不用手动在界面上点点点了,自动化流程一下子就搭起来了。 注意一个小细节,所有涉及日期的值,都是基于GMT标准时间的,不是咱们本地时间。所以写代码的时候要心里有数,该转换的时候要转换。 再来看搜索这块。有时候我们想把某些文章重点推广,让它们更容易被搜到。这时候就可以用`SearchPromotionRulesObject`,用它能把特定关键词和已经发布的文章关联起来,这样用户搜索这些关键词的时候,相关文章就会排在更前面。 还有,如果你想在搜索框里实现自动建议,就像咱们在搜索框打字,下面会弹出一些推荐的文章标题,可以用`search.suggest()`方法。但这个方法需要一个过滤器,叫`KnowledgeSuggestionFilter`,通过它可以限定建议的文章只来自某种语言,或者指定文章的发布状态,比如只建议已发布的文章。这样推荐的结果更精准。 最后要记住,所有这些关于知识的代码操作,前提是你的Salesforce环境里已经启用了知识功能,不然调用这些接口会报错哦。 好了,这一页的核心就是,通过`KbManagement`和相关的类,我们可以完全程序化地控制知识文章的整个生命周期,结合搜索增强功能,让知识库更智能。下一节我们再深入看看具体怎么写代码。

    查看详情
  • 12

    Salesforce Files — Download Customization

    第 312 页

    同学们,咱们今天来看Salesforce里一个非常实用的功能,就是怎么通过代码自定义文件的下载行为。 简单说,Salesforce提供了一个接口,叫`ContentDownloadHandlerFactory`,我们可以自己写一个类来实现它。这个工厂里有个方法可以返回一个处理程序,它能决定两件事: 第一,`isDownloadAllowed`,也就是允不允许直接下载; 第二,`redirectUrl`,一个重定向地址。 那它是怎么工作的呢? 当用户点击下载某个文件时,Salesforce并不会立刻把文件给出去,而是先去查有没有我们定义的工厂实现。 系统会调用咱们工厂里的`getContentDownloadHandlerFactory`方法,拿到一个处理实例,然后看它的`isDownloadAllowed`。如果这个值是`false`,下载就会被拦截,同时把用户引导到`redirectUrl`指定的页面去。 如果有多个自己写的工厂,它们会按照名称顺序一个接一个地问,直到有工厂接手处理这个下载请求,这就是所谓的级联处理。 这样设计的用处可多了。 比如,可以按用户的简档或者访问设备来禁止下载。 再比如,做收件箱场景的控制,或者在下载前先送到外部做防病毒扫描。 还有像打包下载多个文件、生成内容包再提供下载点,都可以靠这套机制灵活实现。 咱们举个收件箱集成的实际例子: 用户想下载文件,我们的工厂检测到这个请求,把`isDownloadAllowed`设成`false`,再把`redirectUrl`指到一个外部系统地址。 用户被转到那个外部系统,系统会先处理文件——比如杀毒、转格式——处理完后,生成一个真正的下载端点,用户最后才从这个端点拿到文件。整个过程对用户来说可能只是一瞬间,但背后就是靠这个下载工厂在控制流程。 这样一来,大家就完全可以把Salesforce的文件下载行为跟自己的业务场景深度整合起来,既安全又灵活。 好了,这一页的核心就是这些,有什么问题咱们随时讨论。

    查看详情