系列文章目录
文章目录
概述
本文尝试通过跟踪调试,阅读dcm4chee-arc-stow项目的主要业务代码。
一、背景资料
项目 dcm4chee-arc-stow
提供通过 HTTP POST 请求接收包含 Bulkdata 的 DICOM 对象或元数据的 RESTful 服务接口。
- Web 服务端点URL:
http[s]://<host>:<port>/dcm4chee-arc/aets/{AETitle}/rs
- 注:用配置的AETitle替换URL中的
{AETitle}
。
1、RESTful服务
通过RESTful服务在Web上存储(STore Over The Web By RESTful Services)
方法 | 服务路径 | 附加URL | 服务名 |
---|---|---|---|
POST | /dcm4chee-arc/aets/{aet}/rs | /studies | 存储DICOM对象实例(Store Instances) |
POST | /dcm4chee-arc/aets/{aet}/rs | /studies/{study} | 将DICOM对象实例存储到Study中(Store Instances to a Study) |
2、传输存储规范
类别 | 限制 |
---|---|
支持的媒体类型(Accept header) | 仅限于application/dicom 或者 application/dicom+xml |
支持的传输语法(Media Type parameter) | 请参阅 – 《图像存储SOP类的传输语法》,《视频存储SOP类的传输语法》,《SR存储SOP类的传输语法》和《其它存储SOP类的传输语法》 |
SOP类别限制 | 请参阅 – 《存储应用程序实体(SCP)的SOP类别》 |
SOP:服务对象对(Service Object Pair)。
3、服务连接策略
同时HTTP请求的最大数量是可配置的。默认情况下它是无限的。
4、响应消息状态
DCM4CHEE-STOW-SERVICE响应消息头包含指示成功、警告或失败的状态代码,如下面的“HTTP标准响应代码”所示。不使用其他状态代码。
服务状态 | HTTP 状态码 | STOW-RS 描述 |
---|---|---|
失败 | 400 – Bad Request | STOW-RS服务由于语法错误而无法存储任何实例。 |
401 – Unauthorized | STOW-RS服务拒绝创建或附加任何实例,因为客户端未经过身份验证。 | |
403 – Forbidden | STOW-RS服务理解该请求,但拒绝满足该请求(例如,权限不足的经过身份验证的用户)。 | |
409 – Conflict | STOW-RS服务请求格式正确,但由于请求中存在冲突(例如,不支持的SOP类或研究实例UID不匹配),服务无法存储任何实例。这也可用于指示STOW-RS服务由于多种原因无法存储任何实例。有关实例错误的其他信息可以在XML响应消息正文中找到。 | |
503 – Busy | STOW-RS服务无法存储任何实例,因为资源不足。 | |
警告 | 202 – Accepted | STOW-RS服务存储了一些实例,但其他实例存在警告或故障。有关此错误的其他信息可以在XML响应消息正文中找到。 |
成功 | 200 – OK | STOW-RS服务已成功存储所有实例。 |
二、业务分析
1、对象关系
下面是项目相关对象的主要类关系图:
2、项目结构
dcm4chee-arc-stow
项目实际只提供了 /studies
和 /studies/{study}
两个接口,分别用来实现Dicom对象实例和将Dicom对象实例存储到 Study 中。
项目中通过 StowRS
类来实现和公开相应的接口,如下图:
可以看到StowRS 类的 Action 方法中,大部分是成对出现的,也就是每一个成对出现的方法都同时实现了两个接口,如下:
@POST
@Path("/studies")
@Consumes("multipart/related;type=application/dicom")
@Produces("application/dicom+json")
public void storeInstancesJSON(@Suspended AsyncResponse ar, InputStream in) throws Exception {
store(ar, in, Input.DICOM, OutputType.JSON);
}
@POST
@Path("/studies/{StudyInstanceUID}")
@Consumes("multipart/related;type=application/dicom")
@Produces("application/dicom+json")
public void storeInstancesJSON(
@PathParam("StudyInstanceUID") String studyInstanceUID,
@Suspended AsyncResponse ar,
InputStream in) throws Exception {
acceptedStudyInstanceUID = studyInstanceUID;
store(ar, in, Input.DICOM, OutputType.JSON);
}
3、业务流程
下图展示了存储Dicom对象的简单流程:
流程图显示项目的主要功能模块:
StowRS
:服务入口(Controller
),负责公开服务接口(Action
);StoreService
:主要的业务调度模块,负责保存Dicom对象流数据到指定的文件系统或者云存储和保存Dicom Tag信息到指定的数据库;StoreServiceEJB
:数据访问层,负责对数据实体的读写;
三、代码解析
在 StowRS
类找到 storeInstancesJSON
方法:
@POST
@Path("/studies")
@Consumes("multipart/related;type=application/dicom")
@Produces("application/dicom+json")
public void storeInstancesJSON(