কোনও সিএক্সএফ বা জ্যাকস-ডাব্লুএস উত্পাদিত ওয়েবসার্চ ক্লায়েন্টে ডাব্লুএসডিএল অবস্থান নির্দিষ্ট করার প্রয়োজনীয়তা কীভাবে এড়ানো যায়?


165

যখন আমি সিএনএক্সএফ থেকে ডাব্লুএসডিএল 2 জাভা ব্যবহার করে একটি ওয়েব সার্ভিস ক্লায়েন্ট জেনারেট করি (যা ডাব্লুএসপোর্টের অনুরূপ কিছু উত্পন্ন করে), আমার পরিষেবাগুলি কোডগুলি দিয়ে শুরু হয়:

@WebServiceClient(name = "StatusManagement", 
                  wsdlLocation = "c:/some_absolute_path_to_a_wsdl_file.wsdl",
                  targetNamespace = "http://tempuri.org/") 
public class StatusManagement extends Service {

    public final static URL WSDL_LOCATION;
    public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
    public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
    static {
        URL url = null;
        try {
            url = new URL("c:/some_absolute_path_to_a_wsdl_file.wsdl");
        } catch (MalformedURLException e) {
            System.err.println("Can not initialize the default wsdl from c:/some_absolute_path_to_a_wsdl_file.wsdl");
            // e.printStackTrace();
        }
        WSDL_LOCATION = url;
    }

হার্ডকোডযুক্ত পরম পথটি সত্যই সফল হয়। উত্পন্ন শ্রেণি খনি ছাড়া অন্য কোনও কম্পিউটারে কাজ করবে না।

প্রথম ধারণাটি হ'ল ডাব্লুএসডিএল ফাইল (প্লাস এটি আমদানি করা সমস্ত কিছুই, অন্যান্য ডাব্লুএসডিএল এবং এক্সএসডি) কোথাও একটি জার-ফাইলের মধ্যে রেখে এবং এটি শ্রেণিবদ্ধ করে। তবে আমরা এড়াতে চাই। যেহেতু সমস্ত জিনিস ডাব্লুএসডিএল এবং এক্সএসডি-ভিত্তিক স্যাক্সএফ এবং জ্যাকএক্সবি দ্বারা উত্পাদিত হয়েছিল, তাই রানটাইমের সময় আমরা ডাব্লুএসডিএলকে জানার দরকার নেই point

ডাব্লুএসডিএলএলএকশন অ্যাট্রিবিউটটি ডাব্লুএসডিএল লোকেশনকে ওভাররাইড করার উদ্দেশ্যে তৈরি করা হয়েছে (কমপক্ষে এটি আমি কোথাও পড়েছি), এবং এটির ডিফল্ট মান ""। যেহেতু আমরা <wsdlLocation></wsdlLocation>maven ব্যবহার করছি, আমরা উত্স জেনারেটরকে ডাব্লুএসডিএল লোকেশন ফাঁকা ছেড়ে দিতে বাধ্য করার জন্য সিক্সএফের কনফিগারেশনের অভ্যন্তরে অন্তর্ভুক্ত করার চেষ্টা করেছি। তবে এটি খালি থাকার কারণে এটি কেবল এক্সএমএল ট্যাগকে উপেক্ষা করে। আমরা একটি সত্যই কুরুশ লজ্জাজনক হ্যাক করেছি, ব্যবহার করে <wsdlLocation>" + "</wsdlLocation>

এটি অন্যান্য স্থানগুলিতেও পরিবর্তন করে:

@WebServiceClient(name = "StatusManagement", 
                  wsdlLocation = "" + "",
                  targetNamespace = "http://tempuri.org/") 
public class StatusManagement extends Service {

    public final static URL WSDL_LOCATION;
    public final static QName SERVICE = new QName("http://tempuri.org/", "StatusManagement");
    public final static QName WSHttpBindingIStatus = new QName("http://tempuri.org/", "WSHttpBinding_IStatus");
    static {
        URL url = null;
        try {
            url = new URL("" + "");
        } catch (MalformedURLException e) {
            System.err.println("Can not initialize the default wsdl from " + "");
            // e.printStackTrace();
        }
        WSDL_LOCATION = url;
    }

সুতরাং, আমার প্রশ্নগুলি হ'ল:

  1. সমস্ত ক্লাস সিক্সএফ এবং জ্যাকএক্সবি দ্বারা তৈরি করা হলেও আমাদের কি সত্যই কোনও ডাব্লুএসডিএল অবস্থানের প্রয়োজন? যদি হ্যাঁ, কেন?

