【问题标题】:Java controller always return a 404 no matter what I do无论我做什么,Java 控制器总是返回 404
【发布时间】:2020-12-19 05:03:50
【问题描述】:

我按照 Spring Boot 文档中的示例进行操作,但由于某种原因,Java 控制器总是返回 404

这是我尝试过的

package com.example.accessingdatamysql;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller // This means that this class is a Controller
@RequestMapping(path="/demo") // This means URL's start with /demo (after Application path)
public class MainController {
  @Autowired // This means to get the bean called userRepository
         // Which is auto-generated by Spring, we will use it to handle the data
  private UserRepository userRepository;

  @PostMapping(path="/add") // Map ONLY POST Requests
  public @ResponseBody String addNewUser (@RequestParam String name
      , @RequestParam String email) {
    // @ResponseBody means the returned String is the response, not a view name
    // @RequestParam means it is a parameter from the GET or POST request

    User n = new User();
    n.setName(name);
    n.setEmail(email);
    userRepository.save(n);
    return "Saved";
  }

  @GetMapping(path="/all")
  public @ResponseBody Iterable<User> getAllUsers() {
    // This returns a JSON or XML with the users
    return userRepository.findAll();
  }
}

这里是spring boot给出的例子https://spring.io/guides/gs/accessing-data-mysql/

那我也试了

@RestController
@RequestMapping("/demo")
public class GreetingClass {

    @GetMapping("/greeting")
    public String getGreeting() {
        return "hello";
    }
}

.pom 文件:

<?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.3.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.braintobytes</groupId>
    <artifactId>Finance_microservice</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Finance_microservice</name>
    <description>Finance service</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <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-mail</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api -->
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

我知道这很奇怪,我按照页面上的说明设置了所有内容,但显然没有任何效果,我还检查了与此类似的其他问题,他们都没有回答我的问题。

好像是tomcat服务器被击中了,因为它说当我打电话时

o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms

然后我得到这个调用 curl 'http://localhost:8080/demo/greeting' 和 'http://localhost:8080/demo/all'

curl : 远程服务器返回错误:(404) Not Found.

日志(第一行去掉文件路径):

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.2.RELEASE)

2020-08-31 08:19:16.508  INFO 20708 --- [           main] c.b.f.FinanceMicroserviceApplication     : Starting FinanceMicroserviceApplication on DESKTOP-A65224I with PID 20708 ()
2020-08-31 08:19:16.510  INFO 20708 --- [           main] c.b.f.FinanceMicroserviceApplication     : No active profile set, falling back to default profiles: default
2020-08-31 08:19:17.096  INFO 20708 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-08-31 08:19:17.101  INFO 20708 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-08-31 08:19:17.101  INFO 20708 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-08-31 08:19:17.150  INFO 20708 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-08-31 08:19:17.150  INFO 20708 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 618 ms
2020-08-31 08:19:17.465  INFO 20708 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-31 08:19:17.675  INFO 20708 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-08-31 08:19:17.681  INFO 20708 --- [           main] c.b.f.FinanceMicroserviceApplication     : Started FinanceMicroserviceApplication in 1.328 seconds (JVM running for 1.835)
2020-08-31 08:20:21.893  INFO 20708 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-08-31 08:20:21.893  INFO 20708 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-08-31 08:20:21.905  INFO 20708 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 12 ms

回复:

{
    "timestamp": "2020-08-31T13:20:21.930+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "",
    "path": "/demo/greeting"
}

如果我这样做,这将有效:

https://github.com/BraintoByte/Test_App_Stack/tree/master/demo

不同的例子:

我附上了一个不同的例子,其层次结构完全相同,但省略了业务逻辑:

控制器中的代码:

package com.braintobytes.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.braintobytes.data.Currency;
import com.braintobytes.data.repository.CurrencyRepository;

@RestController
@RequestMapping("/demo")
public class CurrencyController {
    @Autowired
    private CurrencyRepository currencyRepository;
    
    @GetMapping("/currency")
    public String getCurrency() {
        return "currency";
    }
}

项目层次结构:

完全相同的 pom 和 application.properties:

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mydatabase
spring.datasource.username=myusername
spring.datasource.password=mypassword

【问题讨论】:

  • 你能发布你的 pom.xml 吗?
  • 您是否为您的应用程序设置了任何上下文路径?添加:如果您的程序运行成功,请检查您的日志,您可能会看到您的应用程序的整个基本链接,不包括您的控制器路径
  • @Brain Bytes 你能添加日志吗?使用日志很容易识别问题
  • @AvijitBarua 我发布了抱歉
  • @Sahit 我把它们都贴出来了

标签: java spring-boot api rest tomcat


【解决方案1】:

您的控制器在包中 - com.example.accessingdatamysql

Spring boot 启动日志显示您的主应用程序类 c.b.f.FinanceMicroserviceApplication 在另一个不相关的包层次结构中。

Spring boot 建议将主应用程序类定位在根包中的其他类之上,以便组件扫描开箱即用。

如果您将 com.example 包保留为根包并将您的主应用程序类 FinanceMicroserviceApplication 移至它,那么一切都应该按预期工作。

如果您不遵循 Spring Boot 对包层次结构的建议,那么您需要使用 @SpringBootApplication 注解显式指定要扫描的包。

【讨论】:

  • 我做了,打包 com.braintobytes.finance;导入 org.springframework.boot.SpringApplication;导入 org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication 公共类 FinanceMicroserviceApplication { public static void main(String[] args) { SpringApplication.run(FinanceMicroserviceApplication.class, args); } }
  • @BrainBytes 将 "package com.braintobytes.finance;" 替换为 "package com.example;"然后 com.example 包将成为层次结构中的根包,组件扫描将立即可用。
【解决方案2】:

好吧,上面的建议都没有奏效,但我们走在正确的道路上。

改变结构:

application.properties 中也存在路径问题,因此我更改为:

spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}

收件人:

jdbc:mysql://localhost

最后:

package com.braintobytes.finance.data.repository;

import org.springframework.data.repository.CrudRepository;

import com.braintobytes.finance.data.Currency;

public interface CurrencyRepository extends CrudRepository<Currency, Integer> {

}

哇!

【讨论】:

  • 我很高兴听到至少这些答案可以帮助您找到解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-26
  • 2010-11-07
  • 2016-10-30
相关资源
最近更新 更多