2017-08-16 9 views
0

J'essaie d'apprendre springbott avec un échantillon. Quand j'ai essayé d'appeler un restcontroller qui a été défini sur la classe, j'ai eu une erreur 404.Pourquoi l'annotation RequestMapping ne fonctionne pas avec la classe dans l'application springboot?

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

Cette application n'a pas de mappage explicite/erreur, si vous voyez cela comme une solution de repli. Wed Aug 16 16:18:05 EEST 2017 Une erreur inattendue s'est produite (type = Not Found, status = 404). Aucun message disponible

Mais quand j'ai essayé comme ci-dessous Cela a fonctionné!

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

Pourquoi ces différences se sont-elles produites? En passant je suis un exemple, le développeur l'a défini comme la première section!

Répondre

1

Lorsque vous utilisez le @RestController d'annotation signifie que votre classe agira comme @Controller et toutes les méthodes définies à l'intérieur aura par défaut un @ResponseBody

Mais vous devez définir le chemin spécifique pour chaque méthode dans votre contrôleur.

Par exemple, vous pouvez faire:

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

Avec cette configuration, vous avez défini un chemin dans/test/avec la méthode GET et d'autres «/test/seconde » GET aussi, mais par deafult tous les chemins de vôtre Commencez par "/ test"

Si vous décidez d'utiliser @RequestMapping au niveau de la méthode, vous pouvez modifier le chemin dans la même classe.

Par exemple:

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

Et les deux URL serait accessible avec «/test » et «/seconde »

1

parce que si vous utilisez @RequestMapping au niveau de la classe, il ne saura pas quelle méthode pour exécuter en tant que votre classe peut avoir plusieurs méthodes

+0

mais maintenant, il n'y a qu'une méthode? –

1

Vous devez annoter votre méthode avec @RequestMapping. Le contrôleur ne peut pas savoir quelle méthode doit être exécutée s'il n'y a pas d'annotation.

@RequestMapping("/test") 
Class Level 

@RequestMapping 
Mehtod Level 

Reachable = http://localhost:8080/test 

@RequestMapping("/test") 
Class Level 

@RequestMapping("/abc") 
Mehtod Level 

Reachable = http://localhost:8080/test/abc 

@RequestMapping("/test") 
Class Level 

@RequestMapping("/abc") 
Mehtod Level 

@RequestMapping("/def") 
Mehtod Level 

Reachable = http://localhost:8080/test/abc 
Reachable = http://localhost:8080/test/def 
+0

mais maintenant, il n'y a qu'une seule méthode? –

+0

oui, au niveau de la classe c'est juste le préfixe url. Au niveau de la méthode, vous pouvez définir le suffixe. Ou laissez le niveau de classe emtpy et définissez simplement votre mapping au niveau de la méthode. c'est ton choix – Patrick

1

/test est une application de niveau de classe pour le contrôleur et afin de rendre la getAvaliableRooms() admissible méthode public au service des demandes, vous devez ajouter à votre méthode @RequestMapping("")getAvaliableRooms() comme indiqué ci-dessous:

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

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

En d'autres termes, vous indiquez explicitement au conteneur Spring que parmi les méthodes public à l'intérieur de la classe de contrôleur, il est réellement prévu de servir les requêtes.