最近项目对接过程中,因为对方系统比较旧,我们和对方进行交互使用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错误。问题解决。