more work on http client

This commit is contained in:
Grahame Grieve 2024-10-10 19:29:58 +08:00
parent b9299fa9e2
commit c7ccbb0110
5 changed files with 127 additions and 29 deletions

View File

@ -258,34 +258,59 @@ public class FhirRequestBuilder {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T extends Resource> T unmarshalReference(Response response, String format, String resourceType) { protected <T extends Resource> T unmarshalReference(Response response, String format, String resourceType) {
int code = response.code();
boolean ok = code >= 200 && code < 300;
if (response.body() == null) { if (response.body() == null) {
return null; if (!ok) {
throw new EFhirClientException(response.message());
} else {
return null;
}
} }
String body;
Resource resource = null; Resource resource = null;
try { try {
body = response.body().string();
String ct = response.header("Content-Type"); String ct = response.header("Content-Type");
if (ct == null) { if (ct == null) {
resource = getParser(format).parse(response.body().bytes()); if (ok) {
resource = getParser(format).parse(body);
} else {
System.out.println("Got error response with no Content-Type from "+source+" with status "+code);
System.out.println(body);
resource = OperationOutcomeUtilities.outcomeFromTextError(body);
}
} else { } else {
if (ct.contains(";")) {
ct = ct.substring(0, ct.indexOf(";"));
}
switch (ct) { switch (ct) {
case "application/json": case "application/json":
case "application/fhir+json": case "application/fhir+json":
resource = getParser(ResourceFormat.RESOURCE_JSON.getHeader()).parse(response.body().bytes()); if (!format.contains("json")) {
System.out.println("Got json response expecting "+format+" from "+source+" with status "+code);
}
resource = getParser(ResourceFormat.RESOURCE_JSON.getHeader()).parse(body);
break; break;
case "application/xml": case "application/xml":
case "application/fhir+xml": case "application/fhir+xml":
case "text/xml": case "text/xml":
if (!format.contains("xml")) {
System.out.println("Got xml response expecting "+format+" from "+source+" with status "+code);
}
resource = getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(response.body().bytes()); resource = getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(response.body().bytes());
break; break;
case "text/plain": case "text/plain":
resource = outcomeFromTextError(response.body().string()); resource = OperationOutcomeUtilities.outcomeFromTextError(body);
break; break;
case "text/html" : case "text/html" :
resource = OperationOutcomeUtilities.outcomeFromTextError(XhtmlUtils.convertHtmlToText(response.body().string())); resource = OperationOutcomeUtilities.outcomeFromTextError(XhtmlUtils.convertHtmlToText(response.body().string(), source));
break; break;
default: // not sure what else to do? default: // not sure what else to do?
System.out.println("Got content-type '"+ct+"' from "+source); System.out.println("Got content-type '"+ct+"' from "+source);
resource = OperationOutcomeUtilities.outcomeFromTextError(response.body().string()); System.out.println(body);
resource = OperationOutcomeUtilities.outcomeFromTextError(body);
} }
} }
} catch (IOException ioe) { } catch (IOException ioe) {
@ -293,15 +318,20 @@ public class FhirRequestBuilder {
} catch (Exception e) { } catch (Exception e) {
throw new EFhirClientException("Error parsing response message from "+source+": "+e.getMessage(), e); throw new EFhirClientException("Error parsing response message from "+source+": "+e.getMessage(), e);
} }
if (resource instanceof OperationOutcome && !"OperationOutcome".equals(resourceType)) { if (resource instanceof OperationOutcome && (!"OperationOutcome".equals(resourceType) || !ok)) {
OperationOutcome error = (OperationOutcome) resource; OperationOutcome error = (OperationOutcome) resource;
if (hasError((OperationOutcome) resource)) { if (hasError((OperationOutcome) resource)) {
throw new EFhirClientException("Error from "+source+": " + ResourceUtilities.getErrorDescription(error), error); throw new EFhirClientException("Error from "+source+": " + ResourceUtilities.getErrorDescription(error), error);
} else { } else {
// umm, weird... // umm, weird...
System.out.println("Got OperationOutcome with no error from "+source+" with status "+code);
System.out.println(body);
return null;
} }
} }
if (resource == null) { if (resource == null) {
System.out.println("No resource from "+source+" with status "+code);
System.out.println(body);
return null; // shouldn't get here? return null; // shouldn't get here?
} }
if (resourceType != null && !resource.fhirType().equals(resourceType)) { if (resourceType != null && !resource.fhirType().equals(resourceType)) {

View File

@ -248,34 +248,59 @@ public class FhirRequestBuilder {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T extends Resource> T unmarshalReference(Response response, String format, String resourceType) { protected <T extends Resource> T unmarshalReference(Response response, String format, String resourceType) {
int code = response.code();
boolean ok = code >= 200 && code < 300;
if (response.body() == null) { if (response.body() == null) {
return null; if (!ok) {
} throw new EFhirClientException(response.message());
} else {
return null;
}
}
String body;
Resource resource = null; Resource resource = null;
try { try {
body = response.body().string();
String ct = response.header("Content-Type"); String ct = response.header("Content-Type");
if (ct == null) { if (ct == null) {
resource = getParser(format).parse(response.body().bytes()); if (ok) {
} else { resource = getParser(format).parse(body);
} else {
System.out.println("Got error response with no Content-Type from "+source+" with status "+code);
System.out.println(body);
resource = OperationOutcomeUtilities.outcomeFromTextError(body);
}
} else {
if (ct.contains(";")) {
ct = ct.substring(0, ct.indexOf(";"));
}
switch (ct) { switch (ct) {
case "application/json": case "application/json":
case "application/fhir+json": case "application/fhir+json":
resource = getParser(ResourceFormat.RESOURCE_JSON.getHeader()).parse(response.body().bytes()); if (!format.contains("json")) {
System.out.println("Got json response expecting "+format+" from "+source+" with status "+code);
}
resource = getParser(ResourceFormat.RESOURCE_JSON.getHeader()).parse(body);
break; break;
case "application/xml": case "application/xml":
case "application/fhir+xml": case "application/fhir+xml":
case "text/xml": case "text/xml":
resource = getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(response.body().bytes()); if (!format.contains("xml")) {
System.out.println("Got xml response expecting "+format+" from "+source+" with status "+code);
}
resource = getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(body);
break; break;
case "text/plain": case "text/plain":
resource = OperationOutcomeUtilities.outcomeFromTextError(response.body().string()); resource = OperationOutcomeUtilities.outcomeFromTextError(body);
break; break;
case "text/html" : case "text/html" :
resource = OperationOutcomeUtilities.outcomeFromTextError(XhtmlUtils.convertHtmlToText(response.body().string())); resource = OperationOutcomeUtilities.outcomeFromTextError(XhtmlUtils.convertHtmlToText(response.body().string(), source));
break; break;
default: // not sure what else to do? default: // not sure what else to do?
System.out.println("Got content-type '"+ct+"' from "+source); System.out.println("Got content-type '"+ct+"' from "+source);
resource = OperationOutcomeUtilities.outcomeFromTextError(response.body().string()); System.out.println(body);
resource = OperationOutcomeUtilities.outcomeFromTextError(body);
} }
} }
} catch (IOException ioe) { } catch (IOException ioe) {
@ -283,21 +308,26 @@ public class FhirRequestBuilder {
} catch (Exception e) { } catch (Exception e) {
throw new EFhirClientException("Error parsing response message from "+source+": "+e.getMessage(), e); throw new EFhirClientException("Error parsing response message from "+source+": "+e.getMessage(), e);
} }
if (resource instanceof OperationOutcome && !"OperationOutcome".equals(resourceType)) { if (resource instanceof OperationOutcome && (!"OperationOutcome".equals(resourceType) || !ok)) {
OperationOutcome error = (OperationOutcome) resource; OperationOutcome error = (OperationOutcome) resource;
if (hasError((OperationOutcome) resource)) { if (hasError((OperationOutcome) resource)) {
throw new EFhirClientException("Error from "+source+": " + ResourceUtilities.getErrorDescription(error), error); throw new EFhirClientException("Error from "+source+": " + ResourceUtilities.getErrorDescription(error), error);
} else { } else {
// umm, weird... // umm, weird...
System.out.println("Got OperationOutcome with no error from "+source+" with status "+code);
System.out.println(body);
return null;
} }
} }
if (resource == null) { if (resource == null) {
System.out.println("No resource from "+source+" with status "+code);
System.out.println(body);
return null; // shouldn't get here? return null; // shouldn't get here?
} }
if (resourceType != null && !resource.fhirType().equals(resourceType)) { if (resourceType != null && !resource.fhirType().equals(resourceType)) {
throw new EFhirClientException("Error parsing response message from "+source+": Found an "+resource.fhirType()+" looking for a "+resourceType); throw new EFhirClientException("Error parsing response message from "+source+": Found an "+resource.fhirType()+" looking for a "+resourceType);
} }
return (T) resource; return (T) resource;
} }
/** /**

View File

@ -251,34 +251,59 @@ public class FhirRequestBuilder {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T extends Resource> T unmarshalReference(Response response, String format, String resourceType) { protected <T extends Resource> T unmarshalReference(Response response, String format, String resourceType) {
int code = response.code();
boolean ok = code >= 200 && code < 300;
if (response.body() == null) { if (response.body() == null) {
return null; if (!ok) {
throw new EFhirClientException(response.message());
} else {
return null;
}
} }
String body;
Resource resource = null; Resource resource = null;
try { try {
body = response.body().string();
String ct = response.header("Content-Type"); String ct = response.header("Content-Type");
if (ct == null) { if (ct == null) {
resource = getParser(format).parse(response.body().bytes()); if (ok) {
resource = getParser(format).parse(body);
} else {
System.out.println("Got error response with no Content-Type from "+source+" with status "+code);
System.out.println(body);
resource = OperationOutcomeUtilities.outcomeFromTextError(body);
}
} else { } else {
if (ct.contains(";")) {
ct = ct.substring(0, ct.indexOf(";"));
}
switch (ct) { switch (ct) {
case "application/json": case "application/json":
case "application/fhir+json": case "application/fhir+json":
resource = getParser(ResourceFormat.RESOURCE_JSON.getHeader()).parse(response.body().bytes()); if (!format.contains("json")) {
System.out.println("Got json response expecting "+format+" from "+source+" with status "+code);
}
resource = getParser(ResourceFormat.RESOURCE_JSON.getHeader()).parse(body);
break; break;
case "application/xml": case "application/xml":
case "application/fhir+xml": case "application/fhir+xml":
case "text/xml": case "text/xml":
resource = getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(response.body().bytes()); if (!format.contains("xml")) {
System.out.println("Got xml response expecting "+format+" from "+source+" with status "+code);
}
resource = getParser(ResourceFormat.RESOURCE_XML.getHeader()).parse(body);
break; break;
case "text/plain": case "text/plain":
resource = OperationOutcomeUtilities.outcomeFromTextError(response.body().string()); resource = OperationOutcomeUtilities.outcomeFromTextError(body);
break; break;
case "text/html" : case "text/html" :
resource = OperationOutcomeUtilities.outcomeFromTextError(XhtmlUtils.convertHtmlToText(response.body().string())); resource = OperationOutcomeUtilities.outcomeFromTextError(XhtmlUtils.convertHtmlToText(response.body().string(), source));
break; break;
default: // not sure what else to do? default: // not sure what else to do?
System.out.println("Got content-type '"+ct+"' from "+source); System.out.println("Got content-type '"+ct+"' from "+source);
resource = OperationOutcomeUtilities.outcomeFromTextError(response.body().string()); System.out.println(body);
resource = OperationOutcomeUtilities.outcomeFromTextError(body);
} }
} }
} catch (IOException ioe) { } catch (IOException ioe) {
@ -286,15 +311,20 @@ public class FhirRequestBuilder {
} catch (Exception e) { } catch (Exception e) {
throw new EFhirClientException("Error parsing response message from "+source+": "+e.getMessage(), e); throw new EFhirClientException("Error parsing response message from "+source+": "+e.getMessage(), e);
} }
if (resource instanceof OperationOutcome && !"OperationOutcome".equals(resourceType)) { if (resource instanceof OperationOutcome && (!"OperationOutcome".equals(resourceType) || !ok)) {
OperationOutcome error = (OperationOutcome) resource; OperationOutcome error = (OperationOutcome) resource;
if (hasError((OperationOutcome) resource)) { if (hasError((OperationOutcome) resource)) {
throw new EFhirClientException("Error from "+source+": " + ResourceUtilities.getErrorDescription(error), error); throw new EFhirClientException("Error from "+source+": " + ResourceUtilities.getErrorDescription(error), error);
} else { } else {
// umm, weird... // umm, weird...
System.out.println("Got OperationOutcome with no error from "+source+" with status "+code);
System.out.println(body);
return null;
} }
} }
if (resource == null) { if (resource == null) {
System.out.println("No resource from "+source+" with status "+code);
System.out.println(body);
return null; // shouldn't get here? return null; // shouldn't get here?
} }
if (resourceType != null && !resource.fhirType().equals(resourceType)) { if (resourceType != null && !resource.fhirType().equals(resourceType)) {

View File

@ -348,7 +348,13 @@ public class XhtmlNode extends XhtmlFluent implements IBaseXhtml {
} }
} }
if (n.getNodeType() == NodeType.Element) { if (n.getNodeType() == NodeType.Element) {
b.append(n.allText()); if (!Utilities.existsInList(n.getName(), "img")) {
b.append(n.allText());
} else if (n.hasAttribute("alt")) {
b.append(n.getAttribute("alt"));
} else {
b.append("[image]");
}
if (Utilities.existsInList(n.getName(), "p", "div", "tr", "th", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6")) { if (Utilities.existsInList(n.getName(), "p", "div", "tr", "th", "ul", "ol", "li", "h1", "h2", "h3", "h4", "h5", "h6")) {
b.append("\r\n"); b.append("\r\n");
} else if (Utilities.existsInList(n.getName(), "th", "td", "span")) { } else if (Utilities.existsInList(n.getName(), "th", "td", "span")) {

View File

@ -2,13 +2,15 @@ package org.hl7.fhir.utilities.xhtml;
public class XhtmlUtils { public class XhtmlUtils {
public static String convertHtmlToText(String source) { public static String convertHtmlToText(String source, String desc) {
try { try {
XhtmlDocument doc = new XhtmlParser().parse(source, "html"); XhtmlDocument doc = new XhtmlParser().parse(source, "html");
return doc.getDocumentElement().allText(); return doc.getDocumentElement().allText();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
// todo - should we try another way? // todo - should we try another way?
System.err.println("XHTML content could not be parsed from "+desc);
e.printStackTrace();
System.err.println(source);
return "Unparseable HTML"; return "Unparseable HTML";
} }
} }