  2. আমাদের যদি সত্যই ডাব্লুএসডিএল অবস্থানের প্রয়োজন না হয়, তবে সিএক্সএফ এটি তৈরি না করে এবং এটিকে পুরোপুরি এড়িয়ে চলার জন্য সঠিক ও পরিষ্কার উপায় কী?

  3. আমরা সেই হ্যাকের সাথে কী খারাপ প্রতিক্রিয়া পেতে পারি? কী হয় তা দেখার জন্য আমরা এখনও এটি পরীক্ষা করতে পারি না, তাই যদি কেউ আগে থেকে বলতে পারে, তবে ভাল লাগবে।

উত্তর:


206

আমি অবশেষে আজ এই প্রশ্নের সঠিক উত্তরটি খুঁজে পেয়েছি।

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>${cxf.version}</version>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration> 
                <sourceRoot>${project.build.directory}/generated-sources/cxf</sourceRoot>
                <wsdlOptions>
                    <wsdlOption>
                        <wsdl>${project.basedir}/src/main/resources/wsdl/FooService.wsdl</wsdl>
                        <wsdlLocation>classpath:wsdl/FooService.wsdl</wsdlLocation>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>

লক্ষ্য করুন যে আমি মানটির wsdlLocationসাথে পূর্বনির্ধারণ করেছি classpath:। এটি প্লাগইনকে বলে যে ডাব্লুএসডিএল পরম পাথের পরিবর্তে ক্লাসপথে থাকবে ath তারপরে এটি এর মতো কোড তৈরি করবে:

@WebServiceClient(name = "FooService", 
                  wsdlLocation = "classpath:wsdl/FooService.wsdl",
                  targetNamespace = "http://org/example/foo") 
public class Foo_Service extends Service {

    public final static URL WSDL_LOCATION;

    public final static QName SERVICE = new QName("http://org/example/foo", "Foo");
    public final static QName FooSOAPOverHTTP = new QName("http://org/example/foo", "Foo_SOAPOverHTTP");
    static {
        URL url = Foo_Service.class.getClassLoader().getResource("wsdl/FooService.wsdl");
        if (url == null) {
            java.util.logging.Logger.getLogger(Foo_Service.class.getName())
                .log(java.util.logging.Level.INFO, 
                     "Can not initialize the default wsdl from {0}", "classpath:wsdl/FooService.wsdl");
        }       
        WSDL_LOCATION = url;
    }

নোট করুন যে এটি কেবলমাত্র ২.৪.১ সংস্করণ বা সিএক্সএফ-কোডজেন-প্লাগইনের নতুন সংস্করণে কাজ করে।


8
CXF পরিবর্তে Jax ম্যাভেন প্লাগইন ব্যবহার করার সময়, বাদ classpath:মধ্যে <wsdlLocation...লাইন।
টোভলাইট

উপরের পদ্ধতিটি দ্বারা উত্পন্ন কোড সহ কেউ কি কোনও নামস্থান সমস্যার মুখোমুখি হচ্ছে?
নরেন্দ্র জাগি

আপনার যদি বেশ কয়েকটি থাকে তবে আপনার কি প্রতিটি ডাব্লুএসডিএলকে স্বতন্ত্রভাবে তালিকাবদ্ধ করতে হবে? এটা কি এড়ানো সম্ভব?
পিটসিকার

21

আমরা ব্যাবহার করি

wsdlLocation = "WEB-INF/wsdl/WSDL.wsdl"

অন্য কথায়, ক্লাসপাথের সাথে সম্পর্কিত কোনও পাথ ব্যবহার করুন।

আমি বিশ্বাস করি মার্শাল / আনমারশাল চলাকালীন বার্তাগুলির বৈধতার জন্য রানটাইম সময়ে ডাব্লুএসডিএলের প্রয়োজন হতে পারে।


17

যারা org.jvnet.jax-ws-commons:jaxws-maven-pluginবিল্ড-টাইম সময়ে ডাব্লুএসডিএল থেকে একটি ক্লায়েন্ট তৈরি করতে ব্যবহার করছেন তাদের জন্য:

  • আপনার কোথাও ডাব্লুএসডিএল রাখুন src/main/resources
  • সাথে উপসর্গ করবেন নাwsdlLocationclasspath:
  • এর wsdlLocationসাথে উপসর্গ করুন/

উদাহরণ:

