Aetherus
Aetherus

Reputation: 8888

Spring MVC routes to wrong action

I have the following controller (following Rails naming convention)

@RestController("/vehicles")
public class VehiclesController {

    @GetMapping
    public Iterable<Vehicle> index(
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "25") int per
    ) {
        ...
    }

    @GetMapping("/{id}")
    public Vehicle show(@PathVariable long id) {
        ...
    }

    @PostMapping
    public Vehicle create(@RequestBody Vehicle vehicle) {
        ...
    }

    @PatchMapping("/{id}")
    public void update(@PathVariable long id, @RequestBody Vehicle params) {
        ...
    }

    @DeleteMapping("/{id}")
    public void destroy(@PathVariable long id) {
        ...
    }

}

Every time I send the request

GET /vehicles

I expect the request gets routed to the index method, but it actually is routed to the show method then failed to serve the content because the framework can't convert "vehicles" to a long. Here is the error message:

Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'long'; nested exception is java.lang.NumberFormatException: For input string: "vehicles"

Is there anything wrong in my code? Thanks in advance.

Upvotes: 0

Views: 869

Answers (2)

db80
db80

Reputation: 4427

This is not correct.

@RestController("/vehicles")

The value ("/vehicles") is the name of the Component

In order to add a REST path you need @RestController annotation and @RequestMapping annotations on the class.

@RestController()
@RequestMapping(value = "/vehicles")

The value /vehicles is the suffix of your HTTP call.

You must change also the annotation on your index method:

@RequestMapping(value = "", method = RequestMethod.GET)
public Iterable<Vehicle> index(
    @RequestParam(defaultValue = "1") int page,
    @RequestParam(defaultValue = "25") int per
)

and everything should work as expected.

Upvotes: 0

Maciej Walkowiak
Maciej Walkowiak

Reputation: 12932

The value property of @RestController annotation is not a path prefix but a bean name. To give all annotated methods in your controller a prefix, annotate controller class with @RequestMapping("/vehicles").

@RestController
@RequestMapping("/vehicles")
public class VehiclesController {

    @GetMapping
    public Iterable<Vehicle> index(
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "25") int per
    ) {
        ...
    }

    ...
}

Upvotes: 1

Related Questions