当前位置: 首页 > 知识库问答 >
问题:

Swagger UI没有列出任何控制器/endpoint,但我可以看到V2/API-DOCSendpoint下的json

司空胤
2023-03-14

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

我使用的是Spring4.2.6.Release和Swagger2.5.0。我的rest服务部署到Tomcat 7.0.54。

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

    null
@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();
 }
}
@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/");
}

}
@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控制器类如下所示

@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);
 }
}   

共有1个答案

仉宸
2023-03-14

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

我遇到了很多问题,但与OP场景匹配的主要问题是,虽然/v2/api-docs可以访问并返回JSON,但我的控制器显然没有被拾取,并且当我访问/swagger-ui.html的Swagger UI时,当该页面试图请求/swagger-resources/configuration/UI时,我得到的是404

我的大摇大摆配置类是:

@Configuration
@EnableSwagger2
public class SwaggerWebConfig {
    @Bean
    public Docket api() {
        ...
    }
}
  • /swagger-resources/
  • /swagger-resources/configuration/security
  • /swagger-resources/configuration/ui

都是由。

我不正确的是,我的SwagerWebConfig类是由根应用程序上下文加载的,而它应该属于web应用程序上下文(请参见ApplicationContext vs WebApplicationContext)。

    null
    null
 类似资料:
  • 我正在编写一个应用程序,我需要在单击不同按钮时出现相同的自定义弹出窗口。现在弹出窗口只是一个简单的“你确定吗?确定/取消”窗口,但稍后它将扩展以包括更多自定义功能......所以我不能使用内置的快速对话框。 奇怪的是。当按下按钮X时,弹出窗口(在FXML中定义)启动得很好,但我的控制器类似乎没有运行。我不认为你能做到这一点。我无法弄清楚的是控制器没有运行的原因。我本来以为如果控制器不工作,应用程序

  • 问题内容: 得到反馈后,我运行该程序,但在控制台中没有任何输出 程序运行,但不输出。 问题答案: 是一种阻止方法。它会等到进程退出后再返回。这样做的问题是,许多程序只有在读取/清除标准输出缓冲区后才会退出,这意味着,就您而言,它可能永远不会退出。 尝试这样的事情…

  • 问题内容: 如标题所述,是否有一种简单的方法可以将两列输出到Java中的控制台? 我知道,但是在使用printf时,我还没有找到基于特定列进行空间分配的方法。 问题答案: 使用宽度和精度说明符,将其设置为相同的值。这将填充太短的字符串,并截断太长的字符串。“-”标志将使列中的值左对齐。

  • 我正在尝试用注释配置我的Spring Boot应用程序,并在其中使用@Autowired注释。当我检查是否已加载Bean时,它已加载,但使用@Autowired时,它会显示NoSuchBeanDefinitionException 正如您可以进一步看到的那样,我试图检查我的Bean是否真的被加载了,所以当我运行我的应用程序时,我可以在控制台中看到我的Bean的名称。此外,我尝试将“scanBase

  • 给定以下代码: 在reduce语句之后我需要什么才能看到reduce的结果?如果一个值被推到输入,我不希望看到任何东西。如果推送具有相同键的第二个值,我希望还原器应用(它确实应用了),并且我还希望还原的结果继续到处理管道中的下一个步骤。正如所描述的,我没有在管道的后续步骤中看到任何东西,我不明白为什么。

  • 我目前有一个网络 API 使用 将此数据作为作为 包装响应,以显式设置返回代码。然而,这目前似乎并不奏效。 我应该只为存储库应用解决方案并将结果用作控制器中的列表还是保持原样?