JSON'da RestTemplate üzerinden POST isteği


126

Sorunumu nasıl çözeceğime dair herhangi bir örnek bulamadım, bu yüzden sizden yardım istemek istiyorum. JSON'da RestTemplate nesnesini kullanarak POST isteği gönderemiyorum

Her aldığımda:

org.springframework.web.client.HttpClientErrorException: 415 Desteklenmeyen Ortam Türü

RestTemplate'i şu şekilde kullanıyorum:

...
restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
list.add(new MappingJacksonHttpMessageConverter());
restTemplate.setMessageConverters(list);
...
Payment payment= new Payment("Aa4bhs");
Payment res = restTemplate.postForObject("http://localhost:8080/aurest/rest/payment", payment, Payment.class);

Hatam ne?


1
@troyfolger url artık geçerli değil
Noremac

Teşekkürler - bu bağlantı şu yazı itibariyle çalışıyor: spring.io/guides/gs/consuming-rest
troyfolger

Yukarıdaki spesifik OP sorununu ele almak için, uygun içerik türüne sahip bir HTTP başlığınız eksik olabilir, aşağıdaki morganw09dev yanıtına bakın.
troyfolger

Bu sorunlar çoğunlukla Sunucu API yapılandırmasıyla ilgilidir. Sunucu API'sini Bağımsız bir istemci (Postman gibi) kullanarak test edersiniz ve isteğinizde aynı başlıkları çoğaltırsınız. En azından benim durumumda Hile yaptı.
Linus

1
@Johnny B, eğer cevap verildiyse lütfen cevabı işaretleyin
Vishal

Yanıtlar:


162

Bu teknik benim için çalıştı:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.put(url, entity);

Umarım bu yardımcı olur


3
lütfen hangi satırın http isteğinin sonucunu döndürmesi gerektiğini açıklayın
gstackoverflow

Benim için herhangi bir başlık belirtmeye gerek yoktu. Tek bir parametre alan HttpEntity'yi kullandım.
Constantino Cronemberger

24
yöntem .put()olduğunu void!
üyeler28

4
Kullanma postForEntity(url, entity, String.class)yerine eserleriniput(url, entity)
Janac Meena

1
@Kanu, requestJson geçerli JSON Dizesi mi yoksa başka bir şey mi?
Deva

95

Bir REST uç noktasında hata ayıklamaya çalışırken bu sorunla karşılaştım. İşte kullandığım bir POST isteği yapmak için Spring'in RestTemplate sınıfını kullanan temel bir örnek. Çalışan bir sürüm elde etmek için farklı yerlerden kodları bir araya getirmek oldukça uzun zamanımı aldı.

RestTemplate restTemplate = new RestTemplate();

String url = "endpoint url";
String requestJson = "{\"queriedQuestion\":\"Is there pain in your hand?\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String answer = restTemplate.postForObject(url, entity, String.class);
System.out.println(answer);

Dinlenme uç noktamın belirli JSON ayrıştırıcısı, alan adları etrafında gerekli çift tırnakları kullanıyordu, bu yüzden requestJson String'imdeki çift tırnak işaretlerinden kaçtım.



Spring, Restful API ile Restful API'de olduğu gibi Java Nesnesini otomatik olarak json'a dönüştürmek için mesaj dönüştürücüleri kullanabilir mi?
sonbahar

1
Ortam türünü APPLICATION_JSON olarak ayarlamak, sorunu çözmenin anahtarıdır.
Pete T

HttpEntity <String> varlık = new HttpEntity <String> (requestJson, başlıklar) kullanarak sorunumu çözdüm; bu satır
Ved Prakash

76

Aşağıdaki gibi JSONObjects ile dinlenme şablonu kullanıyorum:

// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);

// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);

// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
  .exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
  JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
  // nono... bad credentials
}

Teşekkürler - JSONObject toString yöntemi benim için yararlıydı, JSONString'imi doğru bir şekilde almamı sağladı.
Simon

1
Bunun için yukarıdaki kod nasıl geliştirilir: curl -vvv -X POST " localhost: 8080 / SillyService_SRC / oauth /… "?
Pra_A

@Mikael Lepistö Bu parametreleri sunucu sonunda json'dan nasıl alabilirim?
KJEjava48

@ KJEjava48 Ne demek istediğini anlamıyorum ... Bu yanıtta sunucu tarafı kodudur. Eğer json yanıtını nasıl ayrıştıracağınızı düşünüyorsanız, kullandığınız çerçeveye bağlıdır.
Mikael Lepistö

@ MikaelLepistö Json yanıtını java'da nasıl alacağınızı da içeren diğer uçta json yanıtının nasıl ayrıştırılacağını kastediyorum? Yalnızca bir uç için (yani sunucu tarafı) kod gönderdiniz.
KJEjava48

13

Belirtildiği gibi burada sana bir eklemem gerekiyor sanırım messageConverteriçin MappingJacksonHttpMessageConverter


10

Spring 3.0 kullanıyorsanız, org.springframework.web.client.HttpClientErrorException: 415 Desteklenmeyen Ortam Türü istisnasından kaçınmanın kolay bir yolu , jackson jar dosyalarını sınıf yolunuza dahil etmek ve mvc:annotation-drivenyapılandırma öğesini kullanmaktır . Burada belirtildiği gibi .

Mvc-ajax uygulamasının neden için herhangi bir özel yapılandırma olmadan çalıştığını anlamaya çalışırken saçlarımı çekiyordum MappingJacksonHttpMessageConverter. Yukarıda bağlantılandırdığım makaleyi yakından okursanız:

Kapakların altında, Spring MVC, serileştirmeyi gerçekleştirmek için bir HttpMessageConverter'a delege eder. Bu durumda, Spring MVC, Jackson JSON işlemcisi üzerine kurulu bir MappingJacksonHttpMessageConverter'ı çağırır. Bu uygulama, sınıf yolunuzda Jackson varken mvc: annotation-güdümlü yapılandırma öğesini kullandığınızda otomatik olarak etkinleştirilir .


7

"415 Unsupported Media Type" hatası, sunucunun POST isteğinizi kabul etmeyeceğini söylüyor. İsteğiniz kesinlikle iyi, yanlış yapılandırılmış olan sunucu.

MappingJacksonHttpMessageConverteristek içerik türü başlığını otomatik olarak olarak ayarlayacak application/jsonve tahminimce sunucunuz bunu reddediyor. Yine de bize sunucu kurulumunuz hakkında hiçbir şey söylemediniz, bu yüzden size bu konuda gerçekten tavsiyede bulunamam.


7

Ben bu şekilde yapıyorum ve işe yarıyor.

HttpHeaders headers = createHttpHeaders(map);
public HttpHeaders createHttpHeaders(Map<String, String> map)
{   
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    for (Entry<String, String> entry : map.entrySet()) {
        headers.add(entry.getKey(),entry.getValue());
    }
    return headers;
}

// Başlıkları buraya geçirin

 String requestJson = "{ // Construct your JSON here }";
logger.info("Request JSON ="+requestJson);
HttpEntity<String> entity = new HttpEntity<String>(requestJson, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
logger.info("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
logger.info("Response ="+response.getBody());

Bu yardımcı olur umarım


4

Bu sorunu alıyordum ve istemcide Spring'in RestTemplate'i ve sunucuda Spring Web'i kullanıyorum. Her iki API de çok zayıf hata raporlamasına sahiptir ve bu da onları geliştirmeyi oldukça zorlaştırır.

Her türlü deneyi saatlerce denedikten sonra, sorunun beklenen Liste yerine POST gövdesi için boş bir referans girilmesinden kaynaklandığını anladım. RestTemplate'in boş bir nesneden içerik türünü belirleyemeyeceğini, ancak bundan şikayet etmediğini varsayıyorum. Doğru başlıkları ekledikten sonra, hizmet yöntemime girmeden önce Spring'de farklı bir sunucu tarafı istisnası almaya başladım.

Düzeltme, null yerine istemciden boş bir Listeye geçmekti. Varsayılan içerik türü boş olmayan nesneler için kullanıldığından üstbilgi gerekmez.


3

Bu kod benim için çalışıyor;

RestTemplate restTemplate = new RestTemplate();
Payment payment = new Payment("Aa4bhs");
MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
map.add("payment", payment);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(map, headerObject);

Payment res = restTemplate.postForObject(url, httpEntity, Payment.class);

çok benzer bir yaklaşım kullanıyorum ve bu benim için işe yaramadı. Bazı nedenlerden dolayı benim 'haritanızın' eşdeğeri json'a dönüştürülmüyor veya giden gövde olarak dahil edilmiyor, yani hedef hizmet herhangi bir yük GÖRMEZ.
abdel

2

Yanıtı işleme koymak istemiyorsanız

private RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(serviceURL, request, Void.class);

İşleme yanıt vermeniz gerekiyorsa

String result = restTemplate.postForObject(url, entity, String.class);

0

Bu kurulumda benim için bir hata oluştu:

AndroidAnnotations Spring Android RestTemplate Module ve ...

GsonHttpMessageConverter

Android ek açıklamalarında, POSTparametresiz istek oluşturmaya dönüştürülen bazı sorunlar var . new Object()Benim için basitçe parametre çözdü.


0

Neden gerekenden daha çok çalışasın? postForEntitybasit bir Mapnesneyi girdi olarak kabul eder . Baharda belirli bir REST uç noktası için testler yazarken aşağıdakiler benim için iyi çalışıyor. Bahar aylarında JSON POST isteği yapmanın mümkün olan en basit yolu olduğuna inanıyorum:

@Test
public void shouldLoginSuccessfully() {
  // 'restTemplate' below has been @Autowired prior to this
  Map map = new HashMap<String, String>();
  map.put("username", "bob123");
  map.put("password", "myP@ssw0rd");
  ResponseEntity<Void> resp = restTemplate.postForEntity(
      "http://localhost:8000/login",
      map,
      Void.class);
  assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
}

0

JSON'u kendiniz eşlemek istemiyorsanız, aşağıdaki gibi yapabilirsiniz:

RestTemplate restTemplate = new RestTemplate();
restTemplate.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
ResponseEntity<String> result = restTemplate.postForEntity(uri, yourObject, String.class);

0

İlkbahar önyüklemesinde aşağıdaki gibi denedim:

ParameterizedTypeReference<Map<String, Object>> typeRef = new ParameterizedTypeReference<Map<String, Object>>() {};
public Map<String, Object> processResponse(String urlendpoint)
{
    try{
    
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        //reqobj
        JSONObject request = new JSONObject();
        request.put("username", name);
        //Or Hashmap 
        Map<String, Object> reqbody =  new HashMap<>();
        reqbody.put("username",username);
        Gson gson = new Gson();//mvn plugin to convert map to String
        HttpEntity<String> entity = new HttpEntity<>( gson.toJson(reqbody), headers);
        ResponseEntity<Map<String, Object>> response = resttemplate.exchange(urlendpoint, HttpMethod.POST, entity, typeRef);//example of post req with json as request payload
        if(Integer.parseInt(response.getStatusCode().toString()) == HttpURLConnection.HTTP_OK)
        {
            Map<String, Object>  responsedetails = response.getBody();
            System.out.println(responsedetails);//whole json response as map object
            return responsedetails;
        }
    } catch (Exception e) {
        // TODO: handle exception
        System.err.println(e);
    }
    return null;
}
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.