Class RestfulServer

java.lang.Object
jakarta.servlet.GenericServlet
jakarta.servlet.http.HttpServlet
ca.uhn.fhir.rest.server.RestfulServer
All Implemented Interfaces:
IRestfulServer<ServletRequestDetails>, IRestfulServerDefaults, jakarta.servlet.Servlet, jakarta.servlet.ServletConfig, Serializable

public class RestfulServer extends jakarta.servlet.http.HttpServlet implements IRestfulServer<ServletRequestDetails>
This class is the central class for the HAPI FHIR Plain Server framework.

See HAPI FHIR Plain Server for information on how to use this framework.

See Also:
  • Field Details

  • Constructor Details

    • RestfulServer

      public RestfulServer()
      Constructor. Note that if no FhirContext is passed in to the server (either through the constructor, or through setFhirContext(FhirContext)) the server will determine which version of FHIR to support through classpath scanning. This is brittle, and it is highly recommended to explicitly specify a FHIR version.
    • RestfulServer

      public RestfulServer(ca.uhn.fhir.context.FhirContext theCtx)
      Constructor
    • RestfulServer

      public RestfulServer(ca.uhn.fhir.context.FhirContext theCtx, ca.uhn.fhir.interceptor.api.IInterceptorService theInterceptorService)
  • Method Details

    • getServerConformanceMethod

      Since:
      5.5.0
    • addHeadersToResponse

      public void addHeadersToResponse(jakarta.servlet.http.HttpServletResponse theHttpResponse)
      This method is called prior to sending a response to incoming requests. It is used to add custom headers.

      Use caution if overriding this method: it is recommended to call super.addHeadersToResponse to avoid inadvertently disabling functionality.

    • createConfiguration

    • createPoweredByAttributes

    • createPoweredByHeader

      Subclasses may override to provide their own powered by header. Note that if you want to be nice and still credit HAPI FHIR you could consider overriding createPoweredByAttributes() instead and adding your own fragments to the list.
    • createPoweredByHeaderComponentName

      Subclasses my override
      See Also:
    • createPoweredByHeaderProductName

      Subclasses my override
      See Also:
    • createPoweredByHeaderProductVersion

      Subclasses my override
      See Also:
    • destroy

      public void destroy()
      Specified by:
      destroy in interface jakarta.servlet.Servlet
      Overrides:
      destroy in class jakarta.servlet.GenericServlet
    • determineResourceMethod

      public BaseMethodBinding determineResourceMethod(RequestDetails requestDetails, String requestPath)
      Figure out and return whichever method binding is appropriate for the given request
    • doDelete

      protected void doDelete(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doDelete in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
    • doGet

      protected void doGet(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doGet in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
    • doOptions

      protected void doOptions(jakarta.servlet.http.HttpServletRequest theReq, jakarta.servlet.http.HttpServletResponse theResp) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doOptions in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
    • doPost

      protected void doPost(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doPost in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
    • doPut

      protected void doPut(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doPut in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
    • getAddProfileTag

      @Deprecated public ca.uhn.fhir.context.api.AddProfileTagEnum getAddProfileTag()
      Deprecated.
      As of HAPI FHIR 1.5, this property has been moved to FhirContext.setAddProfileTagWhenEncoding(AddProfileTagEnum)
      Specified by:
      getAddProfileTag in interface IRestfulServerDefaults
      Returns:
      Returns the setting for automatically adding profile tags
    • setAddProfileTag

      @Deprecated public void setAddProfileTag(ca.uhn.fhir.context.api.AddProfileTagEnum theAddProfileTag)
      Deprecated.
      As of HAPI FHIR 1.5, this property has been moved to FhirContext.setAddProfileTagWhenEncoding(AddProfileTagEnum)
      Sets the profile tagging behaviour for the server. When set to a value other than AddProfileTagEnum.NEVER (which is the default), the server will automatically add a profile tag based on the class of the resource(s) being returned.
      Parameters:
      theAddProfileTag - The behaviour enum (must not be null)
    • getBundleInclusionRule

      public ca.uhn.fhir.context.api.BundleInclusionRule getBundleInclusionRule()
      Specified by:
      getBundleInclusionRule in interface IRestfulServer<ServletRequestDetails>
    • setBundleInclusionRule

      public void setBundleInclusionRule(ca.uhn.fhir.context.api.BundleInclusionRule theBundleInclusionRule)
      Set how bundle factory should decide whether referenced resources should be included in bundles
      Parameters:
      theBundleInclusionRule - - inclusion rule (@see BundleInclusionRule for behaviors)
    • getDefaultResponseEncoding

      public ca.uhn.fhir.rest.api.EncodingEnum getDefaultResponseEncoding()
      Returns the default encoding to return (XML/JSON) if an incoming request does not specify a preference (either with the _format URL parameter, or with an Accept header in the request. The default is EncodingEnum.XML. Will not return null.
      Specified by:
      getDefaultResponseEncoding in interface IRestfulServerDefaults
      Returns:
      Returns the default encoding to return (XML/JSON) if an incoming request does not specify a preference (either with the _format URL parameter, or with an Accept header in the request. The default is EncodingEnum.XML. Will not return null.
    • setDefaultResponseEncoding

      public void setDefaultResponseEncoding(ca.uhn.fhir.rest.api.EncodingEnum theDefaultResponseEncoding)
      Sets the default encoding to return (XML/JSON) if an incoming request does not specify a preference (either with the _format URL parameter, or with an Accept header in the request. The default is EncodingEnum.XML.

      Note when testing this feature: Some browsers will include "application/xml" in their Accept header, which means that the

    • getETagSupport

      Specified by:
      getETagSupport in interface IRestfulServerDefaults
      Returns:
      Returns the server support for ETags (will not be null). Default is DEFAULT_ETAG_SUPPORT
    • setETagSupport

      public void setETagSupport(ETagSupportEnum theETagSupport)
      Sets (enables/disables) the server support for ETags. Must not be null. Default is DEFAULT_ETAG_SUPPORT
      Parameters:
      theETagSupport - The ETag support mode
    • getElementsSupport

      Specified by:
      getElementsSupport in interface IRestfulServerDefaults
      Returns:
      Returns the support option for the _elements parameter on search and read operations.
      See Also:
    • setElementsSupport

      public void setElementsSupport(ElementsSupportEnum theElementsSupport)
      Sets the elements support mode.
      See Also:
    • getFhirContext

      public ca.uhn.fhir.context.FhirContext getFhirContext()
      Gets the FhirContext associated with this server. For efficient processing, resource providers and plain providers should generally use this context if one is needed, as opposed to creating their own.
      Specified by:
      getFhirContext in interface IRestfulServerDefaults
    • setFhirContext

      public void setFhirContext(ca.uhn.fhir.context.FhirContext theFhirContext)
    • getImplementationDescription

    • setImplementationDescription

      public void setImplementationDescription(String theImplementationDescription)
    • getCopyright

      public String getCopyright()
      Returns the server copyright (will be added to the CapabilityStatement). Note that FHIR allows Markdown in this string.
    • setCopyright

      public void setCopyright(String theCopyright)
      Sets the server copyright (will be added to the CapabilityStatement). Note that FHIR allows Markdown in this string.
    • getInterceptors_

      Deprecated.
      As of HAPI FHIR 3.8.0, use getInterceptorService() to access the interceptor service. You can register and unregister interceptors using this service.
      Returns a list of all registered server interceptors
      Specified by:
      getInterceptors_ in interface IRestfulServerDefaults
    • getInterceptorService

      public ca.uhn.fhir.interceptor.api.IInterceptorService getInterceptorService()
      Returns the interceptor registry for this service. Use this registry to register and unregister
      Specified by:
      getInterceptorService in interface IRestfulServerDefaults
      Since:
      3.8.0
    • setInterceptorService

      public void setInterceptorService(@Nonnull ca.uhn.fhir.interceptor.api.IInterceptorService theInterceptorService)
      Sets the interceptor registry for this service. Use this registry to register and unregister
      Since:
      3.8.0
    • setInterceptors

      @Deprecated public void setInterceptors(@Nonnull List<?> theList)
      Deprecated.
      As of HAPI FHIR 3.8.0, use getInterceptorService() to access the interceptor service. You can register and unregister interceptors using this service.
      Sets (or clears) the list of interceptors
      Parameters:
      theList - The list of interceptors (may be null)
    • setInterceptors

      @Deprecated public void setInterceptors(IServerInterceptor... theInterceptors)
      Deprecated.
      As of HAPI FHIR 3.8.0, use getInterceptorService() to access the interceptor service. You can register and unregister interceptors using this service.
      Sets (or clears) the list of interceptors
      Parameters:
      theInterceptors - The list of interceptors (may be null)
    • getPagingProvider

      Description copied from interface: IRestfulServerDefaults
      Returns the paging provider for this server
      Specified by:
      getPagingProvider in interface IRestfulServer<ServletRequestDetails>
      Specified by:
      getPagingProvider in interface IRestfulServerDefaults
    • setPagingProvider

      public void setPagingProvider(IPagingProvider thePagingProvider)
      Sets the paging provider to use, or null to use no paging (which is the default). This will set defaultPageSize and maximumPageSize from the paging provider.
    • getDefaultPageSize

      Description copied from interface: IRestfulServerDefaults
      Default page size for searches. Null means no limit (JpaStorageSettings might have size limit however)
      Specified by:
      getDefaultPageSize in interface IRestfulServerDefaults
    • setDefaultPageSize

      public void setDefaultPageSize(Integer thePageSize)
      Sets the default page size to use, or null if no default page size
    • getMaximumPageSize

      Description copied from interface: IRestfulServerDefaults
      Maximum page size for searches. Null means no upper limit.
      Specified by:
      getMaximumPageSize in interface IRestfulServerDefaults
    • setMaximumPageSize

      public void setMaximumPageSize(Integer theMaximumPageSize)
      Sets the maximum page size to use, or null if no maximum page size
    • getPlainProviders

      Provides the non-resource specific providers which implement method calls on this server
      See Also:
    • setPlainProviders

      @Deprecated public void setPlainProviders(Object... theProv)
      Deprecated.
      This method causes inconsistent behaviour depending on the order it is called in. Use registerProviders(Object...) instead.
      Sets the non-resource specific providers which implement method calls on this server.
      See Also:
    • setPlainProviders

      @Deprecated public void setPlainProviders(Collection<Object> theProviders)
      Deprecated.
      This method causes inconsistent behaviour depending on the order it is called in. Use registerProviders(Object...) instead.
      Sets the non-resource specific providers which implement method calls on this server.
      See Also:
    • getRequestPath

      protected String getRequestPath(String requestFullPath, String servletContextPath, String servletPath)
      Allows users of RestfulServer to override the getRequestPath method to let them build their custom request path implementation
      Parameters:
      requestFullPath - the full request path
      servletContextPath - the servelet context path
      servletPath - the servelet path
      Returns:
      created resource path
    • getResourceBindings

    • getProviderMethodBindings

    • getResourceProviders

      Provides the resource providers for this server
    • setResourceProviders

      public void setResourceProviders(IResourceProvider... theResourceProviders)
      Sets the resource providers for this server
    • setResourceProviders

      public void setResourceProviders(Collection<IResourceProvider> theProviders)
      Sets the resource providers for this server
    • getServerAddressStrategy

      Get the server address strategy, which is used to determine what base URL to provide clients to refer to this server. Defaults to an instance of IncomingRequestAddressStrategy
    • setServerAddressStrategy

      public void setServerAddressStrategy(IServerAddressStrategy theServerAddressStrategy)
      Provide a server address strategy, which is used to determine what base URL to provide clients to refer to this server. Defaults to an instance of IncomingRequestAddressStrategy
    • getServerBaseForRequest

      Returns the server base URL (with no trailing '/') for a given request
    • getServerBindings

      Returns the method bindings for this server which are not specific to any particular resource type. This method is internal to HAPI and developers generally do not need to interact with it. Use with caution, as it may change.
    • getServerConformanceProvider

      Returns the server conformance provider, which is the provider that is used to generate the server's conformance (metadata) statement if one has been explicitly defined.

      By default, the ServerConformanceProvider for the declared version of FHIR is used, but this can be changed, or set to null to use the appropriate one for the given FHIR version.

    • setServerConformanceProvider

      public void setServerConformanceProvider(@Nonnull Object theServerConformanceProvider)
      Returns the server conformance provider, which is the provider that is used to generate the server's conformance (metadata) statement.

      By default, the ServerConformanceProvider implementation for the declared version of FHIR is used, but this can be changed, or set to null if you do not wish to export a conformance statement.

      This method should only be called before the server is initialized. Calling it after the server has started is allowed, but you should be very careful in this case that you only call it while no traffic is hitting the server.
      Throws:
      IllegalStateException - Note that this method can only be called prior to initialization and will throw an IllegalStateException if called after that.
    • getServerName

      Gets the server's name, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
      See Also:
    • setServerName

      public void setServerName(String theServerName)
      Sets the server's name, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
    • getServerVersion

      Gets the server's version, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
    • setServerVersion

      public void setServerVersion(String theServerVersion)
      Gets the server's version, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
    • handleRequest

      protected void handleRequest(ca.uhn.fhir.rest.api.RequestTypeEnum theRequestType, jakarta.servlet.http.HttpServletRequest theRequest, jakarta.servlet.http.HttpServletResponse theResponse) throws jakarta.servlet.ServletException, IOException
      Throws:
      jakarta.servlet.ServletException
      IOException
    • newRequestDetails

      @Nonnull protected ServletRequestDetails newRequestDetails(ca.uhn.fhir.rest.api.RequestTypeEnum theRequestType, jakarta.servlet.http.HttpServletRequest theRequest, jakarta.servlet.http.HttpServletResponse theResponse)
      Subclasses may override this to customize the way that the RequestDetails object is created. Generally speaking, the right way to do this is to override this method, but call the super-implementation (super.newRequestDetails) and then customize the returned object before returning it.
      Parameters:
      theRequestType - The HTTP request verb
      theRequest - The servlet request
      theResponse - The servlet response
      Returns:
      A ServletRequestDetails instance to be passed to any resource providers, interceptors, etc. that are invoked as a part of serving this request.
    • newRequestDetails

      Deprecated.
      Deprecated in HAPI FHIR 4.1.0 - Users wishing to override this method should override newRequestDetails(RequestTypeEnum, HttpServletRequest, HttpServletResponse) instead
    • addRequestIdToResponse

      protected void addRequestIdToResponse(ServletRequestDetails theRequestDetails, String theRequestId)
    • getOrCreateRequestId

      protected String getOrCreateRequestId(jakarta.servlet.http.HttpServletRequest theRequest)
      Reads a request ID from the request headers via the Constants.HEADER_REQUEST_ID header, or generates one if none is supplied.

      Note that the generated request ID is a random 64-bit long integer encoded as hexadecimal. It is not generated using any cryptographic algorithms or a secure PRNG, so it should not be used for anything other than troubleshooting purposes.

    • newRequestId

      protected String newRequestId(int theRequestIdLength)
      Generate a new request ID string. Subclasses may ovrride.
    • validateRequest

      protected void validateRequest(ServletRequestDetails theRequestDetails)
    • init

      public final void init() throws jakarta.servlet.ServletException
      Initializes the server. Note that this method is final to avoid accidentally introducing bugs in implementations, but subclasses may put initialization code in initialize(), which is called immediately before beginning initialization of the restful server's internal init.
      Overrides:
      init in class jakarta.servlet.GenericServlet
      Throws:
      jakarta.servlet.ServletException
    • initialize

      protected void initialize() throws jakarta.servlet.ServletException
      This method may be overridden by subclasses to do perform initialization that needs to be performed prior to the server being used.
      Throws:
      jakarta.servlet.ServletException - If the initialization failed. Note that you should consider throwing UnavailableException (which extends ServletException), as this is a flag to the servlet container that the servlet is not usable.
    • isDefaultPrettyPrint

      public boolean isDefaultPrettyPrint()
      Should the server "pretty print" responses by default (requesting clients can always override this default by supplying an Accept header in the request, or a _pretty parameter in the request URL.

      The default is false

      Note that this setting is ignored by ResponseHighlighterInterceptor when streaming HTML, although even when that interceptor it used this setting will still be honoured when streaming raw FHIR.

      Specified by:
      isDefaultPrettyPrint in interface IRestfulServerDefaults
      Returns:
      Returns the default pretty print setting
    • setDefaultPrettyPrint

      public void setDefaultPrettyPrint(boolean theDefaultPrettyPrint)
      Should the server "pretty print" responses by default (requesting clients can always override this default by supplying an Accept header in the request, or a _pretty parameter in the request URL.

      The default is false

      Note that this setting is ignored by ResponseHighlighterInterceptor when streaming HTML, although even when that interceptor it used this setting will still be honoured when streaming raw FHIR.

      Parameters:
      theDefaultPrettyPrint - The default pretty print setting
    • isIgnoreServerParsedRequestParameters

      If set to true (the default is true) this server will not use the parsed request parameters (URL parameters and HTTP POST form contents) but will instead parse these values manually from the request URL and request body.

      This is useful because many servlet containers (e.g. Tomcat, Glassfish) will use ISO-8859-1 encoding to parse escaped URL characters instead of using UTF-8 as is specified by FHIR.

    • setIgnoreServerParsedRequestParameters

      public void setIgnoreServerParsedRequestParameters(boolean theIgnoreServerParsedRequestParameters)
      If set to true (the default is true) this server will not use the parsed request parameters (URL parameters and HTTP POST form contents) but will instead parse these values manually from the request URL and request body.

      This is useful because many servlet containers (e.g. Tomcat, Glassfish) will use ISO-8859-1 encoding to parse escaped URL characters instead of using UTF-8 as is specified by FHIR.

    • isUncompressIncomingContents

      public boolean isUncompressIncomingContents()
      Should the server attempt to decompress incoming request contents (default is true). Typically this should be set to true unless the server has other configuration to deal with decompressing request bodies (e.g. a filter applied to the whole server).
    • setUncompressIncomingContents

      public void setUncompressIncomingContents(boolean theUncompressIncomingContents)
      Should the server attempt to decompress incoming request contents (default is true). Typically this should be set to true unless the server has other configuration to deal with decompressing request bodies (e.g. a filter applied to the whole server).
    • populateRequestDetailsFromRequestPath

      public void populateRequestDetailsFromRequestPath(RequestDetails theRequestDetails, String theRequestPath)
    • registerInterceptor

      public void registerInterceptor(Object theInterceptor)
      Registers an interceptor. This method is a convenience method which calls getInterceptorService().registerInterceptor(theInterceptor);
      Parameters:
      theInterceptor - The interceptor, must not be null
    • registerProvider

      public void registerProvider(Object provider)
      Register a single provider. This could be a Resource Provider or a "plain" provider not associated with any resource.
    • registerProviders

      public void registerProviders(Object... theProviders)
      Register a group of providers. These could be Resource Providers (classes implementing IResourceProvider) or "plain" providers, or a mixture of the two.
      Parameters:
      theProviders - a Collection of theProviders. The parameter could be null or an empty Collection
    • registerProviders

      public void registerProviders(Collection<?> theProviders)
      Register a group of theProviders. These could be Resource Providers, "plain" theProviders or a mixture of the two.
      Parameters:
      theProviders - a Collection of theProviders. The parameter could be null or an empty Collection
    • registerProviders

      protected void registerProviders(@Nullable Collection<?> theProviders, boolean inInit)
    • returnResponse

      public Object returnResponse(ServletRequestDetails theRequest, BaseParseAction<?> outcome, int operationStatus, boolean allowPrefer, ca.uhn.fhir.rest.api.MethodOutcome response, String resourceName) throws IOException
      Throws:
      IOException
    • service

      protected void service(jakarta.servlet.http.HttpServletRequest theReq, jakarta.servlet.http.HttpServletResponse theResp) throws jakarta.servlet.ServletException, IOException
      Overrides:
      service in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
    • setProviders

      public void setProviders(Object... theProviders)
      Sets the non-resource specific providers which implement method calls on this server
      See Also:
    • setTenantIdentificationStrategy

      public void setTenantIdentificationStrategy(ITenantIdentificationStrategy theTenantIdentificationStrategy)
      If provided (default is null), the tenant identification strategy provides a mechanism for a multitenant server to identify which tenant a given request corresponds to.
    • throwUnknownFhirOperationException

      protected void throwUnknownFhirOperationException(RequestDetails requestDetails, String requestPath, ca.uhn.fhir.rest.api.RequestTypeEnum theRequestType)
    • throwUnknownResourceTypeException

      protected void throwUnknownResourceTypeException(String theResourceName)
    • unregisterInterceptor

      public void unregisterInterceptor(Object theInterceptor)
      Unregisters an interceptor. This method is a convenience method which calls getInterceptorService().unregisterInterceptor(theInterceptor);
      Parameters:
      theInterceptor - The interceptor, must not be null
    • unregisterProvider

      public void unregisterProvider(Object provider)
      Unregister one provider (either a Resource provider or a plain provider)
    • unregisterProviders

      public void unregisterProviders(Collection<?> providers)
      Unregister a Collection of providers
    • unregisterAllProviders

      public void unregisterAllProviders()
      Unregisters all plain and resource providers (but not the conformance provider).
    • getDefaultPreferReturn

      public ca.uhn.fhir.rest.api.PreferReturnEnum getDefaultPreferReturn()
      By default, server create/update/patch/transaction methods return a copy of the resource as it was stored. This may be overridden by the client using the Prefer header.

      This setting changes the default behaviour if no Prefer header is supplied by the client. The default is PreferReturnEnum.REPRESENTATION

      Specified by:
      getDefaultPreferReturn in interface IRestfulServer<ServletRequestDetails>
      See Also:
    • setDefaultPreferReturn

      public void setDefaultPreferReturn(ca.uhn.fhir.rest.api.PreferReturnEnum theDefaultPreferReturn)
      By default, server create/update/patch/transaction methods return a copy of the resource as it was stored. This may be overridden by the client using the Prefer header.

      This setting changes the default behaviour if no Prefer header is supplied by the client. The default is PreferReturnEnum.REPRESENTATION

      See Also:
    • getCapabilityStatement

      public org.hl7.fhir.instance.model.api.IBaseConformance getCapabilityStatement(ServletRequestDetails theRequestDetails)
      Create a CapabilityStatement based on the given request
    • escapedLength

      protected static int escapedLength(String theServletPath)
      Count length of URL string, but treating unescaped sequences (e.g. ' ') as their unescaped equivalent (%20)
    • throwUnknownFhirOperationException

      public static void throwUnknownFhirOperationException(RequestDetails requestDetails, String requestPath, ca.uhn.fhir.rest.api.RequestTypeEnum theRequestType, ca.uhn.fhir.context.FhirContext theFhirContext)