如何創建webservice以及如何調用現有的webservice

由於工作需要使用到webservice,項目框架爲spring,webservice框架爲CXF。

一.如何使用CXF發佈一個webservice服務

1.首先下載CXF的程序壓縮包,作者下載的是apache-cxf-3.1.8,將其中的lib目錄下的包拷貝到項目的根目錄下,由於作者的項目用的是spring框架,所以要把其中的有關spring的架包刪除,要不然會衝突,記得將架包引入到項目中,如果使用maven也可以直接使用maven來引入。

2.修改項目的配置文件,即spring的配置文件:

修改bean的元素描述,其中紅色部分爲新增行

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xsi:schemaLocation="
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
          http://cxf.apache.org/jaxws
          http://cxf.apache.org/schemas/jaxws.xsd">
在配置文件尾部加入需要引入的xml文件,下面倆個文件都是在CXF的架包中,作者將他們直接拿到了配置文件目錄下。3.1.8版本只需要引入這倆個文件,早期的版本可能會需要引用三個。
    <import resource="cxf.xml"/>
    <import resource="cxf-servlet.xml"/>
在web.xml文件中加入以下配置,啓用CXF的servlet,並且將匹配/webservice/*的請求解析爲請求webservice。
        <servlet>
                <servlet-name>CXFServlet</servlet-name>
                <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
                <load-on-startup>1</load-on-startup>
        </servlet>

        <servlet-mapping>
                <servlet-name>CXFServlet</servlet-name>
                <url-pattern>/webservice/*</url-pattern>
        </servlet-mapping>
3.編寫webservice服務端代碼:

webservice服務端代碼分爲倆個類,一個爲服務接口,一個爲接口實現類。

接口HelloInteface.java

<pre name="code" class="java">package com.zy.webservice;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface HelloInteface{
    public String sayHello(@WebParam(name = "userName")String name);
}



實現HelloIntefaceImpl

<pre name="code" class="java">package com.zy.webservice;
import javax.jws.WebService;
@WebService(endpointInterface= "com.zy.webservice.HelloInteface")
public class HelloIntefaceImpl implements HelloInteface{

    @Override
    public String sayHello(String name)
   {
      return "hello"+name;
   }

}



4.發佈代碼爲webservice:

在spring的配置文件中將上面的實現類配置爲webservice:

<pre name="code" class="java"><jaxws:endpoint id="helloworld" implementor="com.zy.webservice.HelloIntefaceImpl"
address="/hello"/>
5.啓動服務,在瀏覽器中輸入localhost:8080/myweb/webservice/hello?wsdl,如果頁面顯示出wsdl文件的內容即發佈
成功。記住要加上?wsdl。


二.如何調用現有的webservice

準備工作:獲取到webservice的wsdl地址,如果需要驗證則需要用戶名以及密碼。

1.將wsdl解析爲java代碼

進入cxf.3.1.8的bin目錄,運行wsdl2java 你的wsdl地址,如果該地址無需賬戶驗證可以直接解析,如果需要驗證,則先使用網頁打開wsdl地址,輸入用戶名密碼驗證後會顯示相應的內容,再將頁面另存爲wsdl文件,最後使用wsdl2java解析即可。

解析後的文件一般有一下幾個:一個接口類,該接口的服務類,XXXXRequest(接口方法所需要的參數),XXXXResponse(方法的返回值),ObjectFactory,package-info.java。後面倆個文件不需要去管。

首先創建一個測試類:

public class TestWebservice

{

public static void main(String[]] args)

{

服務類 service=new 服務類();

接口類 port=service.getXXXport();

XXXXRequest request=new XXXXRequest();

XXXXResponse reponse=port.XXXfunction(request);

}

}

上面的類表現出了大概的調用過程,具體的情況要看具體的需求,可能會出現沒有返回值,參數等等。

特別需要注意的是,如果調用的wsdl需要用戶驗證怎麼辦。這邊引入一片外文,作者使用的是方法二。

HTTP basic authentication with JAX-WS (Client)
Labels: java, web services
JAX-WS does not do very well with HTTP basic authentication. In general, to create and use a web-service client you have to perform the following steps: 1. Use wsimport to generate the stub files 2. Create a service class in the client 3. Retrieve a proxy to the service, also known as a port All three steps could require HTTP basic authentication. And for each step it have to be handled in a different way.
1. The stub files generation
If access to a wsdl file is restricted with basic authentication, wsimport fails to get it. Unfortunately it does not support the common approach to write access credentials right into the URL (RFC 1738). It is not a big deal to resolve this issue. You just need to create a server authentication file: $HOME/.metro/auth. This file should have the WSDL URL with username and password in the RFC 1738 format:
http[s]://user:password@host:port//
You can have line delimited multiple entries in this file and they can be used for various sites that need basic authentication.
2. The service class creation
A constructor of the service object requires access to the WSDL. And again it does not support basic authentication out of the box. You have an option to download the wsdl file and use it locally. Another option is to use the default authenticator:
Authenticator.setDefault(new Authenticator() {
 @Override
 protected PasswordAuthentication getPasswordAuthentication() {
   return new PasswordAuthentication(
     USER_NAME,
     PASSWORD.toCharArray());
 }
});
3. The service class configuration
And the last but not least part of our adventure is configuration of the service port:
OurWebService service = new OurWebService ();
OurWebServicePortType port = service.getOurWebServicePortType();

BindingProvider bindingProvider = (BindingProvider)port;
Map requestContext = bindingProvider.getRequestContext();
requestContext.put(BindingProvider.USERNAME_PROPERTY, USER_NAME);
requestContext.put(BindingProvider.PASSWORD_PROPERTY, PASSWORD);
Done! Now you are able to use methods of the port object to communicate with a web service.
方法二的初始化方法需要加入到service類中,最後的service應該類似於下面:

@WebServiceClient(name = "AdminWebServiceService", targetNamespace = "http://server3.wservice3", wsdlLocation = "http://localhost:9001/wservice3/services/AdminWebService?wsdl")
public class AdminWebServiceService
    extends Service
{

    private final static URL ADMINWEBSERVICESERVICE_WSDL_LOCATION;
    private final static Logger logger = Logger.getLogger(com.myapp.test.wservice3.server3.AdminWebServiceService.class.getName());

    static {
        Authenticator.setDefault(new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
              return new PasswordAuthentication(
                "myusername",
                "mypassword".toCharArray());
            }
           });
        URL url = null;
        try {
            URL baseUrl;
            baseUrl = com.myapp.test.wservice3.server3.AdminWebServiceService.class.getResource(".");
            url = new URL(baseUrl, "http://localhost:9001/wservice3/services/AdminWebService?wsdl");
        } catch (MalformedURLException e) {
            logger.warning("Failed to create URL for the wsdl Location: 'http://localhost:9001/wservice3/services/AdminWebService?wsdl', retrying as a local file");
            logger.warning(e.getMessage());
        }
        ADMINWEBSERVICESERVICE_WSDL_LOCATION = url;
    }

    public AdminWebServiceService(URL wsdlLocation, QName serviceName) {
        super(wsdlLocation, serviceName);
    }

    public AdminWebServiceService() {
        super(ADMINWEBSERVICESERVICE_WSDL_LOCATION, new QName("http://server3.wservice3", "AdminWebServiceService"));
    }
 
    @WebEndpoint(name = "AdminWebService")
    public AdminWebService getAdminWebService() {
        return super.getPort(new QName("http://server3.wservice3", "AdminWebService"), AdminWebService.class);
    }

    @WebEndpoint(name = "AdminWebService")
    public AdminWebService getAdminWebService(WebServiceFeature... features) {
        return super.getPort(new QName("http://server3.wservice3", "AdminWebService"), AdminWebService.class, features);
    }
}









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章