  • ডাব্লুএসডিএল সংরক্ষণ করা হয় /src/main/resources/foo/bar.wsdl
  • এবং jaxws-maven-pluginসাথে কনফিগার করুন<wsdlDirectory>${basedir}/src/main/resources/foo</wsdlDirectory><wsdlLocation>/foo/bar.wsdl</wsdlLocation>

"ক্লাসপাথের সাথে wsdlLocation" উপসর্গটি কেন ব্যবহার করবেন না, আমি এটি ব্যবহার করি এবং এটি কাজ করে
মোহাম্মদ সাদেগ রাফিয়ে

9

1) কিছু ক্ষেত্রে, হ্যাঁ। যদি ডাব্লুএসডিএলে পলিসির মতো জিনিস থাকে এবং এটি রানটাইম আচরণকে নির্দেশ করে তবে ডাব্লুএসডিএল রানটাইমের সময় প্রয়োজন হতে পারে। নীতি সম্পর্কিত জিনিস এবং এই জাতীয় জন্য নিদর্শন তৈরি করা হয় না। এছাড়াও, কিছু অস্পষ্ট আরপিসি / আক্ষরিক ক্ষেত্রে, যে সমস্ত নেমস্পেসের প্রয়োজন হয় সেগুলি উত্পন্ন কোডের (প্রতি অনুমানের) আউটপুট নয়। সুতরাং, ডাব্লুএসডিএল তাদের জন্য প্রয়োজন হবে। অস্পষ্ট ক্ষেত্রে যদিও।

2) আমি ভেবেছিলাম এমন কিছু কাজ করবে। সিএক্সএফ এর কোন সংস্করণ? এটি বাগের মতো শোনাচ্ছে। আপনি সেখানে একটি খালি স্ট্রিং চেষ্টা করতে পারেন (কেবল ফাঁকা জায়গা)। এটি কার্যকর কিনা না তা নিশ্চিত। এটি বলেছিল, আপনার কোডে, আপনি এমন কনস্ট্রাক্টর ব্যবহার করতে পারেন যা ডাব্লুএসডিএল ইউআরএল নেয় এবং কেবল নাল পাস করতে পারে। ডাব্লুএসডিএল ব্যবহার করা হত না।

3) উপরের সীমাবদ্ধতা।


এটি সর্বশেষতম সিএক্সএফ 2.3.1 .1 মাত্র 8 দিন আগে মুক্তি পেয়েছে। নাল পাস করা ভাল ধারণা, আমার এই স্পষ্ট উত্তরটি আগে দেখা উচিত ছিল। আমি এখনও ফাঁকা স্থান চেষ্টা করব।
ভিক্টর স্টাফুসা

না, ফাঁকা স্থানগুলি কিছুই করার মতো করে না। যেমন: এক্সএমএল ট্যাগ সম্পূর্ণ উপেক্ষা করা হয়।
ভিক্টর স্টাফুসা

5

আমি উত্পন্ন করতে সক্ষম ছিল

static {
    WSDL_LOCATION = null;
}

ডাব্লুএসডলুরলের জন্য একটি নাল রাখতে পম ফাইলটি কনফিগার করে:

    <plugin>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-codegen-plugin</artifactId>
        <executions>
            <execution>
                <id>generate-sources</id>
                <phase>generate-sources</phase>
                <configuration>
                    <sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot>
                    <wsdlOptions>
                        <wsdlOption>
                            <wsdl>${basedir}/src/main/resources/service.wsdl</wsdl>
                            <extraargs>
                                <extraarg>-client</extraarg>
                                <extraarg>-wsdlLocation</extraarg>
                                <wsdlurl />
                            </extraargs>
                        </wsdlOption>
                    </wsdlOptions>
                </configuration>
                <goals>
                    <goal>wsdl2java</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

2
এই সমাধানটি সিএক্সএফ 3.1.0 দিয়ে আমার পক্ষে কাজ করে নি। -wsdlLocation: একটি ত্রুটি org.apache.cxf.tools.common.toolspec.parser.BadUsageException পেয়েছিলাম: অপ্রত্যাশিত বিকল্প
Chandru

4

আপনি কি ডাব্লুএসডিএল 2 জাভা ব্যবহার এড়াতে পারবেন? আপনি সরাসরি আপনার এসওএপি ওয়েবসার্চ চালু করতে CXF ফ্রন্টএন্ড এপিআই ব্যবহার করতে পারেন। একমাত্র ক্যাচটি হ'ল আপনার ক্লায়েন্টের শেষে আপনার এসইআই এবং ভিও তৈরি করতে হবে। এখানে একটি নমুনা কোড।

package com.aranin.weblog4j.client;

