जावा क्लास से SOAP वेब सर्विस कॉल कैसे करें?


116

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

इस लाइब्रेरी को अन्य डेवलपर्स के साथ साझा किया जाएगा, और जार में कक्षाओं के बीच ऐसी कक्षाएं होंगी जिनमें एक विधि होती है जो एक वेबसर्विस को बुलाती है (जो अनिवार्य रूप से वर्ग की एक विशेषता निर्धारित करती है, कुछ व्यावसायिक तर्क करती है, जैसे ऑब्जेक्ट को db में संग्रहीत करना, आदि और उन संशोधनों के साथ वस्तु को वापस भेजता है)। मैं इस सेवा को यथासंभव सरल बनाना चाहता हूं, उम्मीद है कि यह सरल है ताकि डेवलपर का उपयोग केवल कक्षा को करने के लिए किया जाए।

Car c = new Car("Blue");
c.webmethod();

मैं सर्वर पर उपयोग करने के लिए JAX-WS का अध्ययन कर रहा हूं, लेकिन मुझे लगता है कि मुझे एक बनाने की आवश्यकता नहीं है wsimport सर्वर में और न ही wsimportक्लाइंट पर , क्योंकि मुझे पता है कि दोनों वर्ग हैं, मुझे बस कक्षाओं के बीच कुछ बातचीत की आवश्यकता है सर्वर और क्लाइंट दोनों में साझा किया गया। आपको क्या लगता है कि कक्षा में वेबसेवा और कॉल करने के लिए कैसे समझ में आता है?


आपका प्रश्न थोड़ा अस्पष्ट है। जिस विधि को आप बनाना चाहते हैं (1) वेब सेवा से वस्तु प्राप्त करेंगे; (2) वस्तु के साथ काम थोड़ा; और (3) इसे वेब सेवा पर वापस पोस्ट करें। क्या यही है?
acdcjunior

नहीं, ऑब्जेक्ट क्लाइंट में बनाया जाएगा, यह कॉल में ws को भेजा जाएगा, ws एक चर सेट करेगा, उदाहरण के लिए currentTime, कुछ व्यावसायिक लॉजिक को db में स्टोर करना पसंद करते हैं, और फिर ऑब्जेक्ट भेजा जाता है वर्तमान सेट के साथ क्लाइंट पर वापस जाएं। आशा है कि मैंने अपने आप को थोड़ा बेहतर बताया। धन्यवाद।
jpz

जवाबों:


273

मैं समझता हूं कि आपकी समस्या जावा से SOAP (JAX-WS) वेब सेवा को कॉल करने और इसकी रिटर्निंग ऑब्जेक्ट प्राप्त करने के तरीके के बारे में है । उस स्थिति में, आपके पास दो संभावित दृष्टिकोण हैं:

  1. के माध्यम से जावा वर्गों को उत्पन्न करें wsimportऔर उनका उपयोग करें; या
  2. एक SOAP क्लाइंट बनाएं जो:
    1. XML के लिए सेवा के मापदंडों को सीरियल करता है;
    2. HTTP हेरफेर के माध्यम से वेब विधि को कॉल करता है; तथा
    3. एक वस्तु में वापस लौटने वाली एक्सएमएल प्रतिक्रिया को पार्स करें।


पहले दृष्टिकोण के बारे में (उपयोग करते हुए wsimport):

मैं देख रहा हूँ कि आपके पास पहले से ही सेवाएँ (इकाइयाँ या अन्य) व्यावसायिक वर्ग हैं, और यह एक तथ्य है कि कक्षाओं का एक wsimportनया सेट उत्पन्न करता है (जो कि आपके पास पहले से मौजूद कक्षाओं के डुप्लिकेट हैं)।

मुझे डर है, हालांकि, इस परिदृश्य में, आप या तो कर सकते हैं:

  • एडेप्ट (संपादित) wsimportउत्पन्न कोड को अपने व्यवसाय वर्गों का उपयोग करने के लिए (यह मुश्किल है और किसी भी तरह से इसके लायक नहीं है - डब्ल्यूएसडीएल परिवर्तन को हर बार ध्यान में रखते हुए, आपको कोड को फिर से लिखना और पढ़ना होगा); या
  • wsimportउत्पन्न वर्गों का त्याग और उपयोग करें । (इस समाधान में, आप व्यावसायिक कोड एक अन्य वास्तुशिल्प परत से एक सेवा के रूप में उत्पन्न वर्गों का "उपयोग" कर सकते हैं।)

दूसरे दृष्टिकोण के बारे में (अपना कस्टम SOAP क्लाइंट बनाएं):

