Spring @ResponseBody 주석은 어떻게 작동합니까?


89

다음과 같은 방법으로 주석이 달린 메서드가 있습니다.

/**
* Provide a list of all accounts.
*/
//  TODO 02: Complete this method.  Add annotations to respond
//  to GET /accounts and return a List<Account> to be converted.
//  Save your work and restart the server.  You should get JSON results when accessing 
//  http://localhost:8080/rest-ws/app/accounts
@RequestMapping(value="/orders", method=RequestMethod.GET)
public @ResponseBody List<Account> accountSummary() {
    return accountManager.getAllAccounts();
}

그래서 저는이 주석으로 알고 있습니다.

@RequestMapping(value="/orders", method=RequestMethod.GET)

이 메서드 는 URL / orders로 표시되는 리소스에 대한 GET HTTP 요청을 처리 합니다 .

이 메서드는 List 를 반환하는 DAO 개체를 호출합니다 .

여기서 Account 는 시스템의 사용자를 나타내며 다음과 같이이 사용자를 나타내는 일부 필드가 있습니다.

public class Account {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long entityId;

    @Column(name = "NUMBER")
    private String number;

    @Column(name = "NAME")
    private String name;

    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name = "ACCOUNT_ID")
    private Set<Beneficiary> beneficiaries = new HashSet<Beneficiary>();

    ...............................
    ...............................
    ...............................
}

내 질문은 : 주석 이 정확히 어떻게 @ResponseBody작동합니까?

반환 된 List<Account>객체 앞에 위치하므로이 목록을 참조한다고 생각합니다. 코스 문서에는이 주석이 다음과 같은 기능을 제공한다고 명시되어 있습니다.

결과가 HTTP 메시지 변환기 (MVC보기 대신)에 의해 HTTP 응답에 기록되는지 확인하십시오.

또한 공식 Spring 문서에서 읽기 : http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html

그것은 List<Account>객체를 가져 와서 Http Response. 이것이 맞습니까 아니면 오해입니까?

이전 accountSummary()방법 의 주석 에는 다음이 기록됩니다.

http : // localhost : 8080 / rest-ws / app / accounts에 액세스 할 때 JSON 결과를 받아야 합니다.

이것이 정확히 무엇을 의미합니까? 것을 그것은 뜻 List<Account>에 의해 반환 된 객체 accountSummary()메소드가 자동으로 변환되어 JSON포맷 한 다음에 넣어 Http Response? 또는 무엇을?

이 어설 션이 참이면 개체가 자동으로 JSON형식 으로 변환되도록 지정하는 곳은 어디 입니까? @ResponseBody주석이 사용될 때 표준 형식이 채택 됩니까 아니면 다른 곳에 지정되어 있습니까?

답변:


160

우선, 주석은 주석을 달지 않습니다 List. 마찬가지로 방법에 주석을 답니다 RequestMapping. 귀하의 코드는

@RequestMapping(value="/orders", method=RequestMethod.GET)
@ResponseBody
public List<Account> accountSummary() {
    return accountManager.getAllAccounts();
}

이제 주석이 의미하는 것은 메서드의 반환 된 값이 HTTP 응답의 본문을 구성한다는 것입니다. 물론 HTTP 응답에는 Java 개체가 포함될 수 없습니다. 따라서이 계정 목록은 REST 애플리케이션에 적합한 형식 (일반적으로 JSON 또는 XML)으로 변환됩니다.

형식의 선택은의 값에 설치된 메시지 컨버터에 따라 produces속성@RequestMapping주석, 클라이언트가 받아들이는 콘텐츠 형식에 (즉, HTTP 요청 헤더에서 사용할 수 있습니다). 예를 들어, 요청이 XML을 받아들이지 만 JSON은 받아들이지 않는다고 말하고 목록을 XML로 변환 할 수있는 메시지 변환기가 설치되어있는 경우 XML이 반환됩니다.


3
안녕하세요, "설치된 메시지 변환기"를 어떻게 설정합니까? 기본값은 항상 Json으로 변환하고 싶습니다. 내가 할 수 있습니까?
샘 YC

@JB Nizet은 http 응답이 Java 객체를 포함 할 수없는 이유를 설명해 주시겠습니까? 나는 자바의 새 벌이다.
Naved Ali

3
@ Er.NavedAli는 http 사양을 읽고 http 응답 콘텐츠 유형은 http 응답에 포함될 수있는 법적 콘텐츠를 정의합니다. 이에 대한 유효한 값은 "application / octet-stream", "image / jpeg", "text / HTML"일 수 있지만 Java 객체는 이에 대한 유효한 값이 아닙니다.
ZhaoGang 2011

@ZhaoGang, Content-type 'application / json'은 내 테스트 케이스에서 'application / xml'로 대체되었지만 응답 본문은 변경되지 않고 여전히 json 형식을 제공합니다.
LeafiWan 2016

1
정확히 어떤 스프링 클래스에서 응답을 반환할지 결정하는 결정이 내려진 것을 의미합니까? 이 결정이 완료된 github의 소스 또는 클래스 이름을 알려 주시겠습니까? 또한 클라이언트가 XML을 수락하지만 XML 변환기가 설치되어 있지 않으면 어떻게됩니까?
anir

