2012-04-27 7 views
34

के लिए स्प्रिंग रेस्ट टेम्पलेट के साथ प्रमाणित POST अनुरोध बनाना मेरे पास एक विश्वसनीय API है जिसे मैं एंड्रॉइड और रेस्ट टेम्पलेट के माध्यम से कनेक्ट करने का प्रयास कर रहा हूं। एपीआई के सभी अनुरोध HTTP प्रमाणीकरण के साथ प्रमाणीकृत हैं, HttpEntity के शीर्षकों को सेट करके और फिर RestTemplate की exchange() विधि का उपयोग कर।एंड्रॉइड

सभी GET अनुरोध इस तरह से काम करते हैं, लेकिन मैं प्रमाणित पोस्ट अनुरोधों को पूरा करने का तरीका नहीं समझ सकता। postForObject और postForEntity POST को संभालते हैं, लेकिन प्रमाणीकरण शीर्षलेख सेट करने का कोई आसान तरीका नहीं है।

तो हो जाता है, तो इस महान काम करता है:

HttpAuthentication httpAuthentication = new HttpBasicAuthentication("username", "password"); 
HttpHeaders requestHeaders = new HttpHeaders(); 
requestHeaders.setAuthorization(httpAuthentication); 

HttpEntity<?> httpEntity = new HttpEntity<Object>(requestHeaders); 

MyModel[] models = restTemplate.exchange("/api/url", HttpMethod.GET, httpEntity, MyModel[].class); 

लेकिन पदों जाहिरा तौर पर exchange() साथ काम नहीं करते यह कभी नहीं अनुकूलित हेडर भेजता है और मैं exchange() का उपयोग कर अनुरोध शरीर स्थापित करने के लिए कैसे नहीं दिख रहा है के रूप में।

RestTemplate से प्रमाणीकृत POST अनुरोध करने का सबसे आसान तरीका क्या है?

+1

requestHeaders.setAuthorization (httpAuthentication) .. इस तरह के setAuthorization के रूप में अपनी undefined..no विधि .. – DEADEND

उत्तर

75

ठीक है जवाब मिला। exchange() सबसे अच्छा तरीका है। विचित्र रूप से HttpEntity कक्षा में setBody() विधि नहीं है (इसमें getBody() है), लेकिन अभी भी निर्माता के माध्यम से अनुरोध निकाय सेट करना संभव है।

// Create the request body as a MultiValueMap 
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();  

body.add("field", "value"); 

// Note the body object as first parameter! 
HttpEntity<?> httpEntity = new HttpEntity<Object>(body, requestHeaders); 

MyModel model = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class); 
+2

यह एक TypeMismatch त्रुटि फेंकता प्रकार बेमेल: ResponseEntity से MyModel को परिवर्तित नहीं कर सकते .. मुझे लगता है कि यह होना चाहिए ResponseEntity मॉडल = restTemplate.exchange ("/ API/url" HttpMethod.POST, httpEntity, MyModel.class); – Sid

+0

'MyModel myModel = restTemplate.exchange (fullServiceUrl, HttpMethod.GET, अनुरोध, MyModel.class) .getBody()' आपके द्वारा उल्लिखित समस्या को हल करने में मदद करेगा – Isank

+0

धन्यवाद। जब तक मैंने आपकी पोस्ट पर ठोकर खाई, तब तक मुझे दो घंटे का खर्च हुआ। – guenhter

7

बहुत उपयोगी मैं एक अलग परिदृश्य में जहाँ मैं अनुरोध एक्सएमएल ही था पोस्ट का मुख्य भाग और नहीं एक परम था। इसके लिए निम्नलिखित कोड का उपयोग किया जा सकता है - किसी अन्य व्यक्ति के समान समस्या होने पर ही उत्तर के रूप में पोस्ट करना लाभ होगा।

final HttpHeaders headers = new HttpHeaders(); 
    headers.add("header1", "9998"); 
    headers.add("username", "xxxxx"); 
    headers.add("password", "xxxxx"); 
    headers.add("header2", "yyyyyy"); 
    headers.add("header3", "zzzzz"); 
    headers.setContentType(MediaType.APPLICATION_XML); 
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML)); 
    final HttpEntity<MyXmlbeansRequestDocument> httpEntity = new HttpEntity<MyXmlbeansRequestDocument>(
      MyXmlbeansRequestDocument.Factory.parse(request), headers); 
    final ResponseEntity<MyXmlbeansResponseDocument> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity,MyXmlbeansResponseDocument.class); 
    log.info(responseEntity.getBody()); 
14

थोड़ा अलग दृष्टिकोण:

MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>(); 
headers.add("HeaderName", "value"); 
headers.add("Content-Type", "application/json"); 

RestTemplate restTemplate = new RestTemplate(); 
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 

HttpEntity<ObjectToPass> request = new HttpEntity<ObjectToPass>(objectToPass, headers); 

restTemplate.postForObject(url, request, ClassWhateverYourControllerReturns.class); 
+2

ऑब्जेक्ट टॉपास –

+0

@ इस्माइल इकबाल से कहां से आता है - यह उस जानकारी के साथ कोई वस्तु हो सकती है जिसे आपको पास करने की आवश्यकता है (उदाहरण के लिए निजी व्यक्ति जॉन = व्यक्ति ("जॉन", 24);)। इसे जेसन पेलोड में परिवर्तित कर दिया जाएगा और अनुरोध निकाय के माध्यम से सर्वर को भेजा जाएगा – Andrey

7

मैं हाल ही में एक मुद्दा है जब मैं जावा से से REST कॉल जबकि पिछले प्रमाणीकरण प्राप्त करने के लिए कोशिश कर रहा था के साथ काम कर रहा था, और जब तक इस सूत्र में जवाब (और अन्य धागे) ने मदद की, अभी भी कुछ परीक्षण और त्रुटि प्राप्त करने में शामिल त्रुटि थी।

मेरे लिए क्या काम किया गया Base64 में एन्कोडिंग प्रमाण-पत्र था और उन्हें मूल प्राधिकरण शीर्षलेख के रूप में जोड़ना था। इसके बाद मैंने उन्हें HttpEntity से restTemplate.postForEntity के रूप में जोड़ा, जिसने मुझे आवश्यक प्रतिक्रिया दी।

यहाँ वर्ग मैं पूर्ण रूप से इस के लिए लिखा था (RestTemplate विस्तार) है:

public class AuthorizedRestTemplate extends RestTemplate{ 

    private String username; 
    private String password; 

    public AuthorizedRestTemplate(String username, String password){ 
     this.username = username; 
     this.password = password; 
    } 

    public String getForObject(String url, Object... urlVariables){ 
     return authorizedRestCall(this, url, urlVariables); 
    } 

    private String authorizedRestCall(RestTemplate restTemplate, 
      String url, Object... urlVariables){ 
     HttpEntity<String> request = getRequest(); 
     ResponseEntity<String> entity = restTemplate.postForEntity(url, 
       request, String.class, urlVariables); 
     return entity.getBody(); 
    } 

    private HttpEntity<String> getRequest(){ 
     HttpHeaders headers = new HttpHeaders(); 
     headers.add("Authorization", "Basic " + getBase64Credentials()); 
     return new HttpEntity<String>(headers); 
    } 

    private String getBase64Credentials(){ 
     String plainCreds = username + ":" + password; 
     byte[] plainCredsBytes = plainCreds.getBytes(); 
     byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); 
     return new String(base64CredsBytes); 
    } 
}