enbiya enbiya - 2 years ago 122
Java Question

Why RequestMapping annotation does't work with class in springboot application?

I'm trying to learn springbott with a sample. When I tried to call a restcontroller that was defined on the class, I got 404 error.

@RestController
@RequestMapping("/test")
public class ReservationResource {

public ResponseEntity<ReservationResponse> getAvaliableRooms(
@RequestParam(value = "checkin") @DateTimeFormat(iso = ISO.DATE) LocalDate checkin,
@RequestParam(value = "checkout") @DateTimeFormat(iso = ISO.DATE) LocalDate checkout) {

return new ResponseEntity<>(new ReservationResponse(), HttpStatus.OK);
}
}


This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Aug 16 16:18:05 EEST 2017
There was an unexpected error (type=Not Found, status=404).
No message available


But when I tried like below It worked!

@RestController
public class ReservationResource {

@RequestMapping("/test")
public ResponseEntity<ReservationResponse> getAvaliableRooms(
@RequestParam(value = "checkin") @DateTimeFormat(iso = ISO.DATE) LocalDate checkin,
@RequestParam(value = "checkout") @DateTimeFormat(iso = ISO.DATE) LocalDate checkout) {

return new ResponseEntity<>(new ReservationResponse(), HttpStatus.OK);
}
}


Why this differences occured? By the way I follow an example, the developer defined it like section one!

Answer Source

When you use the annotation @RestController means that your class will act as @Controller and all methods defined inside will have by default a @ResponseBody

But you need to define the specific path for each method inside your Controller.

For instance you could do:

@RestController
@RequestMapping("/test")
public class ReservationResource {

    @RequestMapping("/") 
    public ResponseEntity<ReservationResponse> getAvaliableRooms(
            @RequestParam(value = "checkin") @DateTimeFormat(iso = ISO.DATE) LocalDate checkin,
            @RequestParam(value = "checkout") @DateTimeFormat(iso = ISO.DATE) LocalDate checkout) {

        return new ResponseEntity<>(new ReservationResponse(), HttpStatus.OK);
    }

    @RequestMapping("/second") 
    public ResponseEntity<ReservationResponse> getAvaliableRooms(
                @RequestParam(value = "checkin") @DateTimeFormat(iso = ISO.DATE) LocalDate checkin,
                @RequestParam(value = "checkout") @DateTimeFormat(iso = ISO.DATE) LocalDate checkout) {

            return new ResponseEntity<>(new ReservationResponse(), HttpStatus.OK);
        }
    }

With this configuration you have defined a path in /test/ with GET method and other "/test/second" also GET, but by deafult all yours paths will start by "/test"

If you decide to use @RequestMapping at method level you can modify the path inside the same class.

For instance:

@RestController
public class ReservationResource {

        @RequestMapping("/test") 
        public ResponseEntity<ReservationResponse> getAvaliableRooms(
                @RequestParam(value = "checkin") @DateTimeFormat(iso = ISO.DATE) LocalDate checkin,
                @RequestParam(value = "checkout") @DateTimeFormat(iso = ISO.DATE) LocalDate checkout) {

            return new ResponseEntity<>(new ReservationResponse(), HttpStatus.OK);
        }

        @RequestMapping("/second") 
        public ResponseEntity<ReservationResponse> getAvaliableRooms(
                    @RequestParam(value = "checkin") @DateTimeFormat(iso = ISO.DATE) LocalDate checkin,
                    @RequestParam(value = "checkout") @DateTimeFormat(iso = ISO.DATE) LocalDate checkout) {

                return new ResponseEntity<>(new ReservationResponse(), HttpStatus.OK);
            }
        }

And both URL would be accessible with "/test" and "/second"

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download