# DICOM文件访问配置说明 ## 问题描述 查询接口返回的本地地址访问403错误:`http://localhost:8080/api/dicom/viewer/INST002/864fdcb2de4a42fca208d7439480e913.dcm` ## 解决方案 ### 1. 新增文件访问接口 **文件位置:** `DicomController.java:263-338` **接口路径:** `GET /api/dicom/viewer/{institutionId}/{fileName}` **功能说明:** - 根据机构ID和文件名查找并返回DICOM文件 - 自动在所有日期子目录中搜索文件 - 支持断点续传 - 添加1小时缓存 ### 2. URL生成逻辑 **文件位置:** `StudyQueryServiceImpl.java:255-290` **工作原理:** - 查询时动态生成访问URL - 从数据库中的 `file_path` 提取机构ID和文件名 - 生成格式:`http://localhost:8080/api/dicom/viewer/{institutionId}/{fileName}` ### 3. 文件查找逻辑 **文件位置:** `DicomController.java:308-338` **查找策略:** ``` 基础路径: ~/qconline/dicom/{institutionId}/ 搜索范围: 所有日期子目录 查找匹配: 文件名完全匹配 ``` **示例:** ``` 请求URL: /api/dicom/viewer/INST002/864fdcb2de4a42fca208d7439480e913.dcm 搜索路径: - ~/qconline/dicom/INST002/2025-12-29/864fdcb2de4a42fca208d7439480e913.dcm - ~/qconline/dicom/INST002/2025-12-30/864fdcb2de4a42fca208d7439480e913.dcm - ... (其他日期目录) ``` ## 权限配置 ### Spring Security配置(如果使用) 需要在SecurityConfig中添加: ```java @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() // DICOM文件访问接口允许访问(根据实际情况调整权限) .antMatchers("/api/dicom/viewer/**").permitAll() // 或者需要认证 // .antMatchers("/api/dicom/viewer/**").authenticated() .and() // ... 其他配置 } ``` ### 文件系统权限 确保DICOM文件目录具有正确的读取权限: ```bash # 检查目录权限 ls -la ~/qconline/dicom/ # 如果权限不足,修改权限 chmod -R 755 ~/qconline/dicom/ ``` ## 测试步骤 ### 1. 测试文件访问接口 ```bash # 直接访问文件 curl -I http://localhost:8080/api/dicom/viewer/INST002/864fdcb2de4a42fca208d7439480e913.dcm # 下载文件 curl -o test.dcm http://localhost:8080/api/dicom/viewer/INST002/864fdcb2de4a42fca208d7439480e913.dcm ``` ### 2. 测试查询接口 ```bash curl -X GET "http://localhost:8080/api/dicom/query?study_instance_uid={uid}&institution_id=INST002" ``` 检查返回的 `instances[].url` 是否可以访问。 ### 3. 浏览器测试 直接在浏览器中访问URL,应该会提示下载DICOM文件。 ## 可能的问题和解决方案 ### 问题1: 403 Forbidden **原因:** - Spring Security拦截了请求 - 文件系统权限不足 **解决方案:** 1. 检查Spring Security配置 2. 修改文件系统权限 ### 问题2: 404 Not Found **原因:** - 文件不存在 - 文件路径不匹配 **解决方案:** 1. 检查日志,确认搜索路径 2. 验证文件实际存储位置 3. 确认 `file_path` 字段存储的路径格式正确 ### 问题3: 文件名包含特殊字符 **原因:** - URL编码问题 **解决方案:** ```java // 在Controller中添加URL解码 String decodedFileName = java.net.URLDecoder.decode(fileName, StandardCharsets.UTF_8); ``` ## 性能优化建议 ### 1. 添加文件缓存 可以使用Spring Cache或Redis缓存频繁访问的文件: ```java @Cacheable(value = "dicomFiles", key = "#institutionId + ':' + #fileName") public byte[] getDicomFile(String institutionId, String fileName) { // ... } ``` ### 2. 使用CDN或对象存储 对于生产环境,建议: - 使用Nginx静态文件服务 - 集成OSS(如阿里云OSS、MinIO) - 添加CDN加速 ### 3. 添加访问日志 记录文件访问情况,便于监控和分析: ```java log.info("DICOM文件访问: institutionId={}, fileName={}, size={}, ip={}", institutionId, fileName, file.length(), request.getRemoteAddr()); ``` ## 配置参数 ### 修改服务器地址 如果需要使用其他地址(如域名),修改 `StudyQueryServiceImpl.java:282`: ```java // 原配置 return String.format("http://localhost:8080/api/dicom/viewer/%s/%s", institutionId, fileName); // 修改为(使用配置文件) @Value("${dicom.viewer.base-url:http://localhost:8080}") private String viewerBaseUrl; return String.format("%s/api/dicom/viewer/%s/%s", viewerBaseUrl, institutionId, fileName); ``` ### 修改缓存时间 修改 `DicomController.java:293`: ```java // 当前:缓存1小时 response.setHeader("Cache-Control", "max-age=3600"); // 修改为:缓存24小时 response.setHeader("Cache-Control", "max-age=86400"); ``` ## 总结 完成以上配置后,DICOM文件访问流程: 1. **上传文件** → 保存到 `~/qconline/dicom/{institutionId}/{date}/{fileId}.dcm` 2. **保存路径** → 将完整路径存储到 `series_info.file_path` 3. **查询数据** → 根据路径动态生成访问URL 4. **访问文件** → 通过 `/api/dicom/viewer/{institutionId}/{fileName}` 访问 现在应该可以正常访问DICOM文件了!