import com.aranin.weblog4j.services.BookShelfService;
import com.aranin.weblog4j.vo.BookVO;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class DemoClient {
    public static void main(String[] args){
        String serviceUrl = "http://localhost:8080/weblog4jdemo/bookshelfservice";
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(BookShelfService.class);
        factory.setAddress(serviceUrl);
        BookShelfService bookService = (BookShelfService) factory.create();

        //insert book
        BookVO bookVO = new BookVO();
        bookVO.setAuthor("Issac Asimov");
        bookVO.setBookName("Foundation and Earth");

        String result = bookService.insertBook(bookVO);

        System.out.println("result : " + result);

        bookVO = new BookVO();
        bookVO.setAuthor("Issac Asimov");
        bookVO.setBookName("Foundation and Empire");

        result = bookService.insertBook(bookVO);

        System.out.println("result : " + result);

        bookVO = new BookVO();
        bookVO.setAuthor("Arthur C Clarke");
        bookVO.setBookName("Rama Revealed");

        result = bookService.insertBook(bookVO);

        System.out.println("result : " + result);

        //retrieve book

        bookVO = bookService.getBook("Foundation and Earth");

        System.out.println("book name : " + bookVO.getBookName());
        System.out.println("book author : " + bookVO.getAuthor());

    }
}

আপনি এখানে পুরো টিউটোরিয়ালটি দেখতে পারেন http://weblog4j.com/2012/05/01/developing-soap-web-service- using-apache-cxf /


2
ডাব্লুএসডিএল ফাইলগুলি অত্যন্ত জটিল ছিল, তাই আমরা সামঞ্জস্যতা নিশ্চিত করার উপায় হিসাবে অটোজেনারেশনকে ব্যবহার করেছি। অটোজেনারেশন কিছু সমানভাবে জটিল জটিল ভিও এবং এসইআই তৈরি করেছে। আমরা অটো-জেনারেটেডগুলিতে সম্পূর্ণরূপে ডিউপলড ডোমেন অবজেক্টের একটি পৃথক সেট ব্যবহার করা বেছে নিয়েছি, সুতরাং আমরা অটোজেনারেশনে হস্তক্ষেপ করি নি বা এটি দ্বারা সীমাবদ্ধ বা পরিচালিত হয়নি। অটো-জেনারেটেড ভিওগুলি কেবল পরিষেবা যোগাযোগের প্রসঙ্গে ব্যবহৃত হত এবং আমরা তাদের যথাসম্ভব স্বল্পকালীন রেখেছি। অন্য কথায়, আমাদের উদ্বেগের একটি হ'ল ম্যানুয়ালি কোড এবং সমস্ত ভিওগুলিকে পরিচালনা করার প্রয়োজন এড়ানো।
ভিক্টর স্টাফুসা

2
আমি ভিক্টরের সাথে একমত, কারণ VO কে ম্যানুয়ালি বজায় রাখা সময় নষ্ট করা এবং পার্থক্যের ঝুঁকি, কম-বেশি দৃশ্যমান এবং যোগ্য হতে পারে .. ডাব্লুএসডিএল 2 জাভা এর ঠিক উদ্দেশ্য, তাই এটি কার্যকর এবং সুরক্ষিত!
ডোনাটেলো

4

সিএক্সএফ 3.1.7 এর জন্য আপডেট

আমার ক্ষেত্রে আমি ডাব্লুএসডিএল ফাইলগুলি রেখেছি src/main/resourcesএবং এই পথটি আমার গ্রিসে আমার ক্রয়ে যুক্ত করেছি (প্রকল্পের উপর ডান ক্লিক করুন-> নির্মাণের পথে -> বিল্ড পাথটি কনফিগার করুন ...-> উত্স [ট্যাব] -> ফোল্ডার যুক্ত করুন)।

এখানে আমার pomফাইলটি কেমন দেখাচ্ছে এবং দেখা যাবে সেখানে কোনও wsdlLocation বিকল্পের প্রয়োজন নেই:

       <plugin>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-codegen-plugin</artifactId>
            <version>${cxf.version}</version>
            <executions>
                <execution>
                    <id>generate-sources</id>
                    <phase>generate-sources</phase>
                    <configuration>
                        <sourceRoot>${project.build.directory}/generated/cxf</sourceRoot>
                        <wsdlOptions>
                            <wsdlOption>
                                <wsdl>classpath:wsdl/FOO_SERVICE.wsdl</wsdl>
                            </wsdlOption>
                        </wsdlOptions>
                    </configuration>
                    <goals>
                        <goal>wsdl2java</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

এবং এখানে উত্পাদিত পরিষেবা। যেমন দেখা যায় যে URL টি ClassLoader এর কাছ থেকে পাওয়া যায়, না তবে পরম ফাইল-পাথ থেকে

@WebServiceClient(name = "EventService", 
              wsdlLocation = "classpath:wsdl/FOO_SERVICE.wsdl",
              targetNamespace = "http://www.sas.com/xml/schema/sas-svcs/rtdm-1.1/wsdl/") 
