【问题标题】:Error 404 Not Found. Why is my RestController not recognized from Spring Boot Application?未找到错误404。为什么 Spring Boot 应用程序无法识别我的 RestController?
【发布时间】:2021-09-06 16:52:37
【问题描述】:

我有以下问题。我有一个简单的 Spring Boot 应用程序,它应该处理用户的债务。该服务确实可以编译,但是插入新记录的 PostRequest 和显示用户债务的 GetRequest 都不起作用。当服务启动时,应用程序会自动为实体创建适当的表。因此我认为数据库连接不会是问题。看起来我的服务无法识别 RestController。使用 Postman,我不断收到错误代码“404 Not Found”。

有人知道我做错了什么吗?

我的实体

package Entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;

@Entity
@Table(name= "debts")
@EnableAutoConfiguration
public class DebtsEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    
    @Column(name = "user_id")
    private String userId;
    @Column(name = "invoice_id")
    private int invoiceId ;
    @Column(name = "creditor")
    private String creditor;
    @Column(name = "amount")
    private double amount;
    @Column(name = "deadline")
    private String deadline;
    @Column(name = "installment")
    private double installment;
    
    
    public DebtsEntity(){
        
    }

    

    public DebtsEntity(int id, String userId, int invoiceId, String creditor, double amount, String deadline,
            double installment) {
        super();
        this.id = id;
        this.userId = userId;
        this.invoiceId = invoiceId;
        this.creditor = creditor;
        this.amount = amount;
        this.deadline = deadline;
        this.installment = installment;
    }


    public int getId() {
        return id;
    }


    public void setId(int id) {
        this.id = id;
    }


    public String getUserId() {
        return userId;
    }


    public void setUserId(String userId) {
        this.userId = userId;
    }


    public int getInvoiceId() {
        return invoiceId;
    }


    public void setInvoiceId(int invoiceId) {
        this.invoiceId = invoiceId;
    }


    public String getCreditor() {
        return creditor;
    }


    public void setCreditor(String creditor) {
        this.creditor = creditor;
    }


    public double getAmount() {
        return amount;
    }


    public void setAmount(double amount) {
        this.amount = amount;
    }


    public String getDeadline() {
        return deadline;
    }


    public void setDeadline(String deadline) {
        this.deadline = deadline;
    }


    public double getInstallment() {
        return installment;
    }


    public void setInstallment(double installment) {
        this.installment = installment;
    }


    @Override
    public String toString() {
        return "debtsEntity [id=" + id + ", userId=" + userId + ", invoiceId=" + invoiceId + ", creditor=" + creditor
                + ", amount=" + amount + ", deadline=" + deadline + ", installment=" + installment + "]";
    }
    
}

我的休息控制器

package Controller;

import java.net.URI;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import DAO.DebtsDAO;
import Entity.DebtsEntity;

@RestController
public class DebtsController {

    @Autowired
    DebtsDAO debtsDAO;
    
    @GetMapping("/{userId}/debts")
    public List<DebtsEntity> retrieveDebtsByUserId(@PathVariable String userId)
    {
        List<DebtsEntity> debts = debtsDAO.findByUserId(userId);
        
        return debts;
    }
    
    @PostMapping("/debts")
    public ResponseEntity<Object> createInvoice(@RequestBody DebtsEntity debtsEntity)  
    {  
        DebtsEntity savedUser =debtsDAO.save(debtsEntity);
        URI location= ServletUriComponentsBuilder.fromCurrentRequest()
        .path("path/{id}")
        .buildAndExpand(savedUser.getId()).toUri();
        
        return ResponseEntity.created(location).build();
    }  
}

我的 DAO

package DAO;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
import Entity.DebtsEntity;

@Component
public interface DebtsDAO extends JpaRepository<DebtsEntity, Integer>{

    List<DebtsEntity> findByUserId(String user_id);

}

我的应用程序.properties

## Database konfiguration
spring.datasource.url=jdbc:postgresql://localhost:5432/Test
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=create
# define if Database Queries should be written in logfile
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.default_schema=public
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL81Dialect

server.port=8000
spring.application.name=Debts

我的依赖

<?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.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>LifeOps</groupId>
    <artifactId>Service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Service</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <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>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

更新 1

获取请求

网址:http://localhost:8000/1000/depts

后请求

网址:http://localhost:8000/depts 请求正文:

{
    "id":1000,
    "user_id": "ABC1234",
    "invoice_id":100001,
    "creator": "A12L",
    "amount": 123012.56,
    "deadline": "20.10.12",
    "installment": 50.00
}
package Service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;

@EntityScan(basePackages = "entity")
@SpringBootApplication
public class ServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }

}

更新 2

Class                                 package
DebtsApplication                      service.debts
DebtsController                       service.debts.controller
DebtsEntity                           service.debts.entity
DebtsDAO                              service.debts.dao

【问题讨论】:

  • 你为什么忽略了非常重要的事情,即你正在调用的 url?
  • 对不起,你是对的,我忘记了。它更新此案例的 URL
  • 你也可以添加你的主类吗?
  • 现在也更新了
  • 没有包吗?

标签: java spring postgresql jpa


【解决方案1】:

我建议你添加一个基本包(类似于“com.doncarlito”)并将ServiceApplication 放入其中。

package com.doncarlito;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;

@EntityScan(basePackages = "entity")
@SpringBootApplication
public class ServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceApplication.class, args);
    }

}

然后将所有其他存在的包移动为这个的子包:

  • com.doncarlito.entity
  • com.doncarlito.dao
  • com.doncarlito.controller
  • com.doncarlito.service

原因是@SpringBootApplication 封装了@Configuration@EnableAutoConfiguration@ComponentScan 注释及其默认属性。 @ComponentScan 的默认值表示使用@ComponentScan 的包上的所有子包都被扫描。这就是为什么在项目的基础包中包含主类通常是一个好习惯的原因。

【讨论】:

  • 我已经尝试了解决方案。在 UPDATE 2 中显示了我的文件夹层次结构。但是,我现在在编译时遇到错误。现在编译器无法创建 bean。创建名称为“debtsController”的 bean 时出错:通过字段“debtsDAO”表示的依赖关系不满足;
  • 这实际上很奇怪,但我们可以尝试一些方法吗? 1. 从DebtsEntity 中删除@EnableAutoConfiguration,因为如上所述没有必要。 2. 将DebtsDAO 中的@Component 替换为@Repository(其他详细信息 --> baeldung.com/spring-component-repository-service)。 3. 从ServiceApplication 中删除@EntityScan(basePackages = "entity"),因为@EnableAutoConfiguration 可以解决问题(其他详细信息 --> baeldung.com/spring-entityscan-vs-componentscan)。
【解决方案2】:

您正在从 x.y.z.ApplicationService 运行您的应用程序,但您的组件位于不同的包中,例如 x.y.a.YourComponent,它不会被 spring 拾取。

默认情况下,spring 会扫描你的 @SpringApplication 类的包(和后代)。参考上述内容,它将是x.y.z.*.....

解决您的问题(替代方案)

  1. 将您的ApplicationService 移到DebtsApplication 旁边,使其位于所有必需组件的“顶部”(例如@RestController
  2. 添加@ComponentScan(basePackgages={'service.debts'})ApplicationService,这样您就可以“手动”显示 spring 在哪里寻找组件。
  3. 还有其他方法,但你应该没问题 2

【讨论】:

    猜你喜欢
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 2021-10-13
    • 2020-04-12
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多