webservice初体验-cxf

前言

最近一段时间,说忙也不是很忙,说闲但确实很少有时间能静下心来写点东西。但于我而言,做任何仪式感很重要,就算没时间坚持,那仪式感也不能丢,这是一种态度,也是最后的底线。今天的这篇推文,是很久以前就实践过了,前几天又整理了一下,上周没有发,本周必须要更新,不敢再堕落了,毕竟已经2020年了。好了开始正题吧。

1、依赖环境

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    
       <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http-jetty</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-features-logging</artifactId>
            <version>${cxf.version}</version>
        </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.11.1</version>
    </dependency>
    
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>2.11.1</version>
      <scope>test</scope>
    </dependency>

注意: 上面的写法是maven加载包的方式,如果不想创建maven项目,可以直接把cxf/lib下的所有包加载到你的项目中也是可以的

2、基本写法

@WebService()
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface MyService {
    /**
     * 人员基本信息查询校验
     *
     * @param name
     * @return String
     * @throws GeneralException
     */
    @WebMethod
    String sayHello(@WebParam(name = "name") String name);
}
  • 注意:如果action不清楚的话,建议不写
实现类:
public class MyserviceImpl implements Myservice {
    @Override
public String sayHello(String name) {
    return name + ",Hello!";
}

注意:

实现类必须和接口在同一级目录下,否则会出现参数无法被识别的情况

3、发布方式

  • (1).默认的发布方式

我发布就是用的这种方式,将发布的代码写在监听器里,这种方式最简单

public class StartListener implements ServletContextListener {
private Logger log = LogManager.getLogger(StartListener.class);
    private final Myservice myservice = new MyserviceImpl();
    private Endpoint endpoint = null;
    String address="http://localhost:7001/myservice";
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
            endpoint = Endpoint.publish(address, myservice);
            log.info("发布MyserviceImpl webservice成功,地址:" + address);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        if (this.endpoint.isPublished())
            this.endpoint.stop();
        log.error("服务被销毁……");
    }
}
  • (2)spring发布

    • 1)引入Spring包

    加入如下依赖

    <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${spring.version}</version>
            </dependency>

    或者直接引入二进制包

    spring-aop-5.1.4.RELEASE.jar
    spring-beans-5.1.4.RELEASE.jar
    spring-context-5.1.4.RELEASE.jar
    spring-core-5.1.4.RELEASE.jar
    spring-expression-5.1.4.RELEASE.jar
    spring-web-5.1.4.RELEASE.jar
    • 2)在classPath下添加applicationContext-cxf.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
   xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:soap="http://cxf.apache.org/bindings/soap"  
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
       http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <!-- 这里配置的是webservice的实现类, --> 
 <!--相当于:JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();   -->
<jaxws:server address="/" serviceClass="lss.medicare.ydjy.ejb.YDJYHospServiceBean">  
   <!-- 配置消息拦截器 -->
   <!-- 这种方式已经过期 -->
   <!--
   <jaxws:inInterceptors>  
       <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>  
   </jaxws:inInterceptors>  
   <jaxws:outInterceptors>  
       <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>  
   </jaxws:outInterceptors>  
   -->
       <!-- 这个是替代类 -->
   <jaxws:features>
       <bean class="org.apache.cxf.ext.logging.LoggingFeature"/>
   </jaxws:features>
</jaxws:server>
</beans>
  • 3)在web.xml中添加如下配置
<context-param>  
    <param-name>contextConfigLocation</param-name>  <!-- 
    这里配置我们上面添加的配置文件,保证配置可以正常加载
    -->
    <param-value>classpath:applicationContext-cxf.xml</param-value>  
</context-param>  
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
    <servlet-name>cxf</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>cxf</servlet-name>
    <!-- 这里配置的是访问路径,我下面的配置的访问路径是  http://127.0.01:9901/webservice/webservice?wsdl -->
    <url-pattern>/webservice/*</url-pattern>
</servlet-mapping>

说明: 配置完成就可以启动你的服务了,如果没有意外,服务已经可以正常考虑

4、注意事项

4.1、客户端兼容性考虑:

  • 因为我这边的需求是要兼容旧版本的webservice(编码格式encoded,也就是weblogic 12C之前的版本),所以单使用cxf并没有解决我的问题,查阅很很多资料,搜索了很多博客,也尝试了很多方法,最后我的解决方案是引入axis1.4来生成客户端,来兼容老版本的webservice,以下是引入axis的操作:
依赖
<dependency>
    <groupId>org.apache.axis</groupId>
    <artifactId>axis</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>com.pansky.axis</groupId>
    <artifactId>jaxrpc</artifactId>
    <version>1.0.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/commons-discovery/commons-discovery -->
    <dependency>
        <groupId>commons-discovery</groupId>
        <artifactId>commons-discovery</artifactId>
        <version>0.2</version>
    </dependency>

注意:

1、这里需要注意的是除了引入axis的包还要引入jaxrpc.jar这个包,当然这包在axis的lib下有,如果你本地用maven的话需要你手动添加到本地仓库,不是很清楚网上有没有,反正我是自己添加的;

2、这里还要添加的是commons-logging和commons-discovery,因为axis1.4依赖这两个包,不添加的话启动会报错

3、这一点和你发布的环境有关,因为我发布的是weblogic,应该这样说吧,都会有冲突,但是本地没有任何冲突,但是到正式环境启动的时候提示javax.xml.namespace.QName冲突,因为在jdk的rt.jar包下用这个类,在jaxrpc.jar中也存在,最后我的解决方法简单粗暴:

删除jaxrpc.jar下的这个类,因为我的项目完全没有用的这里包下的这个类,所以问题解决了,也没有其他问题

##### 接口Java客户端代码生成

wsdl2java -p io.github.syske.webservice.client -d java -client http://127.0.0.1/webservice

-p 包名

-d 保存路径

-client 服务端地址

相关推荐