SpringBoot2 应用 Axis 1.4 开发 WebService

有了前一篇 应用 Axis 1.4 开发 WebService 的对 Axis 1 较为深刻的理解后,现在正式给古老的 Axis 1.4  拉个伴,那就是 SpringBoot2。SpringBoot2 + Axis 1 的主要工作就是把 Axis 的 web.xml 用 SpringBoot2 的方式进行转述。

在 SpringBoot 中用 Axis 1 后,有两个特性不再支持

  1. 不再支持 jws 即时发布 Web Service,不能直接搬用 url-pattern *.jws,没继续深究,实际中希望这么部署的方式用得较少
  2. 不再支持 SOAPMonitorService,它是一个 Java Applet,  Java Applet 在新版的 JDK 中已被移除,早就不推荐使用了

在 SpringBoot 中配置 Servlet 或 ServletListener 有两种方式

  1. ServletRegistrationBean/ServletListenerRegistrationBean
  2. @WebServlet/@WebListener

spring-boot-starter 引入了 log4j-to-slf4j, jul-to-slf4j, 所以不需要配置 log4j.properties, 需要的话可用 logback.xml 配置日志输出。

下面来看整个 SpringBoot2 + Axis 1 项目的目录结构(Maven 项目)

该项目已上传至 GitHub springboot2-axis1.4

项目及配置解析

下面是对该项目的关键部分的说明

依赖包

pom.xml

Axis 1.4 中间的依赖是根据下载的 axis-bin-1_4.tar.gz 解压后 webapps/axis/WEB-INFO/lib 目录中 jar 包依赖改成用 Maven 来管理,外加了一个 javax.mail 依赖,省得启动服务时总提示没有 mail 组件的警告信息。其他为 SpringBoot2 的依赖,由于 Axis 是一个 Web 项目,所以引入了 spring-boot-starter-web。

日志方面,由于 spring-boot-starter-logging 的介入,log4j, jul 的日志全被 slf4j 接管,最终由 LogBack 输出,所以只需要 logback.xml,或者完全在 application.properties 中配置日志也行。

src/main/webapps/WEB-INF/server-config.wsdd 文件是拷贝自 axis 的 server-config.wsdd,用 WSDD 的方式发布 Web Service 要用到它

Servlet/Listener 配置

接着就是转换 axis 的 web.xml 为 SpringBoot 的表达方式,有两种实现

ServletRegistrationBean/ServletListenerRegistrationBean

AppConfig

@WebServlet/@WebListener 的方式

AppConfig1

从中二选一,比如想要用 AppConfig, 则要把  AppConfig1 中的  @Configuration 注解注释掉,反之亦然。

注:用 @WebServlet/@WebListener 的方式时,Servlet 和 Listener 不能为实例的内部类,因此声明类时要用 public static class

