RESTful POST yönteminde parametrelere nasıl erişilir


123

POST yöntemim şuna benzer:

@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String param1, String param2){
    System.out.println("param1 = " + param1);
    System.out.println("param2 = " + param2);
}

Netbeans'te bir Jersey İstemcisi oluşturduğumda, post yöntemini çağıran yöntem şuna benzer:

public void create(Object requestEntity){
    webResource.path("create").type(MediaType.APPLICATION_JSON).post(requestEntity);
}

Bu testi çalıştırırken:

@Test
public void hello(){
    String json = "{param1=\"hello\",param2=\"hello2\"}";
    this.client.create(json);
}

Sunucuda aşağıdaki çıktıyı verir:

INFO: param1 = {param1="hello",param2="hello2"}
INFO: param2 = 

Parametrelerin doğru değeri vermesi için neyi değiştirmem gerekiyor?


bunu android uygulamasında kullanıyor musun kullanmıyor musun?
Android-Droid

Sonunda bu gönderi yöntemini bir android uygulamasında aramak istiyorum. Bir şekilde web hizmeti, değerleri parametrelere nasıl imzalayacağını bilmiyor. Bunu nasıl yapacağımı bilmek istiyorum.
Klaasvaak

Yanıtlar:


356

Kişisel @POSTyöntem yerine bir dize bir JSON nesnesi kabul edilmelidir. Jersey, JSON nesnelerini sıralamak ve eşleştirmeyi kaldırmak için JAXB kullanır (ayrıntılar için forma belgelerine bakın ). Şöyle bir sınıf oluşturun:

@XmlRootElement
public class MyJaxBean {
    @XmlElement public String param1;
    @XmlElement public String param2;
}

O zaman @POSTyönteminiz aşağıdaki gibi görünecektir:

@POST @Consumes("application/json")
@Path("/create")
public void create(final MyJaxBean input) {
    System.out.println("param1 = " + input.param1);
    System.out.println("param2 = " + input.param2);
}

Bu yöntem, HTTP POST'un gövdesi olarak JSON nesnesini almayı bekler. JAX-RS, HTTP mesajının içerik gövdesini açıklamasız bir parametre olarak iletir - inputbu durumda. Gerçek mesaj şuna benzer:

POST /create HTTP/1.1
Content-Type: application/json
Content-Length: 35
Host: www.example.com

{"param1":"hello","param2":"world"}

JSON'u bu şekilde kullanmak, bariz nedenlerden dolayı oldukça yaygındır. Ancak, JavaScript dışında bir şey oluşturuyor veya tüketiyorsanız, verilerden düzgün bir şekilde kaçmak için dikkatli olmanız gerekir. JAX-RS'de, bunu uygulamak için bir MessageBodyReader ve MessageBodyWriter kullanırsınız. Jersey'nin gerekli türler (örneğin, Java ilkelleri ve JAXB sarılmış sınıflar) ve JSON için zaten uygulamalara sahip olduğuna inanıyorum. JAX-RS, veri aktarımı için bir dizi başka yöntemi destekler. Veriler basit argüman geçişi kullanılarak iletildiği için bunlar yeni bir sınıfın oluşturulmasını gerektirmez.


HTML <FORM>

Parametreler, @FormParam kullanılarak açıklanacaktır :

@POST
@Path("/create")
public void create(@FormParam("param1") String param1,
                   @FormParam("param2") String param2) {
    ...
}

Tarayıcı formu "application / x-www-form-urlencoded" kullanarak kodlayacaktır . JAX-RS çalışma zamanı, gövdenin kodunun çözülmesi ve yönteme aktarılmasıyla ilgilenecektir. Tel üzerinde görmeniz gerekenler:

POST /create HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 25

param1=hello&param2=world

Bu durumda içerik URL kodludur .

FormParam'ın adlarını bilmiyorsanız, aşağıdakileri yapabilirsiniz:

@POST @Consumes("application/x-www-form-urlencoded")
@Path("/create")
public void create(final MultivaluedMap<String, String> formParams) {
    ...
}

HTTP Başlıkları

Sen kullanarak yapabilirsiniz @HeaderParam HTTP başlıkları üzerinden parametre geçmek istiyorsan ek açıklama:

@POST
@Path("/create")
public void create(@HeaderParam("param1") String param1,
                   @HeaderParam("param2") String param2) {
    ...
}

HTTP mesajı şöyle görünecektir. Bu POST'un bir gövdesi olmadığını unutmayın.

POST /create HTTP/1.1
Content-Length: 0
Host: www.example.com
param1: hello
param2: world

