Spring @ResponseBody ek açıklaması nasıl çalışır?


92

Aşağıdaki şekilde açıklamalı bir yöntemim var:

/**
* 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();
}

Bu ek açıklamaya göre şunu biliyorum:

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

bu yöntem , URL / siparişler tarafından temsil edilen kaynağa yapılan GET HTTP isteklerini işler .

Bu yöntem bir DAO nesnesini çağırır. Liste .

nerede Hesap sistemde bir kullanıcıyı gösterir ve bu kullanıcıyı temsil bazı alanları vardır, gibi bir şey:

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

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

Sorum şu: @ResponseBody Ek açıklama tam olarak nasıl çalışıyor?

İade edilmeden önce bulunur List<Account> nesnenin aldığından bu Listeye atıfta bulunduğunu düşünüyorum. Kurs belgeleri, bu ek açıklamanın şu işlevi yerine getirdiğini belirtir:

sonucun bir HTTP Mesaj Dönüştürücüsü (MVC Görünümü yerine) tarafından HTTP yanıtına yazılacağından emin olun.

Ve ayrıca resmi Bahar belgelerini okuyunuz: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/ResponseBody.html

Görünüşe göre List<Account>nesneyi alıyor ve onuHttp Response . Bu doğru mu yoksa yanlış mı anlıyorum?

Önceki accountSummary()yöntemin yorumuna yazılanlar :

Http: // localhost: 8080 / rest-ws / app / accounts'e erişirken JSON sonuçlarını almalısınız

Peki bu tam olarak ne anlama geliyor? O anlamına mı List<Account>döndürdüğü nesne accountSummary()yöntemiyle otomatik dönüştürülür JSONiçine format ve ardından koymakHttp Response ? Ya da ne?

Bu iddia doğruysa, nesnenin otomatik olarak JSONformata dönüştürüleceği nerede belirtilir ? @ResponseBodyEk açıklama kullanıldığında standart format benimseniyor mu yoksa başka bir yerde mi belirtiliyor?

Yanıtlar:


163

Her şeyden önce, ek açıklama açıklama eklemiyor List. Yöntemi de olduğu gibi RequestMappingaçıklar. Kodunuz eşdeğerdir

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

Şimdi açıklamanın anlamı, yöntemin döndürülen değerinin HTTP yanıtının gövdesini oluşturacağıdır. Elbette bir HTTP yanıtı Java nesneleri içeremez. Dolayısıyla bu hesap listesi, genellikle JSON veya XML gibi REST uygulamaları için uygun bir biçime dönüştürülür.

Formatın seçimi değerlerine, yüklü mesajı dönüştürücüler bağlıdır producesözelliğin bir @RequestMappingaçıklama ve istemci kabul ettiği içerik türüne (yani HTTP istek başlıklarında mevcuttur). Örneğin, istek XML kabul ettiğini, ancak JSON kabul etmediğini söylüyorsa ve listeyi XML'e dönüştürebilen bir ileti dönüştürücü kuruluysa, XML döndürülür.


4
merhaba, "kurulu mesaj dönüştürücülerini" nasıl kurarız? Varsayılanın her zaman Json'a dönüştürülmesini istiyorum. Bunu yapabilir miyim?
Sam YC

@JB Nizet http yanıtının neden java nesneleri içeremediğini açıklar mısınız? Ben java'ya bir yenibiyim.
Naved Ali

3
@ Er.NavedAli http belirtimini okur, http yanıt içerik türü, bir http yanıtının içerebileceği yasal içeriği tanımlar. bunun için yasal değerler "uygulama / octet-stream", "image / jpeg", "text / HTML" olabilir, ancak java nesneleri bunun için yasal bir değer değildir.
ZhaoGang

@ZhaoGang, İçerik türü 'application / json', test durumumda 'application / xml' ile değiştirildi, ancak yanıt gövdesi değişiklik görünmüyor, hala json formatı mevcut.
LeafiWan

1
tam olarak nerede, yani hangi bahar sınıfında, yanıtın nasıl geri döneceğine karar veriliyor? Beni github'daki kaynağa, bu kararın nerede verildiğine veya sınıf adına yönlendirebilir misiniz? Ayrıca istemci XML'i kabul ederse, ancak XML dönüştürücü kurulu değilse ne olur?
anir

70

Anlaşılması gereken ilk temel şey, mimarilerdeki farklılıktır.

Bir uçta, web sayfalarını kullanan normal web uygulamanıza dayanan MVC mimarisine sahipsiniz ve tarayıcı bir sayfa için bir talepte bulunuyor:

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

Tarayıcı bir istekte bulunur, denetleyici (@Controller) modeli alır (@Entity) ve modelden görünümü (JSP) oluşturur ve görünüm istemciye geri döndürülür. Bu, temel web uygulaması mimarisidir.

Öte yandan, RESTful bir mimariye sahipsiniz. Bu durumda, View yoktur. Denetleyici yalnızca modeli (veya daha RESTful terimlerle kaynak sunumunu) geri gönderir. İstemci, bir JavaScript uygulaması, bir Java sunucusu uygulaması, REST API'mizi açıkladığımız herhangi bir uygulama olabilir. Bu mimari ile müşteri bu modelle ne yapacağına karar verir. Örneğin Twitter'ı ele alalım. Web (REST) ​​API olarak Twitter, uygulamalarımızın durum güncellemeleri gibi şeyleri almak için API'sini kullanmasına izin verir, böylece bu verileri uygulamamıza yerleştirmek için kullanabiliriz. Bu veriler JSON gibi bir formatta gelecek.

Bununla birlikte, Spring MVC ile çalışırken, ilk olarak temel web uygulama mimarisini idare etmek için oluşturuldu. Yöntemlerimizden bir görünüm üretilmesine izin veren farklı yöntem imzası çeşitleri olabilir. Yöntem, ModelAndViewonu açıkça oluşturduğumuz bir yere döndürebilir veya model özniteliklerine yerleştirilen bazı rastgele nesneleri döndürebileceğimiz örtük yollar vardır. Ancak her iki durumda da, istek-yanıt döngüsü boyunca bir yerde üretilen bir görünüm olacaktır.

Fakat kullandığımızda @ResponseBody, bir görünümün üretilmesini istemediğimizi söylüyoruz. Sadece dönüş nesnesini, belirttiğimiz formatta gövde olarak göndermek istiyoruz. Bunun serileştirilmiş bir Java nesnesi olmasını istemeyiz (mümkün olsa da). Yani evet, başka bir yaygın türe dönüştürülmesi gerekiyor (bu tür normalde içerik pazarlığı yoluyla ele alınır - aşağıdaki bağlantıya bakın). Açıkçası, Spring ile pek çalışmıyorum, ancak burada ve orada uğraşıyorum. Normalde kullanırım

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

içerik türünü ayarlamak için, ancak JSON varsayılandır. Benden alıntı yapmayın, ancak JSON alıyorsanız ve belirtmediyseniz produces, o zaman belki de varsayılandır. JSON tek format değil. Örneğin, yukarıdaki kolayca XML gönderilebilir, ancak olması gerekir producesetmek MediaType.APPLICATION_XML_VALUEve yapılandırmak için gereken inanmak HttpMessageConverterJAXB için. JSON'a gelinceMappingJacksonHttpMessageConverter yapılandırmasına gelince, Jackson sınıf yolunda olduğunda.

İçerik Pazarlığı hakkında bilgi edinmek için biraz zaman alırdım . REST'in çok önemli bir parçası. Farklı yanıt biçimleri ve bunları yöntemlerinizle nasıl eşleştireceğiniz hakkında bilgi edinmenize yardımcı olacaktır.


Cevabınızı kullanmadan genel / dinamik bir REST denetleyicisinin nasıl oluşturulacağına dair araştırma sırasında bulduysanız @Controller/@RestController. Görünüm çözümleyici katmanını bir şekilde atlamam gerektiğini keşfettim. O kadar basit değil çünkü AbstractController sınıfı, görünüm adını döndürmesi gereken bir yöntem sağlar. Bununla ilgili bir soru sordum: stackoverflow.com/questions/41016018/… , sorunumu nasıl çözebileceğim konusunda fikirleriniz varsa, lütfen bir yorum gönderin.
nowszy94

2

Buna ek olarak, dönüş türü şu şekilde belirlenir:

  1. HTTP İsteğinin istediğini söylediği şey - Accept başlığında. Kabul et seçeneğinin ne olduğunu görmek için ilk talebe bakmayı deneyin.

  2. HttpMessageConverters Spring'in kurduğu şey. Spring MVC, Jackson kitaplıkları sınıf yolunda ise, XML (JAXB kullanarak) ve JSON için dönüştürücüleri kuracaktır.

Bir seçenek varsa, birini seçer - bu örnekte, JSON olur.

Bu edilir ders notları kaplı. Mesaj Dönüştürücüler ve İçerik Pazarlığı ile ilgili notlara bakın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.