दूसरा दृष्टिकोण लागू करने के लिए, आपको निम्न करना होगा:

  1. कॉल करना:
    • कॉल करने के लिए SAAJ (जावा के लिए अनुलग्नक एपीआई के साथ SOAP) का उपयोग करें (नीचे देखें, इसे कॉल करने के लिए जावा एसई 1.6 या इसके बाद के संस्करण के साथ भेज दिया गया है); या
    • आप इसे java.net.HttpUrlconnection(और कुछ java.ioहैंडलिंग) के माध्यम से भी कर सकते हैं ।
  2. वस्तुओं को XML से और पीछे की ओर मोड़ें:
    • OXM (XML मैपिंग के लिए ऑब्जेक्ट) फ्रेमवर्क का उपयोग करें जैसे कि JAXB को ऑब्जेक्ट्स से एक्सएमएल को सीरीज़ / डिस्क्रिअलाइज़ करने के लिए।
    • या, यदि आपको XML को मैन्युअल रूप से बनाना / पार्स करना है (यह सबसे अच्छा समाधान हो सकता है यदि प्राप्त वस्तु केवल भेजे गए से थोड़ा अलग है)।

क्लासिक java.net.HttpUrlConnectionका उपयोग करके SOAP क्लाइंट बनाना इतना कठिन नहीं है (लेकिन इतना आसान भी नहीं है), और आप इस लिंक में एक बहुत अच्छा शुरुआती कोड पा सकते हैं ।

मैं आपको SAAJ ढांचे का उपयोग करने की सलाह देता हूं:

जावा (SAAJ) के लिए SOAP अटैचमेंट एपीआई के साथ मुख्य रूप से SOAP अनुरोध / रिस्पॉन्स संदेशों के साथ सीधे निपटने के लिए उपयोग किया जाता है जो किसी भी वेब सेवा एपीआई में पर्दे के पीछे होता है। यह डेवलपर्स को JAX-WS का उपयोग करने के बजाय सीधे साबुन संदेश भेजने और प्राप्त करने की अनुमति देता है।

SAAJ का उपयोग करके SOAP वेब सेवा कॉल का कार्यशील उदाहरण (इसे चलाएँ)! यह इस वेब सेवा को कॉल करता है

import javax.xml.soap.*;

public class SOAPClientSAAJ {

    // SAAJ - SOAP Client Testing
    public static void main(String args[]) {
        /*
            The example below requests from the Web Service at:
             https://www.w3schools.com/xml/tempconvert.asmx?op=CelsiusToFahrenheit


            To call other WS, change the parameters below, which are:
             - the SOAP Endpoint URL (that is, where the service is responding from)
             - the SOAP Action

            Also change the contents of the method createSoapEnvelope() in this class. It constructs
             the inner part of the SOAP envelope that is actually sent.
         */
        String soapEndpointUrl = "https://www.w3schools.com/xml/tempconvert.asmx";
        String soapAction = "https://www.w3schools.com/xml/CelsiusToFahrenheit";

        callSoapWebService(soapEndpointUrl, soapAction);
    }

    private static void createSoapEnvelope(SOAPMessage soapMessage) throws SOAPException {
        SOAPPart soapPart = soapMessage.getSOAPPart();

        String myNamespace = "myNamespace";
        String myNamespaceURI = "https://www.w3schools.com/xml/";

        // SOAP Envelope
        SOAPEnvelope envelope = soapPart.getEnvelope();
        envelope.addNamespaceDeclaration(myNamespace, myNamespaceURI);

            /*
            Constructed SOAP Request Message:
            <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myNamespace="https://www.w3schools.com/xml/">
                <SOAP-ENV:Header/>
                <SOAP-ENV:Body>
                    <myNamespace:CelsiusToFahrenheit>
                        <myNamespace:Celsius>100</myNamespace:Celsius>
                    </myNamespace:CelsiusToFahrenheit>
                </SOAP-ENV:Body>
            </SOAP-ENV:Envelope>
            */

        // SOAP Body
        SOAPBody soapBody = envelope.getBody();
        SOAPElement soapBodyElem = soapBody.addChildElement("CelsiusToFahrenheit", myNamespace);
        SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("Celsius", myNamespace);
        soapBodyElem1.addTextNode("100");
    }

    private static void callSoapWebService(String soapEndpointUrl, String soapAction) {
        try {
            // Create SOAP Connection
            SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
            SOAPConnection soapConnection = soapConnectionFactory.createConnection();

            // Send SOAP Message to SOAP Server
            SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(soapAction), soapEndpointUrl);

            // Print the SOAP Response
            System.out.println("Response SOAP Message:");
            soapResponse.writeTo(System.out);
            System.out.println();

            soapConnection.close();
        } catch (Exception e) {
            System.err.println("\nError occurred while sending SOAP Request to Server!\nMake sure you have the correct endpoint URL and SOAPAction!\n");
            e.printStackTrace();
        }
    }

    private static SOAPMessage createSOAPRequest(String soapAction) throws Exception {
        MessageFactory messageFactory = MessageFactory.newInstance();
        SOAPMessage soapMessage = messageFactory.createMessage();

        createSoapEnvelope(soapMessage);

        MimeHeaders headers = soapMessage.getMimeHeaders();
        headers.addHeader("SOAPAction", soapAction);

        soapMessage.saveChanges();

        /* Print the request message, just for debugging purposes */
        System.out.println("Request SOAP Message:");
        soapMessage.writeTo(System.out);
        System.out.println("\n");

        return soapMessage;
    }

}

