虽然我能够在v2 / api-docs端点下看到json,但Swagger UI没有列出任何控制器/端点

时间:2016-08-30 15:43:23

标签: rest swagger swagger-ui spring-4 swagger-2.0

我无法让Swagger UI与我的项目一起使用。 Swagger UI很好用,但它没有列出我的任何REST控制器。

我正在使用SPRING 4.2.6.RELEASE和Swagger 2.5.0。我的休息服务部署到Tomcat 7.0.54。

当Tomcat 7.0.54出现时,它可以获取swagger端点。 我能够点击获取json消息的端点v2 / api-docs。 我也能击中swagger-ui,但我没有看到任何控制器列出。 下拉列表为空,如下所示

enter image description here

**我目前面临的问题是

  1. 我无法获取/ swagger-resources / configuration / ui,当我尝试获取/ swagger-resources / configuration / ui时,当我启动swagger UI时,我得到404(Not Found)错误。我为swagger资源设置了资源处理程序,但这似乎没有帮助。能告诉我可能缺少什么吗?
  2. 我是否应该在扩展的WAR中看到META-INF下的资源文件夹? META-INF中是否应该有任何与springfox相关的文件/文件夹? **
  3. Swagger的Maven依赖         
                             io.springfox             springfox-swagger2             2.5.0         
                         io.springfox             springfox-招摇的UI             2.5.0         

    以下是我的SwaggerCongifuration

    @EnableSwagger2
    public class SwaggerConfiguration {
    
    @Bean
    public Docket api() {
        List<SecurityContext> security = new ArrayList<SecurityContext>();
        security.add(securityContext());
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .pathMapping("/").securityContexts(security);
    }
    
    private SecurityContext securityContext() {
        return SecurityContext.builder()
                .forPaths(PathSelectors.regex("/"))
                .build();
     }
    }
    

    以下是我的WebConfig.xml

    @EnableWebMvc
    @Configuration
    @Import(SwaggerConfiguration.class)
    @ComponentScan("com.bank.direct.services")
    
    public class WebConfig extends WebMvcConfigurerAdapter {
    
    
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> pConverters) {
        pConverters.add(RestUtils.getJSONMessageConverter());
    }
    
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
        .addResourceLocations("classpath:/META-INF/resources/");
    
        registry.addResourceHandler("/webjars/**")
        .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
    
    }
    

    以下是SecurityCongif.xml

    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    @Autowired
    private AuthenticationService _authenticationService;
    
    
    @Autowired
    public void globalUserDetails(AuthenticationManagerBuilder pAuth) throws Exception {
    
        pAuth.userDetailsService(_authenticationService);
    }
    
    
    @Override
    protected void configure(HttpSecurity pHttp) throws Exception {
    
        // Enable HTTP caching
        pHttp.headers().cacheControl().disable();
    
        // Configure security
        pHttp.httpBasic()
    
        // -- Allow only authenticated request
        .and()
        .authorizeRequests()
        .anyRequest().authenticated()
    
        // -- Logout configuration
        .and()
        .logout()
        .logoutUrl("/rest/users/logout/")
        .deleteCookies("XSRF-TOKEN")
        .logoutSuccessUrl("/static/index.html")
        .invalidateHttpSession(true)
    
        // -- CSRF configuration
        .and()
        .csrf().csrfTokenRepository(csrfTokenRepository())
        .and()
        .addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
    
    }
    
    
    private Filter csrfHeaderFilter() {
    
        return new OncePerRequestFilter() {
    
            @Override
            protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    
                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
                if (csrf != null) {
                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                    String token = csrf.getToken();
                    if (cookie == null || token != null && !token.equals(cookie.getValue())) {
                        cookie = new Cookie("XSRF-TOKEN", token);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    }
                }
                filterChain.doFilter(request, response);
            }
        };
    }
    
    
    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }
    

    Rest Controller类如下

    @RestController
    @RequestMapping(value = "/vehicles", produces =     MediaType.APPLICATION_JSON_UTF8_VALUE)
    public class VehicleResource extends Resource {
    
    @Autowired
    private IVehicleService _vehicleService;
    
    @RequestMapping(value = "/brands", method = RequestMethod.GET)
    public APIResponseEntity getBrands(WebRequest pWebRequest) {
    
        IUser user = getUser(pWebRequest);
        BrandCriteria criteria = new BrandCriteria();
        criteria.setLanguageCode(user.getLanguageCode());
    
        List<Brand> res = _vehicleService.getBrands(user, criteria);
    
        return newResponseOK(res);
    }
    
    @RequestMapping(value = "/brands/{brand_code}", method = RequestMethod.GET)
    public APIResponseEntity getBrand(WebRequest pWebRequest, @PathVariable("brand_code") String pBrandCode) {
    
        IUser user = getUser(pWebRequest);
        BrandCriteria criteria = new BrandCriteria();
        criteria.setLanguageCode(user.getLanguageCode());
        criteria.setBrandCode(pBrandCode);
        List<Brand> res = _vehicleService.getBrands(user, criteria);
        return newResponseOK(res);
     }
    }   
    