public class EventService extends Service {

public final static URL WSDL_LOCATION;

public final static QName SERVICE = new QName("http://www.sas.com/xml/schema/sas-svcs/rtdm-1.1/wsdl/", "EventService");
public final static QName EventPort = new QName("http://www.sas.com/xml/schema/sas-svcs/rtdm-1.1/wsdl/", "EventPort");
static {
    URL url = EventService.class.getClassLoader().getResource("wsdl/FOO_SERVICE.wsdl");
    if (url == null) {
        java.util.logging.Logger.getLogger(EventService.class.getName())
            .log(java.util.logging.Level.INFO, 
                 "Can not initialize the default wsdl from {0}", "classpath:wsdl/FOO_SERVICE.wsdl");
    }       
    WSDL_LOCATION = url;   
}

<configuration> <sourceRoot>${basedir}/src/main/java/</sourceRoot> <wsdlRoot>${basedir}/src/main/resources/</wsdlRoot> <includes> <include>*.wsdl</include> </includes> </configuration> আমি সমস্ত .wsdl ফাইলগুলিকে শ্রেণীর পথে অন্তর্ভুক্ত করি তারপরে আমি কীভাবে ডাব্লুএসডিএল অবস্থান নির্দিষ্ট করতে পারি যাতে প্রতিটি উত্পন্ন। জাভা ফাইল সংশ্লিষ্ট .Wdl পাথের সাথে যোগাযোগ করতে পারে? আগাম ধন্যবাদ. @ মেজি
খালিদ শাহ

2

গুরুতরভাবে, শীর্ষ উত্তরটি আমার পক্ষে কাজ করছে না। cxf.version 2.4.1 এবং 3.0.10 ব্যবহার করে দেখুন। এবং প্রতিবার wsdlLocation সহ পরম পাথ তৈরি করুন।

আমার সমাধানটি হ'ল wsdl2javaকমান্ডটি ব্যবহার apache-cxf-3.0.10\bin\ করা -wsdlLocation classpath:wsdl/QueryService.wsdl

বিস্তারিত:

    wsdl2java -encoding utf-8 -p com.jeiao.boss.testQueryService -impl -wsdlLocation classpath:wsdl/testQueryService.wsdl http://127.0.0.1:9999/platf/testQueryService?wsdl

0

@ মার্টিন ডিভিলারস সমাধান ভাল কাজ করে। সম্পূর্ণতার জন্য, নীচের পদক্ষেপগুলি সরবরাহ করে:

  1. আপনার wsdl রিসোর্স ডিরেক্টরিতে যেমন রাখুন: src/main/resource
  2. পম ফাইলে, wsdlDirectory এবং wsdlLocation উভয় যোগ করুন (wsdlLocation এর শুরুতে মিস / মিস করবেন না), নীচের মত। যখন wsdlDirectory কোড তৈরি করতে ব্যবহৃত হয় এবং ডায়নামিক প্রক্সি তৈরির জন্য wsdlLocation রানটাইম ব্যবহার করা হয়।

    <wsdlDirectory>src/main/resources/mydir</wsdlDirectory>
    <wsdlLocation>/mydir/my.wsdl</wsdlLocation>
  3. তারপরে আপনার জাভা কোডে (নো-আরগ কনস্ট্রাক্টর সহ):

    MyPort myPort = new MyPortService().getMyPort();
  4. উত্পন্ন কোডে সাবলীল এপিআই সহ পম ফাইলে সম্পূর্ণ কোড উত্পন্ন অংশটি এখানে রয়েছে।

    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.5</version>
    
    <dependencies>
        <dependency>
            <groupId>org.jvnet.jaxb2_commons</groupId>
            <artifactId>jaxb2-fluent-api</artifactId>
            <version>3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.ws</groupId>
            <artifactId>jaxws-tools</artifactId>
            <version>2.3.0</version>
        </dependency>
    </dependencies>
    
    <executions>
        <execution>
            <id>wsdl-to-java-generator</id>
            <goals>
                <goal>wsimport</goal>
            </goals>
            <configuration>
                <xjcArgs>
                    <xjcArg>-Xfluent-api</xjcArg>
                </xjcArgs>
                <keep>true</keep>
                <wsdlDirectory>src/main/resources/package</wsdlDirectory>
                <wsdlLocation>/package/my.wsdl</wsdlLocation>
                <sourceDestDir>${project.build.directory}/generated-sources/annotations/jaxb</sourceDestDir>
                <packageName>full.package.here</packageName>
            </configuration>
        </execution>
    </executions>

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.