धारावाहिक / deserializing के लिए JAXB का उपयोग करने के बारे में, इसके बारे में जानकारी प्राप्त करना बहुत आसान है। आप यहां शुरू कर सकते हैं: http://www.mkyong.com/java/jaxb-hello-world-example/


ऊपर उल्लिखित विधि का उपयोग करके मैं साबुन संस्करण कैसे सेट करूं?
Redone

मैं आपकी विधि का उपयोग करने में सक्षम था और यह तब काम किया जब मैंने आपका यूआरआई का उपयोग किया था, लेकिन अपने स्वयं के एसओएपी अनुरोध के लिए मुझे एक प्रतिक्रिया मिली, जिसमें से कोई भी मान अपेक्षित के रूप में नहीं दिखाया गया है, अर्थात <xsd:element name="Incident_Number" type="xsd:string"/>। जैसा कि आप देख सकते हैं, तत्व बंद है और डब्ल्यूएस से कोई जानकारी उत्पन्न नहीं हुई है।
मार्टिन एरिक

GetInfoByCityहै 503Service Unavailable, यह seeems। :(
ब्रैड टुरेक

@BradTurek D * mn! मैं सिर्फ यह बदल दिया। मुझे बताने के लिए धन्यवाद! मैं एक और एक मिल जाएगा और इसे थोड़ा में बदल दूंगा।
acdcjunior

1
राहगीर को: यदि उपरोक्त कोड (उदाहरण SOAP वेब सेवा समापन बिंदु) काम करना बंद कर देता है या इरोस (जैसे 500, 503, आदि) देना शुरू कर देता है, तो कृपया मुझे बताएं ताकि मैं इसे ठीक कर सकूं।
acdcjunior 23

3

या बस अपाचे सीएक्सएफ के wsdl2java का उपयोग उन वस्तुओं को उत्पन्न करने के लिए करें जिन्हें आप उपयोग कर सकते हैं।

यह बाइनरी पैकेज में शामिल है जिसे आप उनकी वेबसाइट से डाउनलोड कर सकते हैं। आप बस इस तरह एक कमांड चला सकते हैं:

$ ./wsdl2java -p com.mynamespace.for.the.api.objects -autoNameResolution http://www.someurl.com/DefaultWebService?wsdl

यह वस्तुओं को उत्पन्न करने के लिए wsdl का उपयोग करता है, जिसे आप इस तरह से उपयोग कर सकते हैं (ऑब्जेक्ट नाम भी wsdl से पकड़े गए हैं, इसलिए आपका उपयोग थोड़ा अलग होगा):

DefaultWebService defaultWebService = new DefaultWebService();
String res = defaultWebService.getDefaultWebServiceHttpSoap11Endpoint().login("webservice","dadsadasdasd");
System.out.println(res);

यहां तक ​​कि एक मावेन प्लग-इन भी है जो स्रोतों को उत्पन्न करता है: https://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html

नोट: यदि आप CXF और IDEA का उपयोग करके स्रोत उत्पन्न करते हैं, तो आप इस पर गौर करना चाहते हैं: https://stackoverflow.com/a/46812593/840315


1
मेरे आवेदन में 30+ wsdl है। सिर्फ 1 wsdl (जिसमें 5 साबुन हैं) के लिए संसाधन तैयार करते समय, मेरी ग्रहण आईडीई को 100+ एमबी की कक्षाओं / वस्तुओं से लटका दिया गया और उत्पन्न किया गया।
Manmohan_singh

-1

मुझे साबुन संदेश उत्पन्न करने का एक बहुत ही सरल वैकल्पिक तरीका मिला। एक व्यक्ति वस्तु दी:

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Person {
  private String name;
  private int age;
  private String address; //setter and getters below
}

नीचे एक सरल साबुन संदेश जनरेटर है:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

@Slf4j
public class SoapGenerator {

  protected static final ObjectMapper XML_MAPPER = new XmlMapper()
      .enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)
      .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
      .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
      .registerModule(new JavaTimeModule());

  private static final String SOAP_BODY_OPEN = "<soap:Body>";
  private static final String SOAP_BODY_CLOSE = "</soap:Body>";
  private static final String SOAP_ENVELOPE_OPEN = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
  private static final String SOAP_ENVELOPE_CLOSE = "</soap:Envelope>";

  public static String soapWrap(String xml) {
    return SOAP_ENVELOPE_OPEN + SOAP_BODY_OPEN + xml + SOAP_BODY_CLOSE + SOAP_ENVELOPE_CLOSE;
  }

  public static String soapUnwrap(String xml) {
    return StringUtils.substringBetween(xml, SOAP_BODY_OPEN, SOAP_BODY_CLOSE);
  }
}

आप द्वारा उपयोग कर सकते हैं:

 public static void main(String[] args) throws Exception{
        Person p = new Person();
        p.setName("Test");
        p.setAge(12);

        String xml = SoapGenerator.soapWrap(XML_MAPPER.writeValueAsString(p));
        log.info("Generated String");
        log.info(xml);
      }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.