Bu yöntemi genelleştirilmiş parametre geçişi için kullanmazdım. Yine de belirli bir HTTP başlığının değerine erişmeniz gerekiyorsa gerçekten kullanışlıdır.


HTTP Sorgu Parametreleri

Bu yöntem esas olarak HTTP GET'lerle kullanılır, ancak aynı şekilde POST'lar için de geçerlidir. @QueryParam ek açıklamasını kullanır .

@POST
@Path("/create")
public void create(@QueryParam("param1") String param1,
                   @QueryParam("param2") String param2) {
    ...
}

Önceki teknikte olduğu gibi, parametreleri sorgu dizesi aracılığıyla geçirmek bir ileti gövdesi gerektirmez. İşte HTTP mesajı:

POST /create?param1=hello&param2=world HTTP/1.1
Content-Length: 0
Host: www.example.com

İstemci tarafında sorgu parametrelerini doğru şekilde kodlamak için özellikle dikkatli olmalısınız . Sorgu parametrelerini kullanmak, bazı proxy'ler tarafından uygulanan URL uzunluğu kısıtlamalarının yanı sıra bunları kodlamayla ilgili sorunlar nedeniyle sorunlu olabilir.


HTTP Yol Parametreleri

Yol parametreleri, HTTP kaynak yoluna yerleştirilmeleri dışında sorgu parametrelerine benzer. Bu yöntem bugün olumlu görünüyor. HTTP kaynağını gerçekten tanımlayan yol olduğundan, HTTP önbelleğe alma ile ilgili etkiler vardır. @Path ek açıklaması değiştirildiği ve @PathParam kullandığı için kod diğerlerinden biraz farklı görünüyor :

@POST
@Path("/create/{param1}/{param2}")
public void create(@PathParam("param1") String param1,
                   @PathParam("param2") String param2) {
    ...
}

Mesaj, parametre adlarının mesajın herhangi bir yerine dahil edilmemesi dışında sorgu parametresi sürümüne benzer.

POST /create/hello/world HTTP/1.1
Content-Length: 0
Host: www.example.com

Bu yöntem, sorgu parametresi sürümüyle aynı kodlama sorunlarını paylaşır. Yol segmentleri farklı şekilde kodlanır, bu nedenle orada da dikkatli olmanız gerekir.


Gördüğünüz gibi, her yöntemin artıları ve eksileri vardır. Seçim genellikle müşterileriniz tarafından belirlenir. FORMTabanlı HTML sayfaları sunuyorsanız , kullanın @FormParam. İstemcileriniz JavaScript + HTML5 tabanlıysa, muhtemelen JAXB tabanlı serileştirme ve JSON nesnelerini kullanmak isteyeceksiniz. MessageBodyReader/WriterBu yanlış gidebilir biri daha az şey öylesine uygulamaları sizin için kaçan gerekli özen gerekmektedir. İstemciniz Java tabanlıysa ancak iyi bir XML işlemcisine (örneğin, Android) sahip değilse, o zaman FORMbir içerik gövdesinin oluşturulması ve kodlanması URL'lerden daha kolay olduğu için muhtemelen kodlamayı kullanırdım . Umarım bu mini wiki girişi, JAX-RS'nin desteklediği çeşitli yöntemlere biraz ışık tutar.

Not: Tam açıklama amacıyla, Jersey'in bu özelliğini henüz kullanmadım. Dağıtılmış bir dizi JAXB + JAX-RS uygulamasına sahip olduğumuz ve mobil istemci alanına taşındığımız için bununla uğraşıyorduk. JSON, HTML5 veya jQuery tabanlı çözümlerde XML'e çok daha uygundur.


4
Bu özelliği dün test ettim,
@XmlElement

Bunun için teşekkürler. Hala 2 Strings göndermek istiyorsam, restfull'ün tüketebilmesi için ne gerekir? Veya birden fazla parametre yalnızca @PathParm ile mi çalışır?
Klaasvaak

1
@Klaasvaak - her bir parametrenin nereden çıkarılmasının beklendiğini belirtmeniz gerekir. Şu anda elinizde olduğu gibi Jersey / NetBeans bir form gönderisini üstleniyor ve FormParm olarak gönderilen verileri çıkarıyor. Yöntem artırmalarınızın her birine, verileri nereden almak istediğinizle birlikte açıklama ekleyin (PathParam, FormParam, CookieParam vb.)
Perception

1
@Klaasvaak - Çeşitli ek açıklamaları kullanarak bir grup örnek ekledim
D.Shawley

2
Bunun için çok teşekkür ederim! Bu gerçekten aradığım şeydi. Günümü siz yaptınız;) Şimdi FormParams kullanıyorum ve işe yarıyor!
Klaasvaak
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.