Permintaan POST melalui RestTemplate di JSON


126

Saya tidak menemukan contoh bagaimana menyelesaikan masalah saya, jadi saya ingin meminta bantuan Anda. Saya tidak bisa begitu saja mengirim permintaan POST menggunakan objek RestTemplate di JSON

Setiap kali saya mendapatkan:

org.springframework.web.client.HttpClientErrorException: 415 Jenis Media Tidak Didukung

Saya menggunakan RestTemplate dengan cara ini:

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

Apa kesalahanku?


1
@troyfolger url tidak lagi valid
Noremac

Terima kasih - tautan ini berfungsi pada tulisan ini: spring.io/guides/gs/consuming-rest
troyfolger

Untuk mengatasi masalah OP tertentu di atas, Anda mungkin kehilangan header HTTP dengan jenis konten yang sesuai, lihat jawaban dari morganw09dev di bawah.
troyfolger

Masalah ini sebagian besar terkait dengan konfigurasi API Server. Anda menguji API Server menggunakan klien Standalone (seperti Postman) dan mereplikasi header yang sama dalam permintaan Anda. Setidaknya dalam kasus saya, itulah Trik.
Linus

1
@Johnny B, jika ini telah dijawab tolong tandai jawabannya
Vishal

Jawaban:


162

Teknik ini berhasil untuk saya:

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

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

saya harap ini membantu


3
tolong jelaskan baris mana yang harus mengembalikan hasil permintaan http
gstackoverflow

Bagi saya, tidak perlu menentukan header apa pun. Saya telah menggunakan HttpEntity yang mengambil parameter tunggal.
Constantino Cronemberger

24
metode .put()adalah void!
Memberound

4
Menggunakan postForEntity(url, entity, String.class)karya di tempatput(url, entity)
Janac Meena

1
@Kan, request adalah String JSON yang valid atau yang lainnya?
Deva

95

Saya mengalami masalah ini saat mencoba men-debug titik akhir REST. Berikut adalah contoh dasar menggunakan kelas RestTemplate Spring untuk membuat permintaan POST yang saya gunakan. Butuh waktu lama bagi saya untuk mengumpulkan kode dari berbagai tempat untuk mendapatkan versi yang berfungsi.

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

Parser JSON tertentu, titik akhir istirahat saya menggunakan tanda kutip ganda yang diperlukan di sekitar nama bidang jadi itulah mengapa saya lolos dari tanda kutip ganda di String requestJson saya.



Dapatkah Spring menggunakan pengonversi pesan untuk secara otomatis mengonversi Objek Java ke json seperti yang dilakukan di Restful API dengan RestTemplate?
jatuh

1
Menyetel jenis media ke APPLICATION_JSON adalah kunci untuk menyelesaikan masalah.
Pete T

Saya menyelesaikan masalah saya menggunakan HttpEntity <String> entity = new HttpEntity <String> (requestJson, headers); baris ini
Ved Prakash

76

Saya telah menggunakan template istirahat dengan JSONObjects sebagai berikut:

// 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
}

Terima kasih - metode toString JSONObject berguna bagi saya, ini membantu saya mendapatkan akurasi JSONString saya.
Simon

1
Bagaimana mengembangkan kode di atas untuk ini: curl -vvv -X POST " localhost: 8080 / SillyService_SRC / oauth /… "?
Pra_A

@ Mikael Lepistö Bagaimana cara mengambil parameter ini dari json di server end ??
KJEjava48

@ KJEjava48 Saya tidak mengerti apa yang Anda maksud ... ini adalah kode sisi server sebagai tanggapan. Jika Anda berpikir bagaimana mengurai respons json, itu tergantung pada kerangka kerja yang Anda gunakan.
Mikael Lepistö

@ MikaelLepistö Maksud saya bagaimana mem-parsing respons json di ujung lain termasuk cara menerima respons di java ?? Anda hanya memposting kode untuk satu ujung (yaitu, sisi server).
KJEjava48

13

Seperti yang ditentukan di sini, saya rasa Anda perlu menambahkan messageConverteruntuk MappingJacksonHttpMessageConverter


