文章目录
- 一、服务端
- 1. 版本选型
- 2.导入依赖
- 3. SERVLET
- 4. 接口
- 5.实现类
- 6. 配置工厂
- 7.启动类
- 8. WEB-INF目录1
- 8. WEB-INF目录2
- 9. /目录1
- 9. /目录2
- 10. wsdd
- 11. 测试验证
- 二、客户端
- 开源源码.
一、服务端
1. 版本选型
阿健/框架 | 版本 |
---|---|
spring-boot | 2.5.4 |
axis | 1.4 |
axis-jaxrpc | 1.4 |
commons-discovery | 0.2 |
wsdl4j | 1.6.3 |
2.导入依赖
<!--axis start --><dependency><groupId>org.apache.axis</groupId><artifactId>axis</artifactId><version>1.4</version></dependency><dependency><groupId>axis</groupId><artifactId>axis-jaxrpc</artifactId><version>1.4</version></dependency><dependency><groupId>commons-discovery</groupId><artifactId>commons-discovery</artifactId><version>0.2</version></dependency><dependency><groupId>wsdl4j</groupId><artifactId>wsdl4j</artifactId><version>1.6.3</version></dependency><!--axis end -->
3. SERVLET
package com.gblfy.ws.servlet;import org.apache.axis.transport.http.AxisServlet;/*** AxisServlet** @author gblfy* @date 2021-09-17*/
@javax.servlet.annotation.WebServlet(urlPatterns = "/services/*",loadOnStartup = 1,name = "AxisServlet"
)
public class AxisBootServlet extends AxisServlet {
}
4. 接口
package com.gblfy.ws.service;/*** Axis接口** @author gblfy* @date 2021-09-17*/
public interface IAxisService {public String sayHello(String info);public String sayHello2(String info,String info2);
}
5.实现类
package com.gblfy.ws.service.impl;import com.gblfy.ws.service.IAxisService;
import org.springframework.stereotype.Service;/*** Axis接口实现类** @author gblfy* @date 2021-09-17*/
@Service
public class AxisServiceImpl implements IAxisService {/*** @param info* @return*/@Overridepublic String sayHello(String info) {return "sayHello:" + info;}@Overridepublic String sayHello2(String info, String info2) {return info + info2;}
}
6. 配置工厂
新建org.apache.axis.configuration
包
在新建的包下新建EngineConfigurationFactoryServlet
类,集成EngineConfigurationFactoryDefault
第一种:目录为
String appWebInfPath = “/WEB-INF”;
第二种:目录为
String appWebInfPath = “/”;
package org.apache.axis.configuration;/** Copyright 2002-2004 The Apache Software Foundation.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
import org.apache.axis.AxisProperties;
import org.apache.axis.ConfigurationException;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.EngineConfigurationFactory;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.server.AxisServer;
import org.apache.axis.utils.ClassUtils;
import org.apache.axis.utils.Messages;
import org.apache.commons.logging.Log;import javax.servlet.ServletConfig;
import java.io.InputStream;/*** This is a default implementation of ServletEngineConfigurationFactory.* It is user-overrideable by a system property without affecting* the caller. If you decide to override it, use delegation if* you want to inherit the behaviour of this class as using* class extension will result in tight loops. That is, your* class should implement EngineConfigurationFactory and keep* an instance of this class in a member field and delegate* methods to that instance when the default behaviour is* required.** @author Richard A. Sitze* @author Davanum Srinivas (dims@apache.org)*/
public class EngineConfigurationFactoryServletextends EngineConfigurationFactoryDefault {protected static Log log =LogFactory.getLog(EngineConfigurationFactoryServlet.class.getName());private ServletConfig cfg;/*** Creates and returns a new EngineConfigurationFactory.* If a factory cannot be created, return 'null'.* <p>* The factory may return non-NULL only if:* - it knows what to do with the param (param instanceof ServletContext)* - it can find it's configuration information** @see EngineConfigurationFactoryFinder*/public static EngineConfigurationFactory newFactory(Object param) {/*** Default, let this one go through if we find a ServletContext.** The REAL reason we are not trying to make any* decision here is because it's impossible* (without refactoring FileProvider) to determine* if a *.wsdd file is present or not until the configuration* is bound to an engine.** FileProvider/EngineConfiguration pretend to be independent,* but they are tightly bound to an engine instance...*/return (param instanceof ServletConfig)? new EngineConfigurationFactoryServlet((ServletConfig) param): null;}/*** Create the default engine configuration and detect whether the user* has overridden this with their own.*/protected EngineConfigurationFactoryServlet(ServletConfig conf) {super();this.cfg = conf;}/*** Get a default server engine configuration.** @return a server EngineConfiguration*/public EngineConfiguration getServerEngineConfig() {return getServerEngineConfig(cfg);}/*** Get a default server engine configuration in a servlet environment.* <p>* //* @param ctx a ServletContext** @return a server EngineConfiguration*/private static EngineConfiguration getServerEngineConfig(ServletConfig cfg) {String configFile = cfg.getInitParameter(OPTION_SERVER_CONFIG_FILE);if (configFile == null)configFile =AxisProperties.getProperty(OPTION_SERVER_CONFIG_FILE);if (configFile == null) {configFile = SERVER_CONFIG_FILE;}// String appWebInfPath = "/";String appWebInfPath = "/WEB-INF";//由于部署方式变更为jar部署,此处不可以使用改方式获取路径// ServletContext ctx = cfg.getServletContext();// String realWebInfPath = ctx.getRealPath(appWebInfPath);FileProvider config = null;String realWebInfPath = EngineConfigurationFactoryServlet.class.getResource(appWebInfPath).getPath();InputStream iss = ClassUtils.getResourceAsStream(EngineConfigurationFactoryServlet.class, appWebInfPath + "/" + SERVER_CONFIG_FILE);if (iss != null) {// FileProvider assumes responsibility for 'is':// do NOT call is.close().config = new FileProvider(iss);}if (config == null) {log.error(Messages.getMessage("servletEngineWebInfError03", ""));}/*** Couldn't get data OR file does exist.* If we have a path, then attempt to either open* the existing file, or create an (empty) file.*/if (config == null && realWebInfPath != null) {try {config = new FileProvider(realWebInfPath, configFile);} catch (ConfigurationException e) {log.error(Messages.getMessage("servletEngineWebInfError00"), e);}}/*** Fall back to config file packaged with AxisEngine*/if (config == null) {log.warn(Messages.getMessage("servletEngineWebInfWarn00"));try {InputStream is =ClassUtils.getResourceAsStream(AxisServer.class,SERVER_CONFIG_FILE);config = new FileProvider(is);} catch (Exception e) {log.error(Messages.getMessage("servletEngineWebInfError02"), e);}}return config;}}
7.启动类
@ServletComponentScan //扫描自定义的WebFilter和WebListener,否则无法扫描到
8. WEB-INF目录1
如果上面工厂的静态目录选择 WEB-INF
,请认真阅读这一小节,如果选择/
则可以跳过这一小节,静态目录选择 WEB-INF
有以下二种场景:
第一种:在main目录下,创建webapp/WEB-INF
目录
调整目录属性
8. WEB-INF目录2
第二种:在resources目录下面WEB-INF目录
9. /目录1
如果 6. 配置工厂选择的静态目录为/
,请认真阅读这一小节,有以下二种场景:
第一种:在resources下面存放server-config.wsdd
文件
9. /目录2
第二种:在webapp下面存放server-config.wsdd
文件
,若果选择在webapp下面存放server-config.wsdd
文件,请调整目录属性
10. wsdd
根据上面选择的场景,在指定的目录下面创建server-config.wsdd
文件,内容如下:
-
第一种:在webapp的WEB-INF目录下面
-
第二种:在webapp目录下面
-
第三种:在resources的WEB-INF目录下面
-
第四种:在resources目录下面
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/"xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"><handler type="java:org.apache.axis.handlers.http.URLMapper"name="URLMapper"/><!--要告诉别人的接口名--><service name="AxisServiceShell" provider="java:RPC"><!--这个是 实现类--><parameter name="className" value="com.gblfy.ws.service.impl.AxisServiceImpl"/><!--命名空间设置:默认:http://+ip:端口+urlPatterns+name(暴露的服务名)例如:http://localhost:8080/services/AxisServiceShell自定义格式:<namespace>自定义命名空间</namespace>例如:<namespace>com.gblfy.ws.service.impl</namespace>--><!--这是是暴露的方法名 比如可以值暴露一个--><parameter name="allowedMethods" value="sayHello"/><!--这是是暴露的方法名 也可以用* 表示暴露全部的public方法--><!--<parameter name="allowedMethods" value="*" />--></service><transport name="http"><requestFlow><handler type="URLMapper"/></requestFlow></transport></deployment>
11. 测试验证
http://localhost:8080/services/AxisServiceShell?wsdl
二、客户端
package com.gblfy.ws.client;import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import java.rmi.RemoteException;/*** Axis客户端** @author guobin* @date 2021-09-17*/
@Component
public class AxisClient {private final static Logger log = LoggerFactory.getLogger(AxisClient.class);public static void main(String[] args) throws Exception {String axisUrl = "http://localhost:8080/services/axisServiceShell?wsdl";String namespaceURI = "http://localhost:8080/services/axisServiceShell";// String method = "sayHello";String method = "sayHello2";String reqXml = "1";String reqXml2 = "2";//调用axis服务// AxisClient.axisSendMsg(axisUrl, namespaceURI, method, reqXml);AxisClient.axisSendMsg(axisUrl, namespaceURI, method, reqXml, reqXml2);}/*** @param url WebService地址* @param namespace 命名空间* @param method 方法* @param tReqXml 请求报文* @return* @throws Exception*/public static String axisSendMsg(String url, String namespace, String method, String tReqXml)throws Exception {Service service = new Service();Call call;String res = null;call = (Call) service.createCall();long forStrTime = 0L;if (StringUtils.isBlank(url)) {throw new RuntimeException("调用url地址等于空,请核实地址是否正确!");}if (StringUtils.isBlank(namespace)) {throw new RuntimeException("调用namespace等于空,请核实命名空间是否正确!");}if (StringUtils.isBlank(method)) {throw new RuntimeException("调用method等于空,请核实方法名是否正确!");}if (ObjectUtils.isEmpty(tReqXml)) {throw new RuntimeException("调发送报文等于空,请核实发送内容是否正确!");}call.setTargetEndpointAddress(new java.net.URL(url));//特殊处理部分 startString subUrl = url.substring(url.lastIndexOf("/"));log.info("转发路径标志 {}", subUrl.substring(1, subUrl.length()));//针对xxx需求添加单独逻辑判断if ("ws_fxhx_ws".equals(subUrl.substring(1, subUrl.length()))) {call.addParameter("xmlStr", org.apache.axis.Constants.XSD_STRING, ParameterMode.IN);call.setReturnType(org.apache.axis.Constants.XSD_STRING);}//特殊处理部分 endcall.setOperationName(new QName(namespace, method));// 这是要调用的方法log.info("开始转发请求报文");forStrTime = System.currentTimeMillis();log.info("开始转发时间: {}-毫秒", forStrTime);try {res = (String) call.invoke(new Object[]{tReqXml});} catch (RemoteException e) {e.printStackTrace();throw e;}long forEndTime = System.currentTimeMillis();log.info("转发结束时间: {}-毫秒", forEndTime);long endToStart = (long) (forEndTime - forStrTime);log.info("转发消耗的时间:: {}-毫秒", endToStart);log.info("响应报文: {}", res);return res;}public static String axisSendMsg(String url, String namespace, String method, String tReqXml, String tReqXml2)throws Exception {Service service = new Service();Call call;String res = null;call = (Call) service.createCall();long forStrTime = 0L;if (StringUtils.isBlank(url)) {throw new RuntimeException("调用url地址等于空,请核实地址是否正确!");}if (StringUtils.isBlank(namespace)) {throw new RuntimeException("调用namespace等于空,请核实命名空间是否正确!");}if (StringUtils.isBlank(method)) {throw new RuntimeException("调用method等于空,请核实方法名是否正确!");}if (ObjectUtils.isEmpty(tReqXml)) {throw new RuntimeException("调发送报文等于空,请核实发送内容是否正确!");}call.setTargetEndpointAddress(new java.net.URL(url));//特殊处理部分 startString subUrl = url.substring(url.lastIndexOf("/"));log.info("转发路径标志 {}", subUrl.substring(1, subUrl.length()));//针对xxx需求添加单独逻辑判断if ("ws_fxhx_ws".equals(subUrl.substring(1, subUrl.length()))) {call.addParameter("xmlStr", org.apache.axis.Constants.XSD_STRING, ParameterMode.IN);call.setReturnType(org.apache.axis.Constants.XSD_STRING);}//特殊处理部分 endcall.setOperationName(new QName(namespace, method));// 这是要调用的方法log.info("开始转发请求报文");forStrTime = System.currentTimeMillis();log.info("开始转发时间: {}-毫秒", forStrTime);try {res = (String) call.invoke(new Object[]{tReqXml, tReqXml2});} catch (RemoteException e) {e.printStackTrace();throw e;}long forEndTime = System.currentTimeMillis();log.info("转发结束时间: {}-毫秒", forEndTime);long endToStart = (long) (forEndTime - forStrTime);log.info("转发消耗的时间:: {}-毫秒", endToStart);log.info("响应报文: {}", res);return res;}
}
开源源码.
https://gitee.com/gblfy/unified-access-center