`

jax-ws WebService相关问题(一)

 
阅读更多

1.使用JDK6自带的JAX-WS + Jboss4.2.3 开发WebService发布WebService报错? java.lang.ClassNotFoundException: com.sun.xml.ws.transport.http.servlet.WSServletContextListener

 

解释:JDK本身不带基于Servlet的代码,自带的jax-ws 不带WSServlet和WSServletContextListener两个类,在j2ee的jar包里才有

 

解决方案:

    a.使用代码中Endpoint.publish()发布(轻量级HTTP Server);

       

Endpoint.publish("http://localhost:8080/HelloService", new HelloSEI());

    缺点是每次代码发布很麻烦,修改也麻烦,而且每个IP和端口只能发布一个

 

    b.使用Spring自带的SimpleJaxWsServiceExporter发布(轻量级HTTP Server);

       

<bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter">
    <property name="baseAddress" value="http://localhost:8080/"/>
</bean>

<bean id="accountServiceEndpoint" class="example.AccountServiceEndpoint">
    ...
</bean>

    缺点是每个IP和端口只能发布一个

 

    c.使用jaxws-spring.jar提供的WSSpringServlet方式发布(Servlet发布):

        这需要使用到2个额外的jar包:

        jaxws-spring-1.8.jar

        xbean-spring-v2-2.8.jar

        配置方式:

        web.xml

<web-app>
  <!-- this is for Spring -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- these are for JAX-WS -->
  <servlet>
    <servlet-name>jaxws-servlet</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>jaxws-servlet</servlet-name>
    <url-pattern>/add</url-pattern>
  </servlet-mapping>
  ... if you deploy more services,
  you might need more <servlet-mapping>s ...
</web-app>

    

    applicationContext.xml

    

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ws="http://jax-ws.java.net/spring/core"
  xmlns:wss="http://jax-ws.java.net/spring/servlet"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://jax-ws.java.net/spring/core
    http://jax-ws.java.net/spring/core.xsd
    http://jax-ws.java.net/spring/servlet
    http://jax-ws.java.net/spring/servlet.xsd">

  <wss:binding url="/add" service="#addService" />
  <wss:binding url="/sub">
    <wss:service><!-- nested bean is of course fine -->
      <ws:service bean="#myService" />
    </wss:service>
  </wss:binding>

  <!-- this bean implements web service methods -->
  <bean id="myService" class="foo.MyService" />

  <!-- simplest definition only needs the class name -->
  <ws:service id="addService" impl="foo.MyAddService" handlers="#myHandler"/>

  <bean id="myHandler" class="foo.MyHandler" />

</beans>

 

2.Client端同样部署在jboss web容器上的时候,客户端调用报: java.lang.ClassCastException: com.sun.xml.ws.client.WSServiceDelegate cannot be cast to javax.xml.ws.spi.ServiceDelegate21

 

解释: 这是由于JBOSS有自带的jax-ws api的实现,称为jbossws。导致api类实现冲突。

解决方案:

思路是将JDK总的JAX-WS实现相关的类替换为加载JBOSS的JAX-WS API实现类。

 

做法是将jboss/lib/endorsed/ 目录下的:

                  jboss-jaxrpc.jar

                  jboss-jaxws.jar

                  jboss-jaxws-ext.jar

                  jboss-saaj.jar

                  xercesImpl.jar

拷贝到%JAVA_HOME%/jre/endorsed/目录下。(这使用了JDK的endorsed机制,请查阅相关资料)

JDK的endorsed目录可以根据System.getProperty("java.endorsed.dirs")获得。 需要注意的是:在web容器使用哪个JDK就在那个JDK下面去修改。

 

3.发布的wsdl里面如果import 了wsdl和xsd文件时,客户端访问每次都会Addressing,如何将本地war包里面的xsd和wsdl和发布的服务绑定上?

解释:这个是由于WS的机制造成的,JAX-WS官方提供了解决方案。

解决方案:采用添加jax-ws-catalog的方式,绑定本地的xsd和wsdl

 

<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer=" system"> 
    < system systemId=" http://foo.org/hello?wsdl" uri="HelloService.wsdl"/> 
</catalog>

 

Jax-ws-catalog.xml的放置位置:

Ø  wsimport 命令行或者ant任务

使用-catalog 可选参数,指定catalog file. 例如:

-catalog jax-ws-catalog.xml

 

Ø  WebService客户端运行时环境

Classpath下的该目录:META-INF/jax-ws-catalog.xml

(.jar包中的META-INF/jax-ws-catalog.xml也算)

 

Ø  轻量级的基于HTTP server (j2se)的endpoint发布

就是说是通过调用接口EndPoint.publish(),并指定了HttpServer的。

包括通过Spring的轻量级发布辅助类发布的:

org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter

org.springframework.remoting.jaxws.SimpleHttpServerJaxWsServiceExporter

Classpath下的该目录:META-INF/jax-ws-catalog.xml

 

Ø  基于Servlet的endpoint

WEB-INF/jax-ws-catalog.xml

 

Ø  基于JSR 109标准的 EJB 模块发布

META-INF/jax-ws-catalog.xml

【备注】

笔者在使用CXF作为webservice实现的时候通过指定jax-ws-catalog.xml是能够很好的被加载解析。但是使用JDK自带的jax-ws或者Metro jax-ws RI时,使用JBOSS作为发布容器,始终不能正确执行jax-ws-catalog.xml中描述的 import wsdl/xsdschema引用替换,进一步调试发现是通过jndi的方式访问了jax-ws-catalog.xml,但是没达到使用本地wsdl/xsd的效果

 

4.如何采用endpoint的方式发布一个servcename下有多个portname的WebService?

how to publish multi port webservice with same serviceName?

解释:一般看JAX-WS RI上的例子或者Spring的两个http Stand alone publish 发布辅助类(上文提到的:Spring的轻量级发布辅助类),都看不到这方面的资料。是因为多 port 使用的比较少。

解决方案:扩展Spring提供的http endpoint pubish类 :AbstractJaxWsServiceExporter。

该类胡自动解析带有@WebService注解的初始化为Spring bean了的endpoint发布类,并基于配置的basepath进行发布,发布地址:http://hostname:port/basepath/serviceName/portName

 

代码:

import java.net.InetSocketAddress;
import java.util.List;


import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import javax.xml.ws.WebServiceProvider;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.remoting.jaxws.AbstractJaxWsServiceExporter;


import com.sun.net.httpserver.Authenticator;
import com.sun.net.httpserver.Filter;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpServer;


public class PortableHttpServerJaxWsServiceExporter extends
    AbstractJaxWsServiceExporter
{
    private static final Logger LOG = LoggerFactory.getLogger(PortableHttpServerJaxWsServiceExporter.class);
    
    public PortableHttpServerJaxWsServiceExporter()
    {
        port = 8080;
        backlog = -1;
        shutdownDelay = 0;
        basePath = "/";
        localServer = false;
    }


    public void setServer(HttpServer server)
    {
        this.server = server;
    }


    public void setPort(int port)
    {
        this.port = port;
    }


    public void setHostname(String hostname)
    {
        this.hostname = hostname;
    }


    public void setBacklog(int backlog)
    {
        this.backlog = backlog;
    }


    public void setShutdownDelay(int shutdownDelay)
    {
        this.shutdownDelay = shutdownDelay;
    }


    public void setBasePath(String basePath)
    {
        this.basePath = basePath;
    }


    public void setFilters(List<Filter> filters)
    {
        this.filters = filters;
    }


    public void setAuthenticator(Authenticator authenticator)
    {
        this.authenticator = authenticator;
    }


    @Override
    public void afterPropertiesSet() throws Exception
    {
        if (server == null)
        {
            InetSocketAddress address = (hostname == null ? new InetSocketAddress(
                port)
                : new InetSocketAddress(hostname, port));
            server = HttpServer.create(address, backlog);
            if (logger.isInfoEnabled())
                logger.info((new StringBuilder(
                    "Starting HttpServer at address ")).append(address)
                    .toString());
            server.start();
            localServer = true;
            
            LOG.info("Start http server successful. hostname: {}, port: {}", hostname, port);
        }
        super.afterPropertiesSet();
    }


    @Override
    protected void publishEndpoint(Endpoint endpoint, WebService annotation)
    {
        endpoint.publish(buildHttpContext(endpoint, annotation.serviceName(),
            annotation.portName()));
    }


    @Override
    protected void publishEndpoint(Endpoint endpoint,
        WebServiceProvider annotation)
    {
        endpoint.publish(buildHttpContext(endpoint, annotation.serviceName(),
            annotation.portName()));
    }


    protected HttpContext buildHttpContext(Endpoint endpoint,
        String serviceName, String portName)
    {
        String fullPath = calculateEndpointPath(endpoint, serviceName, portName);
        HttpContext httpContext = server.createContext(fullPath);
        if (filters != null)
            httpContext.getFilters().addAll(filters);
        if (authenticator != null)
            httpContext.setAuthenticator(authenticator);
        
        LOG.info("Listen http context at full path : {}.", httpContext.getPath());
        
        return httpContext;
    }


    protected String calculateEndpointPath(Endpoint endpoint,
        String serviceName, String portName)
    {
        if (null == portName)
        {
            return (new StringBuilder(String.valueOf(basePath))).append(
                serviceName).toString();
        }
        return (new StringBuilder(String.valueOf(basePath)))
            .append(serviceName).append("/").append(portName).toString();
    }


    @Override
    public void destroy()
    {
        super.destroy();
        if (localServer)
        {
            logger.info("Stopping HttpServer");
            server.stop(shutdownDelay);
        }
    }


    protected final Log logger = LogFactory.getLog(getClass());


    private HttpServer server;


    private int port;


    private String hostname;


    private int backlog;


    private int shutdownDelay;


    private String basePath;


    private List<Filter> filters;


    private Authenticator authenticator;


    private boolean localServer;
}

 

发布方式:

<bean class="com.huawei.ossj.ws.publisher.PortableHttpServerJaxWsServiceExporter">
        <property name="basePath" value="/" />
        <property name="port" value="19900" />
    </bean>

 

 

 

 

分享到:
评论

相关推荐

    jax-ws webservice demo

    基于jax-ws 实现的web service client和server端的demo程序。 注:如果使用的是 myeclipse 时 server 部署到tomcat 启动的时候会报错 解决办法:找到myeclipse安装目录下的 plugins 目录里 查找 webservices-rt.jar,...

    jax-ws webservice简单demo

    在这个"jax-ws webservice简单demo"中,我们将探讨JAX-WS的基础知识、如何创建一个简单的Web服务以及如何测试这个服务。 首先,JAX-WS的核心组件包括: 1. **Service端点接口(SEI, Service Endpoint Interface)**...

    如何基于JAX-WS开发一个WebService实例

    本篇将深入讲解如何基于JAX-WS开发一个WebService实例。 首先,让我们了解JAX-WS的基本概念。JAX-WS提供了一种简单的方式来创建SOAP(Simple Object Access Protocol)Web服务,它集成了Java SE和Java EE平台,使得...

    jax-ws实现webservice调用

    **Java API for XML Web Services (JAX-WS)** 是一种由Java SE和Java EE平台支持的用于构建Web服务的标准API。它使得开发人员能够轻松地创建、部署和使用基于SOAP(简单对象访问协议)的Web服务。在本教程中,我们将...

    jax-ws WebService客户端与服务端工程.rar

    这个"jax-ws WebService客户端与服务端工程.rar"压缩包文件包含了一个完整的示例,展示了如何使用JAX-WS创建和消费Web服务。让我们深入探讨一下JAX-WS的核心概念和技术。 1. **Web服务基础**: - **SOAP(Simple ...

    Jax-ws所需要的JAR包

    这些JAR文件包含了JAX-WS的运行时库和相关的服务实现。描述中提到的"Jax-ws所需要的JAR包"很可能包括了以下几个关键组件: 1. **jaxws-api.jar**:这是JAX-WS的API规范JAR,包含了用于开发JAX-WS服务和客户端的接口...

    jax-ws发布webservice

    Java API for XML Web Services(JAX-WS)是Java平台上的一个标准,用于构建和部署Web服务。它简化了Web服务的开发,使得Java开发者能够更方便地创建、调用和部署SOAP(Simple Object Access Protocol)服务。在这个...

    MyEclipse8_0中使用 JAX-WS 部署 WebService 实例

    MyEclipse8_0中使用 JAX-WS 部署 WebService 实例 - 外衣 - 博客频道 - CSDN_NET.mht

    JAX-WS Webservice

    `jaxws-ri`是JAX-WS参考实现的源代码包,包含JAX-WS API的实现以及相关的工具,如`wsimport`,用于从WSDL生成客户端代码。开发者可以使用这个库来快速开发和测试JAX-WS Web服务。 **7. JAX-WS与JAX-RS比较** JAX-...

    jax-ws WebService使用教程

    讲解了从服务器端的开发,到Tomcat服务器部署,再到客服端调用,整个开发流程,并有实例代码

    webservice之jax-ws

    JAX-WS取代了早期的JAX-RPC(Java API for XML-based RPC),提供了一个更加现代、轻量级且基于标准的框架。 1. **SOAP与Web服务** SOAP(简单对象访问协议)是一种基于XML的协议,用于交换结构化的信息。Web服务...

    jax-ws api jar包

    - **@WebService**:这是JAX-WS中的一个关键注解,用于标记一个Java类作为Web服务的接口。它允许开发者定义服务端点接口(SEI,Service Endpoint Interface),其中包含了服务的方法。 - **@SOAPBinding**:这个...

    基于JDK自带的Web服务JAX-WS实现WebService的简单示例

    Java 基于第三方插件实现WebService实在麻烦,尤其是要添加几十M的Jar包...还好,自从JDK 1.6开始,Java自身已经支持WebSeervice的开发即JAX-WS,附件是一个简单的示例,供入门参考。注意,JDK环境要求1.6及以上版本。

    JAX-WS_WebService.rar

    JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用,JAX-WS方式开发和部署webservice应用

    JAX-WS 2.2 RI所有相关jar包

    JAX-WS 2.2 RI 所包含的JAR包集合,包含25个JAR包,列表如下: FastInoset.jar gmbal-api-only.jar ha-api.jar javax.annotation.jar javax.mail_1.4.jar jaxb-api.jar jaxb-impl.jar jaxb-xjc.jar jaxws-api...

    jax-ws创建webservice

    Java API for XML Web Services(jax-ws)是Java平台标准版(Java SE)和企业版(Java EE)的一部分,它为开发者提供了一种创建和消费Web服务的标准方式。jax-ws允许开发人员通过简单的编程模型来实现基于SOAP的Web...

    JAX-WS2.0 API

    JAX-WS(Java API for XML Web Services)2.0 API 是Java平台上的一个标准接口,用于创建和消费Web服务。它提供了一种简单、类型安全且与平台无关的方式来实现基于SOAP(Simple Object Access Protocol)的Web服务。...

    webservice Demo注解+jax-ws

    总的来说,“webservice Demo注解+jax-ws”是一个很好的学习资源,帮助初学者了解如何使用Java注解和JAX-WS来创建、部署和使用Web服务。通过阅读提供的文档和实践示例,你将能够深入理解Web服务的基本原理,并具备...

    MyEclipse6_5上基于JAX-WS开发Webservice(中文示例)

    在IT行业中,Web服务是一种...总之,MyEclipse 6.5结合JAX-WS提供了一种高效的方式来创建和使用Web服务。通过理解JAX-WS的基本概念,并熟悉MyEclipse中的相关工具,开发者可以快速地构建跨平台、跨语言的应用程序交互。

    metro-jax-ws-jaxws221x.zip

    【标题】"metro-jax-ws-jaxws221x.zip" 提供的是一个关于JAX-WS(Java API for XML Web Services)的开发示例,其中包含了JAX-WS 2.2.1版本的相关组件和库文件。这个压缩包是针对Java开发者设计的,用于帮助他们理解...

Global site tag (gtag.js) - Google Analytics