-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can basePath be set to webapp context? #64
Comments
@thomaschristensen Its not really hard coded, its a configured property :). Having said that, I havent found a good way to infer the path (including the scheme, hostname and port) in spring mvc. This is a problem I'd like to see solved as well. Within a corporate network we have the ability to hit the documentation endpoint in a fully qualified domain name or just the machine name (depending on how the web server is set up) for e.g. the documentation for services on a machine called machine1 in a companya.com can be reached using either of these locations
It would be nice to infer those rather than "hard-coding" the basePath. |
@thomaschristensen @dilipkrish
then, in swagger-ui.js:
and finally add in some places where base path need in swagger.js:
Yes, /rest/ is hardocoded, but now it's ok for us |
@Daigotsu Thanks thats pretty useful! |
This will be addressed when issue #95 is fixed |
@Daigotsu Hi, I'm trying use your solution for get dynamic basePath, but I when deploy my application occurr above error: [Thu Jul 2013 12:55:38.337] ERROR [] (org.springframework.web.servlet.DispatcherServlet:468) - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'swaggerConfiguration' defined in URL [file:/home/katia/juno-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/CorporateServicesWeb/WEB-INF/classes/spring-servlet.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.mangofactory.swagger.SwaggerConfiguration]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.mangofactory.swagger.SwaggerConfiguration.() at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1011) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:957) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:652) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:600) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:666) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:519) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:460) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) at javax.servlet.GenericServlet.init(GenericServlet.java:160) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1189) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1103) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1010) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4935) at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5262) at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5257) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662) Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.mangofactory.swagger.SwaggerConfiguration]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.mangofactory.swagger.SwaggerConfiguration.() at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:83) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1004) ... 28 more Caused by: java.lang.NoSuchMethodException: com.mangofactory.swagger.SwaggerConfiguration.() at java.lang.Class.getConstructor0(Class.java:2715) at java.lang.Class.getDeclaredConstructor(Class.java:1987) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:78) ... 29 more Can you help me? |
@Daigotsu Hello, I made a little modification in your bean swaggerConfiguration, I changed tag property for construct-args: And the error message changed: [Thu Jul 2013 14:30:46.118] ERROR [] (org.springframework.web.servlet.DispatcherServlet:468) - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'swaggerConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mangofactory.swagger.DocumentationTransformer com.mangofactory.swagger.SwaggerConfiguration.documentationTransformer; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mangofactory.swagger.DocumentationTransformer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:652) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:600) at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:666) at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:519) at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:460) at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) at javax.servlet.GenericServlet.init(GenericServlet.java:160) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1189) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1103) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1010) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4935) at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5262) at org.apache.catalina.core.StandardContext$3.call(StandardContext.java:5257) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:662) Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mangofactory.swagger.DocumentationTransformer com.mangofactory.swagger.SwaggerConfiguration.documentationTransformer; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mangofactory.swagger.DocumentationTransformer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) ... 28 more Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mangofactory.swagger.DocumentationTransformer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:967) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:837) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) ... 30 more Can you help me? |
@katiaSouza If you copied that configuration snippet, that solution will not work for 0.5.x version. You'd need to create an subclass of the ExtensibilityModel and change the base path in the swaggerConfiguration. |
@katiaSouza @dilipkrish Sorry for late answer. Yeah check new version of swagger. Cause first solution i use in 0.4 version. <mvc:resources location="classpath:/swagger/v2/" mapping="/api/**"/>
<context:property-placeholder location="classpath:swagger-v2.properties" />
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.FixedLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="documentationConfigV2" class="com.XXX.workload.v2.rest.swagger.config.CustomDocumentationConfig">
</bean>
<bean id="extensibilityModule" class="com.XXX.workload.v2.rest.swagger.config.CustomExtensibilityModule" /> swagger-v2.properties
CustomExtensibilityModule.java @Configuration
@Import(DocumentationConfig.class)
public class CustomDocumentationConfig {
@Bean
public NameEndPointComparator endPointComparator() {
return new NameEndPointComparator();
}
@Bean
public NameOperationComparator operationComparator() {
return new NameOperationComparator();
}
@Bean
public SwaggerConfiguration swaggerConfigurationV2(DefaultConfigurationModule defaultConfig,
ExtensibilityModule extensibility, @Value("${documentation.services.basePath}") String basePath,
@Value("${documentation.services.version}") String apiVersion) {
SwaggerConfiguration swaggerConfiguration = new SwaggerConfiguration(apiVersion, basePath);
return extensibility.apply(defaultConfig.apply(swaggerConfiguration));
}
@Bean
public DocumentationControllerV2 documentationControllerV2() {
return new DocumentationControllerV2();
} from api.html var url = window.location.href.match(/.*\/rest/g);
$(function () {
window.swaggerUi = new SwaggerUi({
discoveryUrl: url + '/v2/api-docs',
apiKey:"",
dom_id:"swagger-ui-container",
supportHeaderParams: true,
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function(swaggerApi, swaggerUi){
if(console) {
console.log("Loaded UPSA REST UI")
console.log(swaggerApi);
console.log(swaggerUi);
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
},
onFailure: function(data) {
if(console) {
console.log("Unable to Load UPSA REST UI");
console.log(data);
}
},
docExpansion: "none"
});
window.swaggerUi.load();
}); from swagger.js() ~~~~~~50 line
SwaggerApi.prototype.build = function() {
var _this = this;
this.progress('fetching resource list: ' + this.discoveryUrl);
return jQuery.getJSON(this.discoveryUrl, function(response) {
var res, resource, _i, _j, _len, _len1, _ref, _ref1;
if (response.apiVersion != null) {
_this.apiVersion = response.apiVersion;
}
/*HERE ------->>>>
if ((response.basePath != null) && jQuery.trim(response.basePath).length > 0) {
_this.basePath = response.basePath;
//add config, to define only last part of url in spring application context.
//sdfsdfsdf
if (_this.basePath.match(/^HTTP/i) === null) {
_this.basePath = window.location.href.match(/.*(?=\/rest)/) + response.basePath;
}
if (_this.basePath.match(/^HTTP/i) == null) {
_this.fail("discoveryUrl basePath must be a URL.");
}
_this.basePath = _this.basePath.replace(/\/$/, '');
} else {
_this.basePath = _this.discoveryUrl.substring(0, _this.discoveryUrl.lastIndexOf('/'));
log('derived basepath from discoveryUrl as ' + _this.basePath);
}
~~~~200 line
SwaggerResource = (function() {
function SwaggerResource(resourceObj, api) {
var parts,
_this = this;
this.api = api;
this.path = this.api.resourcePath != null ? this.api.resourcePath : resourceObj.path;
this.description = resourceObj.description;
parts = this.path.split("/");
this.name = parts[parts.length - 1].replace('.{format}', '');
this.basePath = this.api.basePath;
this.operations = {};
this.operationsArray = [];
this.modelsArray = [];
this.models = {};
/*HERE ------->>>>
//add config, to define only last part of url in spring application context.
if (this.basePath.match(/^HTTP/i) === null) {
this.basePath = window.location.href.match(/.*(?=\/rest)/)+this.api.basePath;
}
~~~600 line
SwaggerOperation.prototype.urlify = function(args, includeApiKey) {
var param, queryParams, reg, url, _i, _len, _ref;
if (includeApiKey == null) {
includeApiKey = true;
}
/*HERE ------->>>>
url = window.location.href.match(/.*(?=\/rest)/) + this.resource.basePath + this.pathJson();
_ref = this.parameters;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
param = _ref[_i];
if (param.paramType === 'path') {
if (args[param.name]) {
reg = new RegExp('\{' + param.name + '[^\}]*\}', 'gi');
url = url.replace(reg, encodeURIComponent(args[param.name]));
delete args[param.name];
} else {
throw "" + param.name + " is a required path param.";
}
}
} |
Swagger Spec 1.2 changes the Resource Listing so basePath is no longer required and all api paths are relative to Resource Listing path so this will fix our issue and simplify everything. This change seem to be included in Swagger 1.3 that is at RC2 so maybe an early adoption will be enough to close this issue. |
@Daigotsu Hi, I applied the modification suggested by you in my application and it works very well. |
As said #128 Should fix this one also. |
@boeboe can you share your spring configuration and we can try help. |
The documented way to set up the SwaggerConfiguration bean is to hardcode the basePath. Is there a way to pick up the current webapp context instead?
I understand that when finally publishing it would be better to use properties, since public URL isn't necessarily the same as the webapps deployed context (proxies in front etc).
The text was updated successfully, but these errors were encountered: