简体   繁体   中英

Spring boot controller endpoints not enabled?

I have inherited a Spring Boot microservice which does not have a Service or API layer, it is behaving in a HATEOAS style.

This is not an optimal architecture and needs to be changed into MVC.

Currently all repository methods are accessed directly using the @RepositoryRestResource annotation.

The plan is to refactor this and add Controllers and a API layer (DTOs), however after adding a controller, swagger is not showing the Rest controllers Also to note that when debugging the controller endpoint, it is not actually reached. It is being bypassed, which is another clue.

@CrossOrigin
@RestController
@RequestMapping("/fixing")
public class FixingController {

  private final FixingRepository fixingRepository;

  @Autowired
  FixingController(final FixingRepository fixingRepository) {
    this.fixingRepository = checkNotNull(fixingRepository, "Fixing Repository cannot be null");
  }

  /**
   * Builds a list of Fixing strings from the database
   * @return list
   */
  @RequestMapping(value = "/", method = RequestMethod.GET)
  public List<String> getAllFixings() {

    final List<String> fixingList = new ArrayList<>();
    for (Fixing fixing : fixingRepository.findAll()) {
      String name = fixing.getName();
      fixingList.add(name);
    }
    return fixingList;
  }

}

This is the spring swagger config

@Configuration
public class SwaggerConfig {

@Bean
public Docket api() {

return new Docket(DocumentationType.SWAGGER_2)
  .select()
  .apis(RequestHandlerSelectors.any())
  .paths(PathSelectors.regex("/api.*"))
  .build();
 } 
}

The repository (note no @RepositoryRestResource annotation)

public interface FixingRepository extends JpaRepository<Fixing, Long> {

  @Override
  Fixing findOne(Long id);

  @Override
  List<Fixing> findAll();

}

When I rebuild and start the service, the controller is not shown. It only shows all the entities and their repository methods.

在此处输入图片说明

POM dependencies

 <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--  included explicitly to avoid javadoc generation error
              due to a conflict with a class used by @Transactional annotation -->
        <dependency>
            <groupId>javax.interceptor</groupId>
            <artifactId>javax.interceptor-api</artifactId>
            <version>1.2</version>
        </dependency>


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>8.0.12</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>


        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.8.0</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-data-rest</artifactId>
            <version>2.8.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>1.5.13.RELEASE</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.json/json -->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20180130</version>
        </dependency>

        <dependency>
            <groupId>com.vladmihalcea</groupId>
            <artifactId>hibernate-types-52</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.5</version>
        </dependency>

        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>3.6.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gcp-starter-storage</artifactId>
            <version>1.0.0.RELEASE</version>
        </dependency>

    </dependencies>

Any ideas what is causing this? There is nothing else I can see in the config which is preventing this from working

The issue is with your SwaggerConfig. You are only selecting a subset of your APIs (either the JPA repository sourced or your RestController sourced) via this :

.paths(PathSelectors.regex("/api.*"))

I replicated your scenario and I just commented the path selection out and I can see both type of APIs. Note that you can also use a custom predicate for selecting the paths:

@Configuration
@Import({SpringDataRestConfiguration.class})
public class SwaggerConfig {

    @Autowired
    @SuppressWarnings({"UnusedDeclaration"})
    private ServletContext servletContext;

    @Bean
    public Docket api() {

        return new Docket(DocumentationType.SWAGGER_2)
                .pathProvider(relativePath())
                .select()
                .apis(RequestHandlerSelectors.any())
//                .paths(paths2())
                .build();
    }
    // Select only a few
    private Predicate<String> paths2() {
        return and(
                (regex("/fixing.*")),
                (regex("/api.*")));
    }
    // Exclude these 
    private Predicate<String> paths() {
        return and(
                not(regex("/error.*")),
                not(regex("/metrics.*")),
                not(regex("/jolokia.*")),
                not(regex("/health.*")),
                not(regex("/env.*")),
                not(regex("/metrics.*")),
                not(regex("/info.*")),
                not(regex("/mappings.*")),
                not(regex("/trace.*")),
                not(regex("/dump.*")),
                not(regex("/heapdump.*")),
                not(regex("/configprops.*")),
                not(regex("/beans.*")),
                not(regex("/autoconfig.*")),
                not(regex("/logfile.*")),
                not(regex("/shutdown.*")),
                not(regex("/actuator.*")));
    }
}

Sample Rest Controller:

@CrossOrigin
@RestController
@RequestMapping("/fixing")
public class FixingController {

    /**
     * Builds a list of Fixing strings from the database
     * @return list
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public List<String> getAllFixingsViaRestController() {

        final List<String> fixingList = new ArrayList<>();
        fixingList.add("foo");
        fixingList.add("bar");

        return fixingList;
    }

}

Now my Swagger UI looks like this; you can see both the JPA Repository contributed REST APIs and the RestController contributed API (/fixing path):

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM