Add interceptor for syntax highlighting
This commit is contained in:
parent
7517709edb
commit
0f9d4b8059
|
@ -7,6 +7,7 @@ import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class ServletExamples {
|
public class ServletExamples {
|
||||||
|
@ -47,7 +48,7 @@ public class ServletExamples {
|
||||||
|
|
||||||
// ... define your resource providers here ...
|
// ... define your resource providers here ...
|
||||||
|
|
||||||
// Now register the logging interceptor
|
// Now register the interceptor
|
||||||
ExceptionHandlingInterceptor interceptor = new ExceptionHandlingInterceptor();
|
ExceptionHandlingInterceptor interceptor = new ExceptionHandlingInterceptor();
|
||||||
registerInterceptor(interceptor);
|
registerInterceptor(interceptor);
|
||||||
|
|
||||||
|
@ -59,4 +60,22 @@ public class ServletExamples {
|
||||||
}
|
}
|
||||||
// END SNIPPET: exceptionInterceptor
|
// END SNIPPET: exceptionInterceptor
|
||||||
|
|
||||||
|
// START SNIPPET: responseHighlighterInterceptor
|
||||||
|
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||||
|
public class RestfulServerWithResponseHighlighter extends RestfulServer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initialize() throws ServletException {
|
||||||
|
|
||||||
|
// ... define your resource providers here ...
|
||||||
|
|
||||||
|
// Now register the interceptor
|
||||||
|
ResponseHighlighterInterceptor interceptor = new ResponseHighlighterInterceptor();
|
||||||
|
registerInterceptor(interceptor);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// END SNIPPET: responseHighlighterInterceptor
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,8 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
||||||
// For POST the URL parameters get jumbled with the post body parameters so don't include them, they might be huge
|
// For POST the URL parameters get jumbled with the post body parameters so don't include them, they might be huge
|
||||||
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
|
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (Entry<String, String[]> nextParams : theRequest.getParameters().entrySet()) {
|
Map<String, String[]> parameters = theRequest.getParameters();
|
||||||
|
for (Entry<String, String[]> nextParams : parameters.entrySet()) {
|
||||||
for (String nextParamValue : nextParams.getValue()) {
|
for (String nextParamValue : nextParams.getValue()) {
|
||||||
if (first) {
|
if (first) {
|
||||||
b.append('?');
|
b.append('?');
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class RestfulServerUtils {
|
||||||
|
|
||||||
public static boolean prettyPrintResponse(RestfulServer theServer, RequestDetails theRequest) {
|
public static boolean prettyPrintResponse(RestfulServer theServer, RequestDetails theRequest) {
|
||||||
Map<String, String[]> requestParams = theRequest.getParameters();
|
Map<String, String[]> requestParams = theRequest.getParameters();
|
||||||
String[] pretty = requestParams.remove(Constants.PARAM_PRETTY);
|
String[] pretty = requestParams.get(Constants.PARAM_PRETTY);
|
||||||
boolean prettyPrint;
|
boolean prettyPrint;
|
||||||
if (pretty != null && pretty.length > 0) {
|
if (pretty != null && pretty.length > 0) {
|
||||||
if (Constants.PARAM_PRETTY_VALUE_TRUE.equals(pretty[0])) {
|
if (Constants.PARAM_PRETTY_VALUE_TRUE.equals(pretty[0])) {
|
||||||
|
@ -304,7 +304,7 @@ public class RestfulServerUtils {
|
||||||
|
|
||||||
public static RestfulServer.NarrativeModeEnum determineNarrativeMode(RequestDetails theRequest) {
|
public static RestfulServer.NarrativeModeEnum determineNarrativeMode(RequestDetails theRequest) {
|
||||||
Map<String, String[]> requestParams = theRequest.getParameters();
|
Map<String, String[]> requestParams = theRequest.getParameters();
|
||||||
String[] narrative = requestParams.remove(Constants.PARAM_NARRATIVE);
|
String[] narrative = requestParams.get(Constants.PARAM_NARRATIVE);
|
||||||
RestfulServer.NarrativeModeEnum narrativeMode = null;
|
RestfulServer.NarrativeModeEnum narrativeMode = null;
|
||||||
if (narrative != null && narrative.length > 0) {
|
if (narrative != null && narrative.length > 0) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.commons.lang3.StringEscapeUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
|
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||||
|
@ -153,11 +154,30 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
|
||||||
@Override
|
@Override
|
||||||
public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
|
public boolean outgoingResponse(RequestDetails theRequestDetails, IBaseResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's not a browser...
|
||||||
|
*/
|
||||||
String accept = theServletRequest.getHeader(Constants.HEADER_ACCEPT);
|
String accept = theServletRequest.getHeader(Constants.HEADER_ACCEPT);
|
||||||
if (accept == null || !accept.toLowerCase().contains("html")) {
|
if (accept == null || !accept.toLowerCase().contains("html")) {
|
||||||
return super.outgoingResponse(theRequestDetails, theResponseObject, theServletRequest, theServletResponse);
|
return super.outgoingResponse(theRequestDetails, theResponseObject, theServletRequest, theServletResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It's an AJAX request, so no HTML
|
||||||
|
*/
|
||||||
|
String requestedWith = theServletRequest.getHeader("X-Requested-With");
|
||||||
|
if (requestedWith != null) {
|
||||||
|
return super.outgoingResponse(theRequestDetails, theResponseObject, theServletRequest, theServletResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not a GET
|
||||||
|
*/
|
||||||
|
if (theRequestDetails.getRequestType() != RequestTypeEnum.GET) {
|
||||||
|
return super.outgoingResponse(theRequestDetails, theResponseObject, theServletRequest, theServletResponse);
|
||||||
|
}
|
||||||
|
|
||||||
// Pretty print
|
// Pretty print
|
||||||
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theRequestDetails.getServer(), theRequestDetails);
|
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theRequestDetails.getServer(), theRequestDetails);
|
||||||
|
|
||||||
|
|
|
@ -244,12 +244,6 @@
|
||||||
<version>${guava_version}</version>
|
<version>${guava_version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.derby</groupId>
|
|
||||||
<artifactId>derby</artifactId>
|
|
||||||
<version>${derby_version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-servlets</artifactId>
|
<artifactId>jetty-servlets</artifactId>
|
||||||
|
|
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
|
||||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
|
||||||
|
|
||||||
public class TestRestfulServer extends RestfulServer {
|
public class TestRestfulServer extends RestfulServer {
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ public class TestRestfulServer extends RestfulServer {
|
||||||
}
|
}
|
||||||
setResourceProviders(beans);
|
setResourceProviders(beans);
|
||||||
|
|
||||||
List provList = new ArrayList();
|
List<Object> provList = new ArrayList<Object>();
|
||||||
if (systemProviderDstu1 != null)
|
if (systemProviderDstu1 != null)
|
||||||
provList.add(systemProviderDstu1);
|
provList.add(systemProviderDstu1);
|
||||||
if (systemProviderDstu2 != null)
|
if (systemProviderDstu2 != null)
|
||||||
|
@ -128,12 +129,10 @@ public class TestRestfulServer extends RestfulServer {
|
||||||
setPlainProviders(provList);
|
setPlainProviders(provList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This tells the server to use "incorrect" MIME types if it detects that the
|
* We want to format the response using nice HTML if it's a browser, since this
|
||||||
* request is coming from a browser in the hopes that the browser won't just treat
|
* makes things a little easier for testers.
|
||||||
* the content as a binary payload and try to download it (which is what generally
|
|
||||||
* happens if you load a FHIR URL in a browser)
|
|
||||||
*/
|
*/
|
||||||
setUseBrowserFriendlyContentTypes(true);
|
registerInterceptor(new ResponseHighlighterInterceptor());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default to XML and pretty printing
|
* Default to XML and pretty printing
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class PlainProviderTest {
|
||||||
Patient patient = (Patient) bundle.getEntries().get(0).getResource();
|
Patient patient = (Patient) bundle.getEntries().get(0).getResource();
|
||||||
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
||||||
|
|
||||||
assertEquals(uri, bundle.getLinkSelf().getValue());
|
assertEquals(uri.replace(":hapitest:", "%3Ahapitest%3A"), bundle.getLinkSelf().getValue());
|
||||||
assertEquals(baseUri, bundle.getLinkBase().getValue());
|
assertEquals(baseUri, bundle.getLinkBase().getValue());
|
||||||
|
|
||||||
httpGet.releaseConnection();
|
httpGet.releaseConnection();
|
||||||
|
|
|
@ -134,7 +134,7 @@ public class RestfulServerSelfReferenceTest {
|
||||||
Patient patient = (Patient) bundle.getEntries().get(0).getResource();
|
Patient patient = (Patient) bundle.getEntries().get(0).getResource();
|
||||||
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
assertEquals("PatientOne", patient.getName().get(0).getGiven().get(0).getValue());
|
||||||
|
|
||||||
assertEquals(uri, bundle.getLinkSelf().getValue());
|
assertEquals(uri.replace(":hapitest:", "%3Ahapitest%3A"), bundle.getLinkSelf().getValue());
|
||||||
assertEquals(baseUri, bundle.getLinkBase().getValue());
|
assertEquals(baseUri, bundle.getLinkBase().getValue());
|
||||||
} finally {
|
} finally {
|
||||||
hServer.stop();
|
hServer.stop();
|
||||||
|
|
|
@ -42,6 +42,8 @@ public class SearchWithDstu2BundleTest {
|
||||||
|
|
||||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
|
responseContent = responseContent.replace("_pretty=true&_format=xml", "_format=xml&_pretty=true");
|
||||||
|
|
||||||
ourLog.info(responseContent);
|
ourLog.info(responseContent);
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
|
|
|
@ -79,12 +79,6 @@
|
||||||
<version>${jetty_version}</version>
|
<version>${jetty_version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-servlet</artifactId>
|
|
||||||
<version>${jetty_version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-util</artifactId>
|
<artifactId>jetty-util</artifactId>
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
The self link in the Bundle returned by searches on the server does not respect the
|
The self link in the Bundle returned by searches on the server does not respect the
|
||||||
server's address strategy (which resulted in an internal IP being shown on fhirtest.uhn.ca)
|
server's address strategy (which resulted in an internal IP being shown on fhirtest.uhn.ca)
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
Introduce ResponseHighlighterInterceptor, which provides syntax highlighting on RESTful server responses
|
||||||
|
if the server detects that the request is coming from a browser. This interceptor has been added
|
||||||
|
to fhirtest.uhn.ca responses.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="1.0" date="2015-May-8">
|
<release version="1.0" date="2015-May-8">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
|
@ -173,6 +173,29 @@
|
||||||
|
|
||||||
</subsection>
|
</subsection>
|
||||||
|
|
||||||
|
<subsection name="Response Syntax Highlighting">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The
|
||||||
|
<a href="./apidocs/ca/uhn/fhir/rest/server/interceptor/ResponseHighlighterInterceptor.html">ResponseHighlighterInterceptor</a>
|
||||||
|
(<a href="./xref/ca/uhn/fhir/rest/server/interceptor/ResponseHighlighterInterceptor.html">code</a>)
|
||||||
|
detects when a request is coming from a browser and returns HTML with syntax highlighted XML/JSON instead
|
||||||
|
of just the raw text. In other words, if a user uses a browser to request "http://foo/Patient/1" by typing
|
||||||
|
this address into their URL bar, they will get nice formatted HTML back with a human readable version
|
||||||
|
of the content. This is helpful for testers.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The following example shows how to register this interceptor within
|
||||||
|
a FHIR RESTful server.
|
||||||
|
</p>
|
||||||
|
<macro name="snippet">
|
||||||
|
<param name="id" value="responseHighlighterInterceptor" />
|
||||||
|
<param name="file" value="examples/src/main/java/example/ServletExamples.java" />
|
||||||
|
</macro>
|
||||||
|
|
||||||
|
</subsection>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section name="Creating Interceptors">
|
<section name="Creating Interceptors">
|
||||||
|
|
Loading…
Reference in New Issue