最近项目对接过程中,因为对方系统比较旧,我们和对方进行交互使用webservice方式进行,对方给出相关文档,
接口地址:http://ip:port/abc/def/xxxService?wsdl
接口名称:methodA
1-springboot配合CXF使用
由于接口的ip是内网地址,我们业务服务器出去,我们必须中转到一台可以打通内网ip的机器A上才能请求。首先我们使用内网穿透工具(ngfork),在A上部署一个中转应用。
大概流程如下:
Java核心代码如下:
pom引入依赖
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.1.RELEASE</version><relativePath/></parent><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.18</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8</version></dependency><!-- https://mvnrepository.com/artifact/com.sun.xml.ws/jaxws-ri --><dependency><groupId>com.sun.xml.ws</groupId><artifactId>jaxws-ri</artifactId><version>2.3.3</version><type>pom</type></dependency><!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.2.0.Final</version></dependency><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web-services --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web-services</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-spring-boot-starter-jaxws --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-spring-boot-starter-jaxws</artifactId><version>3.4.3</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.cxf/cxf-rt-transports-http --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-transports-http</artifactId><version>3.4.3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.30</version></dependency></dependencies>
核心java代码如下:
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("接口地址");
Object[] objects = client.invoke("接口名称", reqStr);
objects就是对方返回的结果。
这种情况直接使用ip,完全没有问题,如下使用域名会出现如下错误:
org.apache.cxf.interceptor.Fault: Response was of unexpected text/html ContentType. Incoming portion of HTML stream: <html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.22.1</center>
</body>
</html>
2-使用AXIS请求
上面使用frps进行时,使用域名会出现以上错误,我们更换一种请求方式,就可以获取到结果。方式二直接需要一台公网服务器部署frps,需要域名;然后在中转机上不是frpc客户端,配置相关内容,不需要部署一个服务,直接域名穿透过去。
pom依赖:
<dependency><groupId>org.apache.axis</groupId><artifactId>axis</artifactId><version>1.4</version></dependency><dependency><groupId>org.apache.axis</groupId><artifactId>axis-jaxrpc</artifactId><version>1.4</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>commons-discovery</groupId><artifactId>commons-discovery</artifactId><version>0.5</version></dependency><dependency><groupId>wsdl4j</groupId><artifactId>wsdl4j</artifactId><version>1.5.2</version></dependency>
核心java代码:
//服务地址String url = "https://xxx.com/abc/def/xxxService?wsdl";//命名空间String namespaceURI = XMLConstants.NULL_NS_URI;//方法名String method = "yourMethod";try {Service service = new Service();Call call = (Call) service.createCall();call.setTargetEndpointAddress(url);//设置要调用的方法call.setOperationName(new QName(namespaceURI, method));//设置要返回的数据类型call.setReturnType(new QName(namespaceURI, method), String.class);call.setUseSOAPAction(true);call.setSOAPActionURI(namespaceURI + method);//设置入参call.addParameter(new QName(namespaceURI, "params"), Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);//调用方法并传递参数String resultStr = (String) call.invoke(new Object[]{"{\"name\":\"zhangsan\",\"pwd\":\"abc123456\"}"});System.out.println("服务调用结果:" + resultStr);} catch (Exception e) {e.printStackTrace();}
使用方式二就没有出现方式一的301错误。问题解决。