HAPI FHIR Client获取Patient后Spring MVC返回404及JSON转换问题
问题分析与解决方案
核心问题定位
你能通过HAPI的JSON解析器正确序列化Patient对象并打印,但控制器返回时出现404(entity-not-found),本质不是资源不存在,而是Spring MVC在序列化FHIR资源时配置错误,导致响应处理异常,被框架误映射为404错误。
关键错误修正
1. 修复HapiHttpMessageConverter的核心配置
你的代码中创建HapiHttpMessageConverter时未传入FhirContext,这会导致转换器无法识别FHIR资源结构,无法完成序列化。必须关联对应的FHIR上下文(R4版本)。
2. 移除冲突的Jackson转换器
Jackson默认无法正确处理FHIR资源的特殊结构(如多态、扩展字段等),保留自定义的MappingJackson2HttpMessageConverter会让Spring优先尝试用Jackson序列化,导致失败。
3. 明确控制器的响应MediaType
在控制器方法上指定produces = "application/fhir+json",确保Spring调用正确的消息转换器处理响应。
4. 移除多余的类型注册
Patient是HAPI内置的FHIR R4资源类型,无需手动调用registerCustomType。
修正后的完整代码
配置类(FHIR与WebMvc)
@Configuration public class FhirConfig implements WebMvcConfigurer { private final String fhirServerBase = "https://api.logicahealth.org/DVJan21CnthnPDex/open"; @Bean public FhirContext fhirContext() { return FhirContext.forR4(); } @Bean public IGenericClient fhirClient(FhirContext fhirContext) { return fhirContext.newRestfulGenericClient(fhirServerBase); } @Bean public HapiHttpMessageConverter hapiHttpMessageConverter(FhirContext fhirContext) { // 必须传入FhirContext,让转换器知道使用R4版本的解析规则 return new HapiHttpMessageConverter(fhirContext); } @Override public void extendMessageConverters(List<HttpMessageConverter<?>> messageConverters) { // 将HAPI转换器放在最前面,确保优先被Spring选中 messageConverters.add(0, hapiHttpMessageConverter(fhirContext())); } }
控制器代码
@RestController @RequestMapping("/patients") public class PatientController { private final IGenericClient fhirClient; // 构造注入FHIR客户端 public PatientController(IGenericClient fhirClient) { this.fhirClient = fhirClient; } @GetMapping(value = "/{identifier}", produces = "application/fhir+json") public Patient getPatient(@PathVariable String identifier) { Bundle bundle = fhirClient.search() .forResource(Patient.class) .where(Patient.IDENTIFIER.exactly().identifier(identifier)) .returnBundle(Bundle.class) .execute(); // 真实的资源不存在场景,主动抛出404 if (bundle.getEntry() == null || bundle.getEntry().isEmpty()) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Patient not found"); } return (Patient) bundle.getEntry().get(0).getResource(); } }
额外注意事项
- 确保依赖正确:如果使用Maven,需引入
hapi-fhir-spring-boot-starter或hapi-fhir-structures-r4、hapi-fhir-client等核心依赖 - 请求时需确保客户端Accept头包含
application/fhir+json(浏览器测试可通过Postman等工具指定) - 若仍有问题,开启Spring DEBUG日志,查看
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor相关日志,确认消息转换器的选择是否正确
内容的提问来源于stack exchange,提问作者Yaroslav Lukianenko
相关产品推荐
相关产品推荐

