2016-04-05 11 views
2

Spring RestTemplate kullanarak JSON olarak temsil edilen bir sorgu parametresine sahip bir HTTP bitiş noktasına bir istekte bulunmam gerekiyor. Spring RestTemplate ile JSON olarak temsil edilen sorgu parametresi nasıl kullanılır?

restTemplate.getForObject(
    apiRoot + "/path" + "?object={myObject}", 
    Response.class, 
    new MyObject()) 

İşte MyObject JSON dönüştürülecek (ve tabii ki URL olarak kodlanmış) gerekir. Ancak RestTemplate, bunun yerine toString çağrısı ile String'a dönüştürür. MyObject, JSON tarafından Jackson'a dönüştürülebilir.

UriComponentsBuilder.fromHttpUrl(apiRoot) 
    .path("/path") 
    .queryParam("object", new MyObject())) 
    .queryParam("access_token", accessToken) 
    .toUri() 

eliyle ObjectMapper.writeValueAsString arama önlemek için bir yol var mı: UriComponentsBuilder aynı şekilde davranır?

Güncelleme: netleştirmek için, sonuçta ben 42 eşit değerde benim URI'de (veya URL encodeded formu ?object=%7B%22key%22%3A42%7D olarak) MyObject gelmiştir verilen bir özellik key?object={"key":42} olması gerekir.

+2

Eğer uygunsa 'MyObject.toString()' 'de ObjectMapper.writeValueAsString 'öğesini kullanabilirsiniz. – TheKojuEffect

+0

Yapabilirim ama muhtemelen iki sebepten dolayı olmaz. İlk önce DTO'larım Bahar Bağlamından bağımsız olarak saklayacağım, çünkü gerçek bir projede bağlam yoluyla önceden yapılandırılmış 'ObjectMapper'ı telleyeceğim. Ve ikincisi, oldukça belirsiz, ben nesneler JSON dönüşüm için alternatif yolu tanıtmak ve doğrudan ihtiyacım olduğunda 'ObjectMapper' arayarak açık kalmayı tercih ederim. – raindev

cevap

1

writeValueAsString kullanımıyla ilgili sorun nedir? Açıklayabilir misin?

aklım benziyor gelen tek çözüm (Jackson bu nesne o anda tefrika edilmesi gerektiğini bilmek için bir yol olup olmadığını sanmıyorum):

@Autowired 
ObjectMapper objectMapper; 

@Override 
public void run(String... strings) throws Exception { 

    String urlBase = "http://localhost:8080/path"; 

    RestTemplate restTemplate = new RestTemplate(); 

    String url; 
    MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>(); 
    params.set("object", objectMapper.writeValueAsString(new MyObject())); 

    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(urlBase).queryParams(params); 
    url = builder.build().toUri().toString(); 

    LOGGER.info("Composed before decode: " + url); 

    //restTemplate.getForObject(url, Void.class); 

    url = URLDecoder.decode(url, "UTF-8"); 

    LOGGER.info("Composed after decode: " + url); 
} 

Çıktı:

2016-04-05 16:06:46.811 INFO 6728 --- [main] com.patrykwoj.StackOverfloApplication : Composed before decode: http://localhost:8080/path?object=%7B%22key%22:43%7D 
2016-04-05 16:06:46.941 INFO 6728 --- [main] com.patrykwoj.StackOverfloApplication : Composed after decode: http://localhost:8080/path?object={"key":43} 

Düzenleme: istek parametre olarak JSON nesnesi gönderme genellikle iyi bir fikir olmadığını, söylemeyi unutmuşum

. Örneğin, muhtemelen JSON içinde küme parantezleri ile sorunla karşılaşacaksınız.

+0

İlk olarak size cevap vermek için: evet, sorgu parametreleri için JSON kullanımının özellikle zarif bir fikir olmadığını kabul ediyorum. Ne yazık ki, Facebook bu uç noktaların bazıları için kullanıyor. – raindev

+0

Özellikle "writeValueAsString" ile _bad_ diye bir şey yok. Aslında işim bitti. Bu tür çağrılardan kurtulmak istediğim neden genellikle, istek gövdesini genellikle "String" olarak değil, JSON'a otomatik olarak dönüştürülen nesneleri kullanmamamızın nedenidir. JsonProcessingException ile uğraşmak zorunda kalmamak, işleri daha da basitleştirecektir. – raindev

+0

Sınırlamanın sorunun özünde olduğunu düşünmüyorum. Aynı mantıksal Jackson, sorgu gövdesine istek gövdesi yazılırken JSON'a ne serileştirileceğini "bilmek" için kullanılır. Uygulamamış olmanın en açık nedeni, bugünün tarihsel nedenlerinin yanı sıra, böyle bir API tasarımı tarzını (bizim kontrolümüz altında olduğu düşünülürse) caydırmaktır. – raindev

İlgili konular