Last active
August 11, 2017 07:13
-
-
Save ben-manes/af6ab5e857f29f55d990 to your computer and use it in GitHub Desktop.
Swagger 1.5.1-M1 + RestEasy 3.x + Guice 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import javax.servlet.Filter; | |
import javax.servlet.FilterChain; | |
import javax.servlet.FilterConfig; | |
import javax.servlet.ServletException; | |
import javax.servlet.ServletRequest; | |
import javax.servlet.ServletResponse; | |
import javax.servlet.http.HttpServletResponse; | |
import com.google.inject.Singleton; | |
/** | |
* Allow CORS for Swagger specification api. | |
* | |
* @author ben.manes@gmail.com (Ben Manes) | |
*/ | |
@Singleton | |
final class ApiOriginFilter implements Filter { | |
@Override | |
public void doFilter(ServletRequest request, ServletResponse response, | |
FilterChain chain) throws IOException, ServletException { | |
HttpServletResponse res = (HttpServletResponse) response; | |
res.addHeader("Access-Control-Allow-Origin", "*"); | |
res.addHeader("Access-Control-Allow-Headers", "Content-Type"); | |
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); | |
chain.doFilter(request, response); | |
} | |
@Override | |
public void destroy() {} | |
@Override | |
public void init(FilterConfig filterConfig) throws ServletException {} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies { | |
compile dependencies.create('com.wordnik:swagger-jersey2-jaxrs:1.5.1-M1') { | |
exclude group: 'org.glassfish.jersey.containers' | |
exclude group: 'org.glassfish.jersey.media' | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.HashSet; | |
import java.util.Set; | |
import org.reflections.Reflections; | |
import org.reflections.scanners.ResourcesScanner; | |
import org.reflections.scanners.SubTypesScanner; | |
import org.reflections.scanners.TypeAnnotationsScanner; | |
import org.reflections.util.ClasspathHelper; | |
import org.reflections.util.ConfigurationBuilder; | |
import com.wordnik.swagger.annotations.Api; | |
import com.wordnik.swagger.jaxrs.config.BeanConfig; | |
import com.wordnik.swagger.models.Contact; | |
import com.wordnik.swagger.models.Info; | |
import com.wordnik.swagger.models.License; | |
/** | |
* A {@link BeanConfig} that supports multiple resource packages. This can be removed in Swagger M2 | |
* where this enhancement is supported (and directly ported from). | |
* | |
* @author ben.manes@gmail.com (Ben Manes) | |
*/ | |
final class ResourceConfig extends BeanConfig { | |
@Override | |
public Set<Class<?>> classes() { | |
ConfigurationBuilder config = new ConfigurationBuilder(); | |
Set<String> acceptablePackages = new HashSet<String>(); | |
if (getResourcePackage() != "") { | |
String[] parts = getResourcePackage().split(","); | |
for (String pkg : parts) { | |
if (!"".equals(pkg)) { | |
acceptablePackages.add(pkg); | |
config.addUrls(ClasspathHelper.forPackage(pkg)); | |
} | |
} | |
} | |
config.setScanners(new ResourcesScanner(), | |
new TypeAnnotationsScanner(), new SubTypesScanner()); | |
setInfo(new Info() | |
.title(getTitle()) | |
.version(getVersion()) | |
.description(getDescription()) | |
.termsOfService(getTermsOfServiceUrl())); | |
if (getContact() != null) { | |
getInfo().contact(new Contact().name(getContact())); | |
} | |
if ((getLicense() != null) && (getLicenseUrl() != null)) { | |
getInfo().license(new License().name(getLicense()).url(getLicenseUrl())); | |
} | |
getSwagger().setInfo(getInfo()); | |
Set<Class<?>> classes = new Reflections(config).getTypesAnnotatedWith(Api.class); | |
Set<Class<?>> output = new HashSet<Class<?>>(); | |
for (Class<?> cls : classes) { | |
if (acceptablePackages.contains(cls.getPackage().getName())) { | |
output.add(cls); | |
} | |
} | |
return output; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.servlet.ServletContextListener; | |
import com.google.inject.multibindings.Multibinder; | |
import com.google.inject.servlet.ServletModule; | |
import com.wordnik.swagger.jaxrs.listing.ApiListingResource; | |
import com.wordnik.swagger.jaxrs.listing.SwaggerSerializers; | |
/** | |
* A module to install <a href="http://swagger.io">Swagger</a> with JAX-RS scanning. | |
* | |
* @author ben.manes@gmail.com (Ben Manes) | |
*/ | |
public final class SwaggerModule extends ServletModule { | |
@Override | |
protected void configureServlets() { | |
Multibinder.newSetBinder(binder(), ServletContextListener.class) | |
.addBinding().to(SwaggerServletContextListener.class); | |
bind(SwaggerApiListingResource.class); | |
bind(SwaggerSerializers.class); | |
filter("/api/*").through(ApiOriginFilter.class); | |
} | |
@Path("/api") | |
static final class SwaggerApiListingResource extends ApiListingResourceJSON {} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.stream.Collectors; | |
import javax.annotation.Nullable; | |
import javax.servlet.ServletContextEvent; | |
import javax.servlet.ServletContextListener; | |
import org.jboss.resteasy.util.GetRestful; | |
import com.google.inject.Inject; | |
import com.google.inject.Injector; | |
import com.typesafe.config.Config; | |
import com.typesafe.config.ConfigFactory; | |
import com.wordnik.swagger.config.ScannerFactory; | |
import com.wordnik.swagger.jaxrs.config.BeanConfig; | |
/** | |
* A context listener that scans for APIs and configures Swagger. | |
* | |
* @author ben.manes@gmail.com (Ben Manes) | |
*/ | |
final class SwaggerServletContextListener implements ServletContextListener { | |
private final Config config = ConfigFactory.load().getConfig(getClass().getPackage().getName()); | |
private final Injector injector; | |
@Inject | |
SwaggerServletContextListener(Injector injector) { | |
this.injector = injector; | |
} | |
@Override | |
public void contextInitialized(ServletContextEvent event) { | |
BeanConfig beanConfig = getBeanConfig(); | |
event.getServletContext().setAttribute("reader", beanConfig); | |
event.getServletContext().setAttribute("swagger", beanConfig.getSwagger()); | |
event.getServletContext().setAttribute("scanner", ScannerFactory.getScanner()); | |
} | |
private BeanConfig getBeanConfig() { | |
BeanConfig beanConfig = new ResourceConfig(); | |
beanConfig.setHost(getConfigString("host")); | |
beanConfig.setTitle(getConfigString("title")); | |
beanConfig.setVersion(getConfigString("version")); | |
beanConfig.setContact(getConfigString("contact")); | |
beanConfig.setLicense(getConfigString("license")); | |
beanConfig.setBasePath(getConfigString("base_path")); | |
beanConfig.setLicenseUrl(getConfigString("licenseUrl")); | |
beanConfig.setDescription(getConfigString("description")); | |
beanConfig.setPrettyPrint(getConfigString("pretty_print")); | |
beanConfig.setTermsOfServiceUrl(getConfigString("terms_of_service_url")); | |
// Must be called last | |
beanConfig.setResourcePackage(resourcePackages()); | |
beanConfig.setScan(true); | |
return beanConfig; | |
} | |
@Nullable | |
private String getConfigString(String path) { | |
return config.hasPath(path) ? config.getString(path) : null; | |
} | |
/** Returns a comma separated list of resource packages. */ | |
private String resourcePackages() { | |
return injector.getBindings().keySet().stream() | |
.map(key -> key.getTypeLiteral().getRawType()) | |
.filter(GetRestful::isRootResource) | |
.map(clazz -> clazz.getPackage().getName()) | |
.distinct() | |
.collect(Collectors.joining(",")); | |
} | |
@Override | |
public void contextDestroyed(ServletContextEvent event) {} | |
} |
Thanks for this. I'm trying to add a swagger module to GWizard :) Lots of learning to do.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ben-manes, could you please add an example for the configuration of the web.xml?