65

이해해야 할 첫 번째 기본 사항은 아키텍처의 차이입니다.

한쪽 끝에는 웹 페이지를 사용하는 일반 웹 앱을 기반으로하는 MVC 아키텍처가 있으며 브라우저는 페이지를 요청합니다.

Browser <---> Controller <---> Model
               |      |
               +-View-+

브라우저가 요청을하고 컨트롤러 (@Controller)가 모델 (@Entity)을 가져 와서 모델에서보기 (JSP)를 생성하고보기가 클라이언트로 다시 반환됩니다. 이것이 기본 웹 앱 아키텍처입니다.

반면에 RESTful 아키텍처가 있습니다. 이 경우에는보기가 없습니다. 컨트롤러는 모델 (또는보다 RESTful 용어로 리소스 표현) 만 다시 보냅니다. 클라이언트는 JavaScript 애플리케이션, Java 서버 애플리케이션, REST API를 노출하는 모든 애플리케이션이 될 수 있습니다. 이 아키텍처를 통해 클라이언트는이 모델로 수행 할 작업을 결정합니다. 예를 들어 트위터를 보자. Twitter as the Web (REST) ​​API는 애플리케이션이 API를 사용하여 상태 업데이트와 같은 정보를 얻을 수 있도록하여 해당 데이터를 애플리케이션에 넣을 수 있도록합니다. 해당 데이터는 JSON과 같은 형식으로 제공됩니다.

즉, Spring MVC로 작업 할 때 기본 웹 애플리케이션 아키텍처를 처리하기 위해 처음 빌드되었습니다. 우리의 메소드에서 뷰를 생성 할 수있는 다양한 메소드 시그니처 플레이버가있을 수 있습니다. 메서드 ModelAndView는 명시 적으로 생성 한 위치를 반환 하거나 모델 속성으로 설정되는 임의의 객체를 반환 할 수있는 암시 적 방법이 있습니다. 그러나 어느 쪽이든 요청-응답주기의 어딘가에 뷰가 생성됩니다.

그러나를 사용할 때 우리 @ResponseBody는 뷰가 생성되는 것을 원하지 않는다는 의미입니다. 지정하는 형식에 관계없이 반환 객체를 본문으로 보내려고합니다. (가능하지만) 직렬화 된 Java 객체가되는 것을 원하지 않습니다. 따라서 예, 다른 일반적인 유형으로 변환해야합니다 (이 유형은 일반적으로 콘텐츠 협상을 통해 처리됩니다. 아래 링크 참조). 솔직히 여기저기서 다루지 만 Spring과 많이 일하지 않는다. 일반적으로 나는

@RequestMapping(..., produces = MediaType.APPLICATION_JSON_VALUE)

콘텐츠 유형을 설정하지만 JSON이 기본값 일 수 있습니다. 저를 인용하지 마십시오.하지만 JSON을 받고 있고을 지정하지 않은 경우 produces기본값 일 수 있습니다. JSON은 유일한 형식이 아닙니다. 예를 들어, 위의 쉽게 XML로 전송 될 수 있지만, 당신은이해야 producesMediaType.APPLICATION_XML_VALUE나는 당신이를 구성 할 필요가 생각 HttpMessageConverterJAXB를 위해. MappingJacksonHttpMessageConverter구성된 JSON의 경우 클래스 경로에 Jackson이있을 때.

콘텐츠 협상 에 대해 배우려면 시간이 좀 걸릴 것 입니다. REST의 매우 중요한 부분입니다. 다양한 응답 형식과이를 방법에 매핑하는 방법을 배우는 데 도움이됩니다.


.NET을 사용하지 않고 일반 / 동적 REST 컨트롤러를 만드는 방법에 대한 조사 중에 답변을 찾은 경우 @Controller/@RestController. 뷰 리졸버 레이어를 어떻게 든 생략해야한다는 것을 발견했습니다. AbstractController 클래스는 뷰 이름을 반환해야하는 메서드를 제공하기 때문에 그렇게 간단하지 않습니다. 나는 그것에 대해 질문했다 : stackoverflow.com/questions/41016018/… , 내 문제를 어떻게 해결할 수 있을지에 대한 아이디어가 있다면, 댓글을 달아주세요.
nowszy94

1

또한 반환 유형은 다음과 같이 결정됩니다.

  1. HTTP 요청이 원하는 내용-Accept 헤더에서. Accept가 무엇으로 설정되어 있는지 확인하기 위해 초기 요청을 살펴보십시오.

  2. HttpMessageConverters Spring이 설정하는 것. Spring MVC는 Jackson 라이브러리가 클래스 경로에있는 경우 XML (JAXB 사용) 및 JSON에 대한 변환기를 설정합니다.

선택 사항이 있으면 하나를 선택합니다.이 예에서는 JSON이됩니다.

이것은 되는 과정을 노트에 덮여. 메시지 변환기 및 콘텐츠 협상에 대한 참고 사항을 찾으십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.