Pracuję na Spring Framework 4.0.7, razem z MVC i Rest
Mogę pracować w zgodzie z:
@Controller
ResponseEntity<T>
Na przykład:
@Controller
@RequestMapping("/person")
@Profile("responseentity")
public class PersonRestResponseEntityController {
Metodą (tylko do tworzenia)
@RequestMapping(value="/", method=RequestMethod.POST)
public ResponseEntity<Void> createPerson(@RequestBody Person person, UriComponentsBuilder ucb){
logger.info("PersonRestResponseEntityController - createPerson");
if(person==null)
logger.error("person is null!!!");
else
logger.info("{}", person.toString());
personMapRepository.savePerson(person);
HttpHeaders headers = new HttpHeaders();
headers.add("1", "uno");
//http://localhost:8080/spring-utility/person/1
headers.setLocation(ucb.path("/person/{id}").buildAndExpand(person.getId()).toUri());
return new ResponseEntity<>(headers, HttpStatus.CREATED);
}
zwrócić coś
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public ResponseEntity<Person> getPerson(@PathVariable Integer id){
logger.info("PersonRestResponseEntityController - getPerson - id: {}", id);
Person person = personMapRepository.findPerson(id);
return new ResponseEntity<>(person, HttpStatus.FOUND);
}
Działa w porządku
Mogę zrobić to samo z :
@RestController
(Wiem, że to to samo niż@Controller
+@ResponseBody
)@ResponseStatus
Na przykład:
@RestController
@RequestMapping("/person")
@Profile("restcontroller")
public class PersonRestController {
Metodą (tylko do tworzenia)
@RequestMapping(value="/", method=RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void createPerson(@RequestBody Person person, HttpServletRequest request, HttpServletResponse response){
logger.info("PersonRestController - createPerson");
if(person==null)
logger.error("person is null!!!");
else
logger.info("{}", person.toString());
personMapRepository.savePerson(person);
response.setHeader("1", "uno");
//http://localhost:8080/spring-utility/person/1
response.setHeader("Location", request.getRequestURL().append(person.getId()).toString());
}
zwrócić coś
@RequestMapping(value="/{id}", method=RequestMethod.GET)
@ResponseStatus(HttpStatus.FOUND)
public Person getPerson(@PathVariable Integer id){
logger.info("PersonRestController - getPerson - id: {}", id);
Person person = personMapRepository.findPerson(id);
return person;
}
Moje pytania to:
- kiedy z solidnego powodu lub z konkretnego scenariusza jedna opcja musi być obowiązkowo stosowana nad drugą
- Jeśli (1) nie ma znaczenia, jakie podejście jest sugerowane i dlaczego.
źródło
ResponseEntity
, jest bardziej elastyczny. Po prostu miałem wątpliwości@RestController
. DziękujęAby uzupełnić odpowiedź od Sotorios Delimanolis.
To prawda, że
ResponseEntity
zapewnia to większą elastyczność, ale w większości przypadków nie będziesz jej potrzebować i skończysz z nimiResponseEntity
wszędzie w kontrolerze, co utrudni czytanie i zrozumienie.Jeśli chcesz zająć się przypadkami specjalnymi, takimi jak błędy (nie znaleziono, konflikt itp.), Możesz dodać
HandlerExceptionResolver
do swojej konfiguracji Springa. Tak więc w swoim kodzie po prostu rzucasz określony wyjątek (NotFoundException
na przykład) i decydujesz, co zrobić w swoim programie obsługi (ustawiając stan HTTP na 404), dzięki czemu kod kontrolera jest bardziej przejrzysty.źródło
Zgodnie z oficjalną dokumentacją: Tworzenie kontrolerów REST z adnotacją @RestController
Wydaje się, że najlepiej jest używać go
@RestController
dla jasności, ale można go również połączyć zResponseEntity
elastycznością w razie potrzeby ( zgodnie z oficjalnym samouczkiem i kodem tutaj i moim pytaniem, aby to potwierdzić ).Na przykład:
jest taki sam jak:
W ten sposób możesz zdefiniować
ResponseEntity
tylko wtedy, gdy jest to potrzebne.Aktualizacja
Możesz użyć tego:
źródło
@ResponseStatus(HttpStatus.OK)
jest ignorowany po powrocieResponseEntity<>(user, responseHeaders, HttpStatus.NOT_FOUND)
. Odpowiedź HTTP to404
Odpowiedni interfejs API REST powinien zawierać poniższe komponenty w odpowiedzi
Głównym celem ResponseEntity było zapewnienie opcji 3, pozostałe opcje można było osiągnąć bez ResponseEntity.
Jeśli więc chcesz podać lokalizację zasobu, lepiej byłoby użyć ResponseEntity, w przeciwnym razie można by tego uniknąć.
Rozważmy przykład, w którym interfejs API został zmodyfikowany w celu udostępnienia wszystkich wymienionych opcji
Źródło - Wiosna w akcji
źródło