Added example using embedded Jetty and Guice - meaning its way more easy to debug and 'deploy'
This commit is contained in:
parent
43f21c0dcf
commit
ba9d951053
|
@ -0,0 +1,47 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>1.2</version>
|
||||
</parent>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<artifactId>hapi-fhir-base-example-embedded-ws</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-servlet</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-webapp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-servlet</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-guice</artifactId>
|
||||
<version>1.18.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-dstu2</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,37 @@
|
|||
package embedded;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.servlet.GuiceServletContextListener;
|
||||
import com.sun.jersey.api.container.filter.GZIPContentEncodingFilter;
|
||||
import com.sun.jersey.api.core.ResourceConfig;
|
||||
import com.sun.jersey.guice.JerseyServletModule;
|
||||
|
||||
import filters.CharsetResponseFilter;
|
||||
import filters.CorsResponseFilter;
|
||||
|
||||
public class ContextListener extends GuiceServletContextListener {
|
||||
|
||||
@Override
|
||||
protected Injector getInjector() {
|
||||
|
||||
return Guice.createInjector(new JerseyServletModule() {
|
||||
|
||||
@Override
|
||||
protected void configureServlets() {
|
||||
final Map<String, String> params = ImmutableMap
|
||||
.<String, String> builder()
|
||||
.put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS,
|
||||
Joiner.on(";").join(
|
||||
CharsetResponseFilter.class.getName(),
|
||||
CorsResponseFilter.class.getName(),
|
||||
GZIPContentEncodingFilter.class
|
||||
.getName())).build();
|
||||
serve("/model/*").with(FhirRestfulServlet.class, params);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package embedded;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.narrative.INarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
|
||||
|
||||
@Singleton
|
||||
public class FhirRestfulServlet extends RestfulServer {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -3931111342737918913L;
|
||||
|
||||
public FhirRestfulServlet() {
|
||||
super(FhirContext.forDstu2()); // Support DSTU2
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called automatically when the servlet is initializing.
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
/*
|
||||
* Two resource providers are defined. Each one handles a specific type
|
||||
* of resource.
|
||||
*/
|
||||
final List<IResourceProvider> providers = new ArrayList<IResourceProvider>();
|
||||
providers.add(new SomeResourceProvider());
|
||||
setResourceProviders(providers);
|
||||
|
||||
/*
|
||||
* Use a narrative generator. This is a completely optional step, but
|
||||
* can be useful as it causes HAPI to generate narratives for resources
|
||||
* which don't otherwise have one.
|
||||
*/
|
||||
final INarrativeGenerator narrativeGen = new DefaultThymeleafNarrativeGenerator();
|
||||
getFhirContext().setNarrativeGenerator(narrativeGen);
|
||||
|
||||
/*
|
||||
* Tells HAPI to use content types which are not technically FHIR
|
||||
* compliant when a browser is detected as the requesting client. This
|
||||
* prevents browsers from trying to download resource responses instead
|
||||
* of displaying them inline which can be handy for troubleshooting.
|
||||
*/
|
||||
setUseBrowserFriendlyContentTypes(true);
|
||||
|
||||
registerInterceptor(new ResponseHighlighterInterceptor());
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package embedded;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.DefaultServlet;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
|
||||
import com.google.inject.servlet.GuiceFilter;
|
||||
|
||||
public class ServerStartup {
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
|
||||
final Server server = new Server(9090);
|
||||
final ServletContextHandler sch = new ServletContextHandler(server, "/");
|
||||
sch.addEventListener(new ContextListener());
|
||||
sch.addFilter(GuiceFilter.class, "/*",
|
||||
EnumSet.of(DispatcherType.REQUEST));
|
||||
sch.addServlet(DefaultServlet.class, "/");
|
||||
server.start();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package embedded;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
|
||||
public class SomeResourceProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Practitioner.class;
|
||||
}
|
||||
|
||||
@Search()
|
||||
public List<Practitioner> findPractitionersByName(
|
||||
@RequiredParam(name = Practitioner.SP_NAME) final StringDt theName) {
|
||||
throw new UnprocessableEntityException(
|
||||
"Please provide more than 4 characters for the name");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package filters;
|
||||
|
||||
|
||||
import javax.ws.rs.core.HttpHeaders;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import com.sun.jersey.spi.container.ContainerRequest;
|
||||
import com.sun.jersey.spi.container.ContainerResponse;
|
||||
import com.sun.jersey.spi.container.ContainerResponseFilter;
|
||||
|
||||
public class CharsetResponseFilter implements ContainerResponseFilter {
|
||||
|
||||
@Override
|
||||
public ContainerResponse filter(final ContainerRequest request,
|
||||
final ContainerResponse response) {
|
||||
|
||||
final MediaType contentType = response.getMediaType();
|
||||
if (contentType != null) {
|
||||
response.getHttpHeaders().putSingle(HttpHeaders.CONTENT_TYPE,
|
||||
contentType.toString() + ";charset=UTF-8");
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package filters;
|
||||
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.ResponseBuilder;
|
||||
|
||||
import com.sun.jersey.spi.container.ContainerRequest;
|
||||
import com.sun.jersey.spi.container.ContainerResponse;
|
||||
import com.sun.jersey.spi.container.ContainerResponseFilter;
|
||||
|
||||
public class CorsResponseFilter implements ContainerResponseFilter {
|
||||
|
||||
@Override
|
||||
public ContainerResponse filter(final ContainerRequest req,
|
||||
final ContainerResponse contResp) {
|
||||
|
||||
final ResponseBuilder resp = Response.fromResponse(contResp
|
||||
.getResponse());
|
||||
resp.header("Access-Control-Allow-Origin", "*").header(
|
||||
"Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
||||
|
||||
final String reqHead = req
|
||||
.getHeaderValue("Access-Control-Request-Headers");
|
||||
|
||||
if (null != reqHead && !reqHead.equals("")) {
|
||||
resp.header("Access-Control-Allow-Headers", reqHead);
|
||||
}
|
||||
|
||||
contResp.setResponse(resp.build());
|
||||
return contResp;
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,11 @@
|
|||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
|
|
Loading…
Reference in New Issue