【问题标题】:Spring Webflux returns 404 ( Not Foud )Spring Webflux 返回 404 (未找到)
【发布时间】:2020-08-24 04:10:44
【问题描述】:

我必须使用 spring Webflux 以反应方式保存一些值。但是当我发送请求时,会返回 404 状态作为响应。

pom.xml

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

EmpController 类

@RestController
@RequestMapping("/emp")
public class EmpController {

    private EmployeeRepository empRepo;

    @Autowired
    public EmpController(EmployeeRepository empRepo)
    {
        this.empRepo=empRepo;
    }

    @PostMapping("/save")
    @Consumes({MediaType.APPLICATION_JSON})
    public void saveEmp(@RequestBody Mono<Employee> emp)
    {
             emp.subscribe(e-> {
                 e.setDate(new Date());
                 empRepo.saveEmp(e);
             });
    }
}

当我通过 PostMan 发送请求时,返回 404(未找到)。

【问题讨论】:

  • 确保您的EmpController@ComponentScan 下关注。如果您没有放置任何@ComponentScan,请确保您已将文件放置在您的main() 所在的相同或子包下。您可以在此处分享您的项目结构以进一步了解或创建 GitHub 存储库并分享 URL。
  • @Vipul Kumar 在这里 Github repo 链接github.com/Benzeman97/reactive-async-app.git
  • jersey 依赖是unneded。春天不使用球衣
  • 删除jersey@ThomasAndolf 后它工作了。如果可能,请告诉我原因

标签: java spring spring-boot reactive-programming spring-webflux


【解决方案1】:

JAX-RSJava EE 中关于如何编写 REST api 的规范。几个库已经实现了上述规范,比如JerseyrestEasy。在构建 Java EE 应用程序时,您需要其中一个库来构建一个 rest api。

Spring 构建了自己的方式来构建 rest api spring-web 用于非响应式应用程序,spring-webflux 用于响应式应用程序。

JerseyrestEasy(据我所知)仅在您构建非反应式应用程序时才有效。

为了使您的代码正常工作,您需要删除:

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

JerseyJAX-RS 的 Java EE 实现。它在 Java EE 中用于构建 Java EE 样式的 rest api。您正在构建一个反应式应用程序,使用 Spring Webflux,它有自己的构建 REST api 的方式。

Spring 不是 Java EE 应用程序。当您添加该依赖项时,spring 假设您想要构建一个 Spring 应用程序但不使用 Spring 内置的 REST api 函数和注释等,因此它没有注册您的代码,您使用 Springs 编写的构建 rest apis 的方式.

假设您要以“球衣方式”编写 REST api,如果您使用球衣,则需要手动注册您的 api 类。而且(据我所知)Jersey 仅适用于非 webflux 应用程序。

这主要是基础知识,如果你不明白为什么我建议你在尝试 webflux 之前阅读并构建一个常规的 spring boot 应用程序。

我建议你阅读以下部分:

Reactive programming, Reactor getting started

Baeldung Webflux

Building a reactive Webflux Application

Spring boot Webflux

【讨论】:

    【解决方案2】:

    这很奇怪,但是当我删除 jersey 依赖项并且它起作用了。仍然不确定其背后的原因。 提出拉取请求您合并相同以进行我所做的更改 https://github.com/Benzeman97/reactive-async-app/pull/1

    【讨论】:

      【解决方案3】:

      您需要删除以下 Jersey 依赖项。

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

      背后的原因是 spring-boot-starter-jersey 是使用 JAX-RS 和 Jersey 构建 Restful Web 应用程序的启动器。由于您已经在项目中使用了它,因此 spring 不会在内置的 spring 函数中使用诸如 @GetMapping、@PostMapping 之类的 rest api。 如果您想使用 jersey 创建其余 api,请使用 @GET 注释获取 api 和 @Produces 来定义映射,如下所示。

      例如。

      import javax.ws.rs.GET;
      import javax.ws.rs.Path;
      import javax.ws.rs.Produces;
      import org.springframework.stereotype.Service;
      
      @Service
      @Path("/hello")
      public class HelloService {
      
          @GET
          @Produces("text/plain")
          public String hello() {
              return "Hello from Spring";
          }
      }
      

      您还必须在 JerseyConfig 中注册此类。

      import com.zetcode.endpoint.HelloService;
      import org.glassfish.jersey.server.ResourceConfig;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      public class JerseyConfig extends ResourceConfig {
      
          public JerseyConfig() {
              
              register(HelloService.class);
          }
      }
      

      如果你想继续使用 spring 内置函数并使用响应式,只需删除 jersey 依赖项并使用 webflux 依赖项来创建你的 rest api。

      【讨论】:

      • 我什至不确定球衣是否可以用于响应式应用。你能确认一下吗?
      • 是的,它不能用于响应式应用程序。对于响应式,我们必须使用 webflux 删除球衣依赖。
      【解决方案4】:

      我遇到了同样的问题。 解决办法:

      1. 转到 application.properties,
      2. 删除 server.servlet.context-path
      3. 并添加 spring.webflux.base-path

      【讨论】: