简体   繁体   English

Spring Boot Web throws 404 with API call, correct project structure

[英]Spring Boot Web throws 404 with API call, correct project structure

SOLVED : Adding @Service annotation in CRUDServices.java and removing @ComponentScan in the main application solved EVERYTHING.已解决:在CRUDServices.java中添加 @Service 注释并在主应用程序中删除 @ComponentScan 解决了所有问题。

I have a small application with Spring Boot Web, JPA and PostgreSQL database.我有一个带有 Spring Boot Web、JPA 和 PostgreSQL 数据库的小型应用程序。 When trying to call ANY of these API calls I get a 404. In another application done the same way it's successfull.当尝试调用这些 API 中的任何一个时,我得到一个 404。在另一个应用程序中以相同的方式完成它是成功的。 All classes are in the same package and I don't get why it wouldn't find the controller (which seems to be the issue for most others with similair/same problem).所有课程都在同一个 package 中,我不明白为什么它找不到 controller(这似乎是大多数其他有类似/相同问题的问题)。

It runs on port 8081 because I have another service running on port 8080.它在端口 8081 上运行,因为我有另一个服务在端口 8080 上运行。

I tried removing the ComponentScan but then get a missing bean exception.我尝试删除 ComponentScan,但随后出现了丢失的 bean 异常。 I don't get it - they are all in the same package structure?我不明白 - 它们都在同一个 package 结构中? I only have ONE package and that's booking.crudservice我只有一个 package 那是 booking.crudservice

Main application主要应用

package booking.crudservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Service;

@SpringBootApplication
@ComponentScan(basePackages="booking.crudservice.CRUDservices")
public class CrudserviceApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(CrudserviceApplication.class, args);
    }
}

Controller Controller

package booking.crudservice;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

/*
    This has PUT,POST, GET, DELETE requstest to the API endpoints for the CRUD operations
    in CRUDservices.java
 */

@RestController
@RequestMapping("/bookings")
public class BookingController
{
    @Autowired
    private CRUDServices services;

    //Return a specific booking by ID.
    @RequestMapping("/{bookingID}")
    public Optional<BookingEntity> getBookingByID(@PathVariable String bookingID)
    {
        return services.getBookingByID(bookingID);
    }

    //Return all bookings
    @RequestMapping("/allbookings")
    public List<BookingEntity> getAllBookings()
    {
        return services.getAllBookings();
    }

    @RequestMapping(method = RequestMethod.POST, value ="/addbooking")
    public void addBooking(@RequestBody BookingEntity booking)
    {
        services.addBooking(booking);
    }

    //Update a given booking (with a bookingID), and replace it with new BookingEntity instance.
    @RequestMapping(method = RequestMethod.PUT, value ="/bookings/{bookingID}")
    public void updateBooking(@RequestBody BookingEntity booking, @PathVariable String bookingID)
    {
        services.updateBooking(booking, bookingID);
    }

    //Deletes a booking with the given bookingID
    @RequestMapping(method = RequestMethod.DELETE, value ="/bookings/{bookingID}")
    public void deleteBooking(@PathVariable String bookingID)
    {
        services.deleteBooking(bookingID);
    }
}

pom.xml pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>booking</groupId>
    <artifactId>crudservice</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>crudservice</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.properties file application.properties 文件

server.port=8081
spring.datasource.url=jdbc:postgresql://localhost:5432/bookingDB
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL81Dialect

CRUDServices.java CRUDServices.java

package booking.crudservice;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/*
    This service holds all CRUD operations performed on the database.
    This utilizes the BookingRepository.java, which extends the CRUDrepository interface.
    Using ORM via JPA all operations on the database can be easily performed here.
    To connect to the web GET,PUT,POST and DELETE http requests will be made on all the operations via
    BookingController, enabling the user and other possible services to interact with the database
    using API endpoints.
 */

public class CRUDServices
{
    @Autowired
    private BookingRepository repository;

    //READ all bookings from DB using GET request
    public List<BookingEntity> getAllBookings()
    {
        List<BookingEntity> bookings = new ArrayList<>();
        repository.findAll().
                forEach(bookings::add);

        return bookings;
    }
    //SEARCH for a booking, given bookingID
    public Optional<BookingEntity> getBookingByID(String bookingID)
    {
        return repository.findById(bookingID);
    }

    public void addBooking(BookingEntity booking)
    {
        repository.save(booking);
    }

    public void updateBooking(BookingEntity booking, String bookingID)
    {
        //1. Search for the given ID in the database
        //2. Replace the booking object on that ID with new booking object from parameter.
    }

    public void deleteBooking(String bookingID)
    {
        repository.deleteById(bookingID);
    }
}

In CrudserviceApplication class you mentioned base-package as在 CrudserviceApplication class 中,您将基础包提到为

@ComponentScan(basePackages="booking.crudservice.CRUDservices")

That means spring boot will look for classes annotated with spring stereotype annotations like这意味着 spring 引导将查找带有 spring 构造型注释的类,例如

  • @Component @成分
  • @Configuration @配置
  • @Controller @控制器
  • @RestController @RestController
  • @Service @服务

for classes present inside booking.crudservice.CRUDservices package and its sub-packages.对于booking.crudservice.CRUDservices package 及其子包中存在的类。 However, I can see your BookingController class is present in booking.crudservice package which is not a sub-package (in fact, it's parent package).但是,我可以看到您的 BookingController class 存在于booking.crudservice package 中,它不是子包(实际上,它是父包)。

That's why spring boot is not scanning BooKingController class and hance you're getting 404.这就是为什么 spring 引导不扫描 BooKingController class 而你得到 404 的原因。

As a fix, you can remove basePackages parameter inside @ComponentScan annotation and it'll scan all components present inside booking.crudservice and its sub-package(s).作为修复,您可以删除 @ComponentScan 注释中的 basePackages 参数,它将扫描booking.crudservice及其子包中存在的所有组件。

Since your CrudserviceApplication.class is present in the base package itself.由于您的CrudserviceApplication.class存在于基础 package 本身中。 You don't have to use the @ComponentScan annotation.您不必使用 @ComponentScan 注释。

You should be having @Service annotation in your service class ( CRUDServices.class ) for spring to maintain and inject it.您应该在服务 class ( CRUDServices.class ) 中为 spring 提供@Service注释以维护和注入它。

Also, can you verify that you're calling all your handler methods with /bookings/yourhandlerendpoint prefix.此外,您能否验证您是否正在使用/bookings/yourhandlerendpoint前缀调用所有处理程序方法。 In your case在你的情况下

  • /bookings/{bookingID} /预订/{预订ID}
  • /bookings/allbookings /预订/所有预订
  • /bookings/addbooking /预订/添加预订
  • /bookings/bookings/{bookingID} /预订/预订/{预订ID}
  • /bookings/bookings/{bookingID} /预订/预订/{预订ID}

Also, I could see that you've adding /bookings perfix twice for couple of methods.另外,我可以看到您为几种方法添加了两次/bookings perfix。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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