MVC 및 Rest와 함께 Spring Framework 4.0.7을 사용하고 있습니다.
나는 평화롭게 일할 수 있습니다 :
@Controller
ResponseEntity<T>
예를 들면 다음과 같습니다.
@Controller
@RequestMapping("/person")
@Profile("responseentity")
public class PersonRestResponseEntityController {
이 방법으로 (만들기 만하면)
@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);
}
무언가를 돌려주기 위해
@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);
}
잘 작동
나는 다음과 같이 할 수 있습니다 :
@RestController
(나는@Controller
+ 와 동일하다는 것을 알고있다@ResponseBody
)@ResponseStatus
예를 들면 다음과 같습니다.
@RestController
@RequestMapping("/person")
@Profile("restcontroller")
public class PersonRestController {
이 방법으로 (만들기 만하면)
@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());
}
무언가를 돌려주기 위해
@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;
}
내 질문은 :
- 때 고체 이유로 또는 특정 시나리오 하나의 옵션 다른 이상 의무적으로 사용해야합니다
- (1)이 중요하지 않은 경우 어떤 접근 방식이 제안되며 그 이유는 무엇입니까?
답변
ResponseEntity
전체 HTTP 응답을 나타냅니다. 상태 코드, 헤더 및 본문과 관련된 모든 것을 제어 할 수 있습니다.
@ResponseBody
는 HTTP 응답 본문의 표시 자이며 HTTP 응답 @ResponseStatus
의 상태 코드를 선언합니다.
@ResponseStatus
매우 유연하지 않습니다. 전체 메소드를 표시하므로 핸들러 메소드가 항상 동일한 방식으로 작동하는지 확인해야합니다. 그리고 여전히 헤더를 설정할 수 없습니다. HttpServletResponse
또는 HttpHeaders
매개 변수 가 필요합니다 .
기본적으로 ResponseEntity
더 많은 일을 할 수 있습니다.
답변
Sotorios Delimanolis의 답변을 완성합니다.
ResponseEntity
더 많은 유연성 을 제공하는 것이 사실 이지만 대부분의 경우 필요하지 않으며 ResponseEntity
컨트롤러의 모든 곳에서 결과를 읽고 이해하기가 어렵습니다.
오류 (찾을 수 없음, 충돌 등)와 같은 특수한 경우를 처리 HandlerExceptionResolver
하려면 스프링 구성에을 추가하면 됩니다. 따라서 코드에서 특정 예외 ( NotFoundException
예 :)를 throw하고 처리기에서 수행 할 작업 (HTTP 상태를 404로 설정)을 결정하면 컨트롤러 코드가 더 명확 해집니다.
답변
공식 문서에 따르면 @RestController 주석으로 REST 컨트롤러 작성
@RestController는 @ResponseBody와 @Controller를 결합한 스테레오 타입 주석입니다. 또한 컨트롤러에 더 많은 의미를 부여하고 향후 프레임 워크 릴리스에서 추가 의미를 가질 수 있습니다.
@RestController
명확성 을 위해 사용하는 것이 가장 좋지만 필요할 때 유연성 을 위해 결합 할 수도 있습니다 ResponseEntity
( 공식 튜토리얼 및 여기에 나와 있는 코드 와 내 질문에 따르면 ).
예를 들면 다음과 같습니다.
@RestController
public class MyController {
@GetMapping(path = "/test")
@ResponseStatus(HttpStatus.OK)
public User test() {
User user = new User();
user.setName("Name 1");
return user;
}
}
와 같다:
@RestController
public class MyController {
@GetMapping(path = "/test")
public ResponseEntity<User> test() {
User user = new User();
user.setName("Name 1");
HttpHeaders responseHeaders = new HttpHeaders();
// ...
return new ResponseEntity<>(user, responseHeaders, HttpStatus.OK);
}
}
이런 식으로 ResponseEntity
필요할 때만 정의 할 수 있습니다 .
최신 정보
이것을 사용할 수 있습니다 :
return ResponseEntity.ok().headers(responseHeaders).body(user);
답변
적절한 REST API는 응답 아래 구성 요소를 가져야합니다.
- 상태 코드
- 응답 본문
- 변경된 리소스의 위치 (예 : 리소스가 생성 된 경우 클라이언트는 해당 위치의 URL을 알고 싶어 함)
ResponseEntity의 주요 목적은 옵션 3을 제공하는 것이 었으며 나머지 옵션은 ResponseEntity 없이도 달성 할 수 있습니다.
따라서 리소스의 위치를 제공하려면 ResponseEntity를 사용하는 것이 좋습니다. 그렇지 않으면 피할 수 있습니다.
언급 된 모든 옵션을 제공하도록 API가 수정 된 예를 고려하십시오.
// Step 1 - Without any options provided
@RequestMapping(value="/{id}", method=RequestMethod.GET)
public @ResponseBody Spittle spittleById(@PathVariable long id) {
return spittleRepository.findOne(id);
}
// Step 2- We need to handle exception scenarios, as step 1 only caters happy path.
@ExceptionHandler(SpittleNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Error spittleNotFound(SpittleNotFoundException e) {
long spittleId = e.getSpittleId();
return new Error(4, "Spittle [" + spittleId + "] not found");
}
// Step 3 - Now we will alter the service method, **if you want to provide location**
@RequestMapping(
method=RequestMethod.POST
consumes="application/json")
public ResponseEntity<Spittle> saveSpittle(
@RequestBody Spittle spittle,
UriComponentsBuilder ucb) {
Spittle spittle = spittleRepository.save(spittle);
HttpHeaders headers = new HttpHeaders();
URI locationUri =
ucb.path("/spittles/")
.path(String.valueOf(spittle.getId()))
.build()
.toUri();
headers.setLocation(locationUri);
ResponseEntity<Spittle> responseEntity =
new ResponseEntity<Spittle>(
spittle, headers, HttpStatus.CREATED)
return responseEntity;
}
// Step4 - If you are not interested to provide the url location, you can omit ResponseEntity and go with
@RequestMapping(
method=RequestMethod.POST
consumes="application/json")
@ResponseStatus(HttpStatus.CREATED)
public Spittle saveSpittle(@RequestBody Spittle spittle) {
return spittleRepository.save(spittle);
}
근원-행동 봄