2 个答案:

答案 0 :(得分:1)

将较旧的项目从XML Spring配置迁移到Java Spring配置并更新spring和Swagger版本后,我遇到了一个听起来完全像这样的问题,所以我想我会在这里记录我的解决方案。

我遇到了一些问题,但与OP的情况相匹配的主要问题是虽然/v2/api-docs可以访问并返回JSON,但我的控制器显然没有被拾取,而且我在/swagger-ui.html访问了Swagger UI,当该页面尝试请求/swagger-resources/configuration/ui

时,我收到了404

我的Swagger配置类是:

@Configuration
@EnableSwagger2
public class SwaggerWebConfig {
    @Bean
    public Docket api() {
        ...
    }
}

@ EnableSwagger2注释导入另一个配置类Swagger2DocumentationConfiguration,后者又导入SwaggerCommonConfiguration,它对springfox.documentation.swagger.web中的类进行组件扫描,最终加载ApiResourceController,这是

  • /swagger-resources/
  • /swagger-resources/configuration/security
  • /swagger-resources/configuration/ui

来自。

我错误的是我的SwaggerWebConfig类是由根应用程序上下文加载的,当它应该属于Web应用程序上下文see ApplicationContext vs WebApplicationContext)时。

Web应用程序上下文中的Bean可以访问根应用程序上下文中的bean,但不是相反,这解释了为什么Docket bean(在根应用程序上下文中不正确)无法在Web应用程序中获取@Controller bean上下文并解释了为什么尽管创建了ApiResourceController bean,但它的方法在尝试访问它们时会给出404(它们应该在Web应用程序上下文中)

关于相关问题的一些其他说明:

  • 如果你可以点击v2 / api-docs那么你的Docket bean正在运行
  • 在非spring-boot环境中,您需要自己注册两个资源处理程序,因为Spring {this question的答案中解释了Spring Boot的自动配置可以为您完成此操作。这应该解决404的问题:
    • /swagger-ui.html(即404获取实际的html swagger-ui.html页面)
    • 和swagger-ui.html加载的三个webjars:
      • /webjars/springfox-swagger-ui/springfox.js
      • /webjars/springfox-swagger-ui/swagger-ui-bundle.js
      • /webjars/springfox-swagger-ui/swagger-ui-standalone-preset.js
  • 如果您获得拒绝访问而不是404,则如this answer所示,您可能需要告诉spring security允​​许访问:
    • /webjars/**
    • /swagger-ui.html
    • /v2/api-docs
    • /swagger-resources/**

答案 1 :(得分:0)

You need to point the the generated Swagger Definition in Swagger UI. i.e in place of http://example.com/api give your swagger definition path something like http://localhost:8080/RestResource/api/swagger.json

This article might help you more