2017-08-16 1 views
0

Ich versuche Springbott mit einer Probe zu lernen. Als ich versuchte, einen Restcontroller aufzurufen, der in der Klasse definiert war, bekam ich 404 Fehler.Warum RequestMapping Annotation funktioniert nicht mit Klasse in Springboot-Anwendung?

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

Diese Anwendung hat keine explizite Zuordnung für/Fehler, so dass Sie sehen dies als einen Rückfall. Mi Aug 16 16:18:05 EEST 2017 Es ist ein unerwarteter Fehler aufgetreten (Typ = Nicht gefunden, Status = 404). Keine Nachricht verfügbar

Aber als ich versuchte, wie unten Es funktionierte!

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

Warum diese Unterschiede aufgetreten sind? Ich folge übrigens einem Beispiel, der Entwickler hat es wie Abschnitt 1 definiert!

Antwort

1

Wenn Sie die Anmerkung @RestController bedeutet, dass Ihre Klasse als @Controller handeln und alle innerhalb definierten Methoden werden standardmäßig über eine @ResponseBody

Sie müssen jedoch den spezifischen Pfad für jede Methode in Ihrem Controller definieren.

Zum Beispiel könnten Sie tun:

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

Mit dieser Konfiguration Sie einen Pfad in/Test definiert haben/mit GET-Methode und anderen „/ test/Sekunde“ auch, aber durch deafult all deine Pfade start by "/ test"

Wenn Sie sich entscheiden, @RequestMapping auf Methodenebene zu verwenden, können Sie den Pfad innerhalb derselben Klasse ändern.

Zum Beispiel:

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

Und beide URL würde mit "/ test" und "/ Sekunde"

1

, denn wenn man @RequestMapping auf Klassenebene verwenden wird es nicht wissen, welche Methode auszuführen als Klasse mehrere Methoden

+0

aber jetzt gibt es nur eine Methode? –

1

Sie haben Ihre Methode mit @RequestMapping mit Anmerkungen versehen haben. Der Controller kann nicht wissen, welche Methode ausgeführt werden soll, wenn keine Anmerkung vorhanden ist.

@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

aber jetzt gibt es nur eine Methode? –

+0

Ja, auf Klassenebene ist es nur das Präfix URL. Auf Methodenebene können Sie das Suffix definieren. Oder lassen Sie die Klassenstufe empty und legen Sie Ihr Mapping nur auf Methodenebene fest. es ist Ihre Wahl – Patrick

1

/test ist ein Klasse Level-Mapping für den Controller und dann, um das zu machen zugänglich sein

@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); 
    } 
} 
: getAvaliableRooms() public Methode, die für Anfragen dienen, müssen Sie @RequestMapping("") auf Ihre getAvaliableRooms() Methode hinzufügen, wie unten gezeigt

Mit anderen Worten, Sie teilen dem Spring-Container explizit mit, welche der public-Methoden innerhalb der Controller-Klasse tatsächlich für das Bedienen der Anfragen gedacht ist.

Verwandte Themen