ResponseEntity를 사용하는 경우 Spring RESTful 애플리케이션을위한 @RestController
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
isn't very flexible. It marks the entire method so you have to be sure that your handler method will always behave the same way. And you still can't set the headers. You'd need the HttpServletResponse
or a HttpHeaders
parameter.
Basically, ResponseEntity
lets you do more.
To complete the answer from Sotorios Delimanolis.
It's true that ResponseEntity
gives you more flexibility but in most cases you won't need it and you'll end up with these ResponseEntity
everywhere in your controller thus making it difficult to read and understand.
If you want to handle special cases like errors (Not Found, Conflict, etc.), you can add a HandlerExceptionResolver
to your Spring configuration. So in your code, you just throw a specific exception (NotFoundException
for instance) and decide what to do in your Handler (setting the HTTP status to 404), making the Controller code more clear.
According to official documentation: Creating REST Controllers with the @RestController annotation
@RestController is a stereotype annotation that combines @ResponseBody and @Controller. More than that, it gives more meaning to your Controller and also may carry additional semantics in future releases of the framework.
It seems that it's best to use @RestController
for clarity, but you can also combine it with ResponseEntity
for flexibility when needed (According to official tutorial and the code here and my question to confirm that).
For example:
@RestController
public class MyController {
@GetMapping(path = "/test")
@ResponseStatus(HttpStatus.OK)
public User test() {
User user = new User();
user.setName("Name 1");
return user;
}
}
is the same as:
@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);
}
}
This way, you can define ResponseEntity
only when needed.
Update
You can use this:
return ResponseEntity.ok().headers(responseHeaders).body(user);
A proper REST API should have below components in response
- Status Code
- Response Body
- Location to the resource which was altered(for example, if a resource was created, client would be interested to know the url of that location)
The main purpose of ResponseEntity was to provide the option 3, rest options could be achieved without ResponseEntity.
So if you want to provide the location of resource then using ResponseEntity would be better else it can be avoided.
Consider an example where a API is modified to provide all the options mentioned
// 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);
}
Source - Spring in Action
'Programming' 카테고리의 다른 글
Virtualenv에 다른 버전의 Python을 설치할 수 있습니까? (0) | 2020.06.15 |
---|---|
Java에서 개인 정적 변수를 사용하는 것은 무엇입니까? (0) | 2020.06.15 |
작업 또는 작업 세트별로 사용자를 전환하는 방법은 무엇입니까? (0) | 2020.06.15 |
DI 컨테이너를 통해 생성 된 객체를 초기화하는 패턴이 있습니까? (0) | 2020.06.15 |
Node.js에서 process.env.PORT은 (는) 무엇 이죠? (0) | 2020.06.15 |