복붙노트

[SPRING] Spring RESTful 애플리케이션을 위해 ResponseEntity <T>와 @RestController를 사용할 때

SPRING

Spring RESTful 애플리케이션을 위해 ResponseEntity 와 @RestController를 사용할 때

스프링 프레임 워크 4.0.7, MVC 및 나머지 함께 일하고 있습니다.

나는 평화롭게 일할 수 있습니다.

예 :

@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
@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. ==============================

    1.ResponseEntity는 전체 HTTP 응답을 나타냅니다. 상태 코드, 헤더 및 본문에 들어갈 내용을 제어 할 수 있습니다.

    ResponseEntity는 전체 HTTP 응답을 나타냅니다. 상태 코드, 헤더 및 본문에 들어갈 내용을 제어 할 수 있습니다.

    @ResponseBody는 HTTP 응답 본문의 표식이며 @ResponseStatus는 HTTP 응답의 상태 코드를 선언합니다.

    @ResponseStatus는 매우 유연하지 않습니다. 전체 메서드를 표시하므로 처리기 메서드가 항상 같은 방식으로 작동해야합니다. 그리고 여전히 헤더를 설정할 수 없습니다. HttpServletResponse 또는 HttpHeaders 매개 변수가 필요합니다.

    기본적으로 ResponseEntity를 사용하면 더 많은 작업을 수행 할 수 있습니다.

  2. ==============================

    2.Sotorios Delimanolis의 답변을 완료하십시오.

    Sotorios Delimanolis의 답변을 완료하십시오.

    ResponseEntity를 사용하면 유연성이 향상되지만 대부분의 경우에는 필요하지 않으며 컨트롤러의 모든 곳에서 이러한 ResponseEntity로 끝나기 때문에 읽고 이해하기가 어렵습니다.

    에러 (Not Found, Conflict, etc.)와 같은 특수한 케이스를 다루고 싶다면 HandlerExceptionResolver를 Spring 설정에 추가 할 수있다. 따라서 코드에서 특정 예외 (예를 들어 NotFoundException)를 던지고 Handler에서 수행 할 작업 (HTTP 상태를 404로 설정)을 결정하여 컨트롤러 코드를 더 명확하게 만듭니다.

  3. ==============================

    3.공식 문서에 따르면 : @RestController 어노테이션으로 REST 컨트롤러 생성하기

    공식 문서에 따르면 : @RestController 어노테이션으로 REST 컨트롤러 생성하기

    그것은 명확성을 위해 @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);
    
  4. ==============================

    4.적절한 REST API는 응답으로 구성 요소 아래에 있어야합니다.

    적절한 REST API는 응답으로 구성 요소 아래에 있어야합니다.

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

    출처 - 행동중인 봄

  5. from https://stackoverflow.com/questions/26549379/when-use-responseentityt-and-restcontroller-for-spring-restful-applications by cc-by-sa and MIT license