10

Jika Anda menggunakan Spring 3.0, cara mudah untuk menghindari org.springframework.web.client.HttpClientErrorException: 415 Pengecualian Jenis Media yang Tidak Didukung , adalah dengan menyertakan file jar jackson di jalur kelas Anda, dan menggunakan mvc:annotation-drivenelemen config. Seperti yang ditentukan di sini .

Saya menarik rambut saya mencoba mencari tahu mengapa aplikasi mvc-ajax bekerja tanpa konfigurasi khusus untuk file MappingJacksonHttpMessageConverter. Jika Anda membaca artikel yang saya tautkan di atas dengan cermat:

Di bawah sampul, Spring MVC mendelegasikan ke HttpMessageConverter untuk melakukan serialisasi. Dalam kasus ini, Spring MVC memanggil MappingJacksonHttpMessageConverter yang dibangun di atas prosesor Jackson JSON. Implementasi ini diaktifkan secara otomatis saat Anda menggunakan elemen konfigurasi mvc: annotation-driven dengan Jackson hadir di classpath Anda .


7

Kesalahan "415 Jenis Media Tidak Didukung" memberi tahu Anda bahwa server tidak akan menerima permintaan POST Anda. Permintaan Anda baik-baik saja, itu adalah server yang salah konfigurasi.

MappingJacksonHttpMessageConverterakan secara otomatis mengatur header tipe konten permintaan ke application/json, dan perkiraan saya adalah bahwa server Anda menolaknya. Anda belum memberi tahu kami apa pun tentang penyiapan server Anda, jadi saya tidak bisa benar-benar memberi tahu Anda tentang itu.


7

Saya melakukan dengan cara ini dan berhasil.

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;
}

// Berikan header di sini

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

Semoga ini membantu


4

Saya mendapatkan masalah ini dan saya menggunakan Spring's RestTemplate di klien dan Spring Web di server. Kedua API memiliki pelaporan kesalahan yang sangat buruk, membuatnya sangat sulit untuk dikembangkan.

Setelah berjam-jam mencoba semua jenis eksperimen, saya menemukan bahwa masalahnya disebabkan oleh memberikan referensi nol untuk badan POST, bukan Daftar yang diharapkan. Saya berasumsi bahwa RestTemplate tidak dapat menentukan tipe konten dari objek null, tetapi tidak mengeluh tentang itu. Setelah menambahkan header yang benar, saya mulai mendapatkan pengecualian sisi server yang berbeda di Spring sebelum memasuki metode layanan saya.

Perbaikannya adalah meneruskan List kosong dari klien, bukan null. Tidak ada header yang diperlukan karena tipe konten default digunakan untuk objek bukan nol.


3

Kode ini berfungsi untuk saya;

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

saya menggunakan pendekatan yang sangat mirip dan TIDAK berhasil untuk saya. untuk beberapa alasan yang setara dengan 'peta' saya tidak sedang dikonversi ke json atau dimasukkan sebagai badan keluar yaitu, layanan target TIDAK melihat muatan apa pun.
abdel

2

Jika Anda tidak ingin memproses respons

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

Jika Anda membutuhkan respons untuk memproses

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

0

Bagi saya, kesalahan terjadi dengan penyiapan ini:

AndroidAnnotations Spring Android RestTemplate Module dan ...

GsonHttpMessageConverter

Anotasi Android memiliki beberapa masalah dengan ini dikonversi untuk menghasilkan POSTpermintaan tanpa parameter. Cukup parameter new Object()memecahkannya untuk saya.


0

Mengapa bekerja lebih keras dari yang Anda harus? postForEntitymenerima Mapobjek sederhana sebagai input. Berikut ini berfungsi dengan baik untuk saya saat menulis tes untuk titik akhir REST tertentu di Spring. Saya percaya ini adalah cara yang paling sederhana untuk membuat permintaan JSON POST di Spring:

@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

Jika Anda tidak ingin memetakan JSON sendiri, Anda dapat melakukannya sebagai berikut:

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

0

Saya mencoba sebagai berikut di boot musim semi:

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;
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.