Nafaz M N M
Nafaz M N M

Reputation: 1688

Spring Webflux returns 404 ( Not Foud )

I have to save some values in a reactive way using spring Webflux. But when I send the request then 404 status is returned as a response.

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 class

@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);
             });
    }
}

When I send the request via PostMan then 404(not found) is returned.

enter image description here enter image description here

Upvotes: 3

Views: 6761

Answers (4)

Kirill Parfenov
Kirill Parfenov

Reputation: 653

I had the same problem. The solution:

  1. go to application.properties,
  2. remove server.servlet.context-path
  3. and add spring.webflux.base-path

Upvotes: 4

Ankush Sharma
Ankush Sharma

Reputation: 140

You need to remove below Jersey dependency.

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

The reason behind is that the spring-boot-starter-jersey is a starter for building Restful web applications using JAX-RS and Jersey. Since you have used it in your project the spring does not use in built spring functions for rest api's like @GetMapping, @PostMapping. If you want to use jersey to create the rest api then use @GET annotation for Get api and the @Produces to defined the mapping as below.

Eg.

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";
    }
}

Also you have to register this class in 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);
    }
}

And if you want to go ahead with the spring build in functions and use reactive just remove the jersey dependency and use webflux dependency to create your rest api's.

Upvotes: 0

Toerktumlare
Toerktumlare

Reputation: 14712

JAX-RS is a specification within Java EE of how to code REST api's. Several libraries have then implemented said specification, Like Jersey or restEasy. WHen building a Java EE application, you needed one of these libraries to be able to build a rest api.

Spring built their own way of building rest apis spring-web for non reactive applications, and spring-webflux for reactive applications.

Jersey and restEasy (to my knowledge) only works if you are building a non-reactive application.

In order to make your code work you need to remove:

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

Jersey is a Java EE implementation of JAX-RS. It is used in Java EE to build Java EE styled rest apis. You are building a reactive application, using Spring Webflux which has its own way of building REST api's.

Spring is not a Java EE application. When you added that dependency, spring assumed that you wanted to build a Spring Application but not use the Spring built in REST api functions and annotations etc, so it didn't register your code, that you have written with Springs way of building rest apis.

It assumed you were going to write a REST api the "jersey way" and if you are using jersey you need to register your api classes manually. And (to my knowledge) Jersey only works with non-webflux applications.

This is all mainly basic knowledge, and if you dont understand why i suggest you read up and build a regular spring boot application, before trying out webflux.

I suggest you read the following parts:

Reactive programming, Reactor getting started

Baeldung Webflux

Building a reactive Webflux Application

Spring boot Webflux

Upvotes: 3

Vipul Kumar
Vipul Kumar

Reputation: 479

It is Strange but when I removed jersey dependency and it Worked. Still not sure about the reason behind it. raised pull request you the merge the same to take the changes I have done https://github.com/Benzeman97/reactive-async-app/pull/1

Upvotes: 0

Related Questions