java - Hapi FHIR RestfulServer 未解析 R4 同意资源的 id
问题描述
在我的 tomcat 应用程序中,我有一个扩展 RestfulServer 的 FHIRServlet。它注册了一个拦截器,以便能够检索 servlet 接收到的原始 JSON(我需要对其进行签名并返回它)和一个处理接收到的同意资源的同意资源提供程序:
package com.myapp.servlet;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import com.myapp.fhir.resourceprovider.ConsentResourceProvider;
import com.myapp.fhir.resourceprovider.component.PreprocessedRequestInterceptor;
import com.myapp.util.Configuration;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
@WebServlet(urlPatterns = {"/fhir/*"}, displayName = "FHIR Server")
public class FHIRServlet extends RestfulServer {
@Override
protected void initialize() throws ServletException {
setFhirContext(Configuration.getInstance().getFhirContext());
registerInterceptor(new PreprocessedRequestInterceptor());
setResourceProviders(List.of(new ConsentResourceProvider()));
}
}
不幸的是,我有两个问题:
- 当我尝试检索同意的 ID 时,它返回 null。如果我使用相同的 FhirContext 手动解析原始 JSON,它会很好地检索 id。
package com.myapp.fhir.resourceprovider;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hl7.fhir.r4.model.Consent;
import com.myapp.util.Configuration;
public class ConsentResourceProvider implements IResourceProvider {
private final Logger logger = LogManager.getLogger(ConsentResourceProvider.class);
@Override
public Class<Consent> getResourceType() {
return Consent.class;
}
@Create
public MethodOutcome createConsent(@ResourceParam Consent theConsent, HttpServletRequest theRequest) throws Exception {
logger.info("Identifier: " + getConsentIDWithVersion(theConsent)); // Returns null
FhirContext fhirContext = Configuration.getInstance().getFhirContext();
IParser parser = fhirContext.newJsonParser().setPrettyPrint(true);
String userConsentChangeLogToSign = getUserConsentChangeLogToSign(theRequest);
theConsent = parser.parseResource(Consent.class, userConsentChangeLogToSign);
logger.info("Identifier: " + getConsentIDWithVersion(theConsent)); // Returns Consent/6139f5375d04d763fa8d06aa/_history/1631194843361
Provenance provenance = createConsentSignature(theConsent, signedUserConsentChangeLog);
logger.debug("Signature: "+ parser.encodeResourceToString(provenance));
MethodOutcome methodOutcome = new MethodOutcome();
methodOutcome.setResource(provenance);
return methodOutcome;
}
protected String getUserConsentChangeLogToSign(HttpServletRequest theRequest) throws InvalidRequestException {
String originalJSONConsent = new String((byte[])theRequest.getAttribute("originalJSONConsent"), StandardCharsets.UTF_8);
logger.info("Retrieved originalJSONConsent: "+ originalJSONConsent);
return originalJSONConsent;
}
protected Provenance createConsentSignature(Consent theConsent, String signedUserConsentChangeLog) {
Provenance provenance = new Provenance();
String consentId = getConsentIDWithVersion(theConsent);
logger.debug("ConsentId: "+ consentId);
provenance.getTargetFirstRep()
.setType("Consent")
.setReference(consentId);
return provenance;
}
protected String getConsentIDWithVersion(Consent theConsent) {
return theConsent.getId();
}
}
package com.myapp.fhir.resourceprovider.component;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.rest.api.server.RequestDetails;
public class PreprocessedRequestInterceptor {
protected Logger logger = LogManager.getLogger(PreprocessedRequestInterceptor.class);
@Hook(Pointcut.SERVER_INCOMING_REQUEST_POST_PROCESSED)
public boolean interceptRequest(HttpServletRequest theRequest, RequestDetails requestDetails) {
if(!"Consent".equalsIgnoreCase(requestDetails.getResourceName())) {
logger.debug("Not a Consent resource: "+ requestDetails.getResourceName());
return true;
}
requestDetails.loadRequestContents();
if(requestDetails.getRequestContentsIfLoaded() == null) {
logger.debug("RequestContents if not loaded");
return true;
}
logger.info("Set originalJSONConsent attribute to "+ new String(requestDetails.getRequestContentsIfLoaded()));
theRequest.setAttribute("originalJSONConsent", requestDetails.getRequestContentsIfLoaded());
return true;
}
}
我尝试禁用(不注册)最后一堂课,但没有帮助。
- 当我在目标中使用 Consent id 创建出处资源时,它会被截断,因此它只包含“Consent/6139f5375d04d763fa8d06aa”而没有整个 _history 部分。
编辑 > 解析器有一个选项:
getFhirContext().getParserOptions().setStripVersionsFromReferences(false);
这解决了第二个问题。
感觉好像我做错了什么,但我在文档中找不到任何有用的信息。
谢谢你的帮助。
解决方案
推荐阅读
- ansible - 如何通过循环获取在 Ansible 中注册的 json 特定值
- r - '错误:无法从已安装的包中找到函数 runmean':caTools?
- php - Elastica 在 setScript 之前没有对聚合进行分组
- c++ - MOCK 一个接受 unique_ptr 的方法
- ios - 如何在 SWIFT 4 中使用 Twitter REST API 发布直接消息
- angular - 无法隐藏周数 ngx-bootstrap daterangepicker
- limit - 如何在一个html页面中放置几个不同限制的仪表图?
- azure - 使用 Get-AzureADApplication 获取 AAD 应用信息时出错
- java - 每当用户创建他的帐户时,我的网站都需要子域
- c++ - 函数指针作为友元函数