加上 /axis/services/*url-pattern 是因为 AdminClient 默认会调用 http://localhost:8080/axis/services/AdminService,如果总是用 -l 参数指定 url 的话,该 url-pattern 可省去。

应用程序入口

Main 启动类没什么特别的,就是一个最简单的 SpringBootApplication 启动类,后面说的重启应用就是重新运行下面的 Main 类

到目前为止,我们可以启动本应用,这是一个 Web 项目(因为引入了 spring-boot-starter-web 依赖),它会起动一个内嵌的  Tomcat, 启动后打开 http://localhost:8080/servlet/,看到

这是一个熟悉的 Apache Axis 1 的 Web Service 列表界面,此时测试 Version.getVersion 服务是可用的, 访问 http://localhost:8080/services/Version?method=getVersion

开发一个简单的 Web Service

现在来开发一个自己简单的 Web Service - HelloService,要添加的 Java 类只要 HelloService, 代码为

发布 HelloService,只要在 server-config.wsdd 中加上几行

暴露 blog.yanbin.ws.HelloService 中的所有 public 方法为 Web Service, 并且服务对象的生命周期是 application。要卸载 HelloService 服务,只要把这几行去掉,并重启应用

完后,只要重启应用程序,再次查看服务列表就能看到

用 http://localhost:8080/services/HelloService?wsdl 查看服务描述。

测试新加的  HelloService

Web 方式,访问 http://localhost:8080/services/HelloService?method=sayHello&name=Yanbin

HelloService 有一个接口是 sayHello, 来测试一下该接口

在 ServiceTest 中有测试该服务的代码,如下

测试通过,并且输出如下:

Hello Yanbin

同时我们在日志配置 logback.xml 设置了 org.apache.axis.transport.http.HTTPSender 的输出级别为 DEBUG,所以能完整看到 HTTP 交互的请求响应的详情

可利用该日志输出信息,用 cURL 或 PostMan 进行一样的 HTTP 请求,这方面的详情请参考上一篇 应用 Axis 1.4 开发 WebService。为了不来回跳跃,还是重复一下吧

$ curl -X POST -H "SOAPAction;" http://localhost:8080/services/HelloService \
--data '<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <sayHello soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
            <arg0 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:string">Yanbin</arg0>
        </sayHello>
    </soapenv:Body>
</soapenv:Envelope>'
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><sayHelloResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><sayHelloReturn xsi:type="xsd:string">Hello Yanbin</sayHelloReturn></sayHelloResponse></soapenv:Body></soapenv:Envelope>

用 deploy.wsdd 文件部署服务

前面是直接修改 server-config.wsdd 的方来部署新服务的,我们也可以通过  AdminClient 来部署,写好了 HelloService 类后,把想要加入到 server-config.wsdd 文件中的内容放在一个单独的文件里,如这里的 deploy.wsdd,内容为

然后可执行类似如下的命令

$ java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8080/services/AdminService test/resources/deloy.wsdd

-Djava.ext.dirs=lib 指定能运行 AdminClient 的含有足够依赖 jar 包的目录,如 axis-bin-1_4.tar.gz 解压后 webapps/axis/WEB-INFO/lib 目录

为了省事,当前项目包含必须的 jar 包,我们直接用 Java 代码来调用 AdminClient 更简单且可重用。本例中写在 RunAdminClient 类中,以单元测试用例的方式呈现

如果要卸载该 HelloService, 把有关它的那几行从 server-config.wsdd 中移除掉,再重启服务就行。或者创建一个 undeploy.wsdd 文件,内容为

再对它执行 AdminClient,如

$ java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8080/services/AdminService test/resources/deloy.wsdd

或是用 RunAdminClient 类中的

用 AdminClient 的好处是不需要每次重启,因为它除了对 server-config.wsdd 文件修改外,还调用 AdminService 在内存里也作了手脚。

问题

如果在 IntelliJ IDEA 中,你的 Axis 应用是一个子模块,那么在 IDE 中启动时须配置

Working directory: $MODULE_DIR$ 

否则运行时报类似如下的错误

16 Nov 2021 19:25:11 [main] ERROR org.apache.axis.configuration.EngineConfigurationFactoryServlet.getServerEngineConfig(162) - Unable to find config file. Creating new servlet engine config file: /WEB-INF/server-config.wsdd
16 Nov 2021 19:25:11 [main] ERROR org.apache.axis.configuration.EngineConfigurationFactoryServlet.getServerEngineConfig(176) - Problem with servlet engine /WEB-INF directory
org.apache.axis.ConfigurationException: Configuration file directory '/private/var/folders/hm/t_nnzqw55g17fqwhf2rgtx3r0000gp/T/tomcat-docbase.8080.3352273356626804333/WEB-INF' does not exist or is not a directory or is not readable.
    at org.apache.axis.configuration.FileProvider.<init>(FileProvider.java:99)
    at org.apache.axis.configuration.EngineConfigurationFactoryServlet.getServerEngineConfig(EngineConfigurationFactoryServlet.java:174)

因为从当前目录开始找不到 src/main/webapp/WEB-INF,而且放在该目录中的 index.html 也不会被注册为 welcome file。

总结

最后好像也没有太多要说,升级到 Apache Axis2, 因为它最近都有更新,Axis 1 早就没人管了。或者还可以选择 Apache CXF 去,CXF 是两个项目的联合体,Celtix 和 XFire(XFire 还真有耳闻),曾经叫过 CeltiXfire,后来缩写成了 CXF(Celtix 含  CX, XFire 含 XF, 大家都公平)。还有一个选择是 Spring WS。这里有一篇三者对比的文章 Apache CXF vs. Apache AXIS vs. Spring WS

链接:

  1. Spring boot axis 1.4 webService Server
  2. The @ServletComponentScan Annotation in Spring Boot
  3. How to Register a Servlet in Java
  4. Using Servlet components: @WebServlet, @WebFilter and @WebListener in Spring boot application

类别: Java/JEE. 标签: , . 阅读(31). 订阅评论. TrackBack.
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x