序
WebService真是烦,为了不想写那些烦人的适配代码,使用了CXF 生成的客户端,但遇到要填自定义参数的时候,却无从入手。。。
经过几天的研究,各种尝试,解读原码。终于把问题解决,项目终于可以顺序进行下去了。。
遇到的问题
1:SAP 提供的webService 要求输入账号验证信息,如下图所示,但是使用生成的CXF客户端却没有一个属性可以配置。
问题解决
整个代码如下(已经脱敏):
实现的是一个定时把需要地接的数据,通过webservice 发送到目标系统。
package com.ly.mp.swcas.test;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.interceptor.security.JAASAuthenticationFeature;
import org.apache.cxf.interceptor.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceFeature;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Api(value = "SapSendTest")
@RestController
@RequestMapping(value = "/swcas/SapSendTest")
public class SapSendTest {
private static Logger log = LoggerFactory.getLogger(SapSendTest.class);
@Value("${tryMax.OldPartBackSync}")
private int tryMax;
@Autowired
ISendTaskBiz biz;
@Value("${webservice.wsdl}")
String wsdlPath;
SIWTYPOST _port;
public SIWTYPOST getPort() throws MalformedURLException {
if (_port != null) return _port;
URL wsdlURL = new URL(wsdlPath);
QName SERVICE_NAME = new QName("http://**.com/SWCAS/I080302WarrantyPost", "SI_WTY_POSTService");
SIWTYPOSTService ss = new SIWTYPOSTService(wsdlURL, SERVICE_NAME);
_port = ss.getHTTPPort();
((BindingProvider) _port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "userName");
((BindingProvider) _port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password");
return _port;
}
// 添加
@ApiOperation(value = "sap财务信息发送", notes = "sap财务信息发送")
@RequestMapping(path = "/syncSaleTest", method = RequestMethod.POST)
public RestResult syncSale() throws InvocationTargetException, IllegalAccessException, ParseException, MalformedURLException {
RestResult rs = new RestResult(1, "测试成功");
//查出七天内,状态为已完成,并且不存在发送任务的业务
Date dEnd = new Date();
Date dStart = DateUtils.addDay(dEnd, -7);
List<String> typeLst = new ArrayList<>();
typeLst.add("**信息");
typeLst.add("**信息");
List<SyncSendTask> lst = biz.getSendTask(typeLst, dStart, dEnd, tryMax);
if (CollectionUtils.isEmpty(lst)) {
System.out.println("没有需要发送的数据");
System.out.println("-------------end SapFinanceSendTask job--------------");
return rs;
}
SIWTYPOST _port = getPort();
for (SyncSendTask task : lst) {
StopWatch watch = new StopWatch();
task.setSendTime(new Date());
try {
watch = new StopWatch();
watch.start();
com.ly.mp.swcas.wsInvoker.DTWTYPOST data = new com.ly.mp.swcas.wsInvoker.DTWTYPOST();
DTWTYPOST.WTYPOST en = new DTWTYPOST.WTYPOST();
SendFinanceWrap wrap = new Gson().fromJson(task.getSendContent(), SendFinanceWrap.class);
BeanUtils.copyProperties(wrap,en);
data.getWTYPOST().add(en);
com.ly.mp.swcas.wsInvoker.DTWTYPOSTRes wsResult = _port.siWTYPOST(data);
if (wsResult != null && !CollectionUtils.isEmpty(wsResult.getWTYPOST())) {
task.setResponseContent(new Gson().toJson(wsResult));
DTWTYPOSTRes.WTYPOST it = wsResult.getWTYPOST().get(0);
if ("S".equals(it.getStats())) {
task.setSendStatus("1");
} else {
task.setSendStatus("2");
}
}
} catch (Exception ex) {
ex.printStackTrace();
StringWriter stringWriter = new StringWriter();
ex.printStackTrace(new PrintWriter(stringWriter));
task.setResponseContent(stringWriter.toString());
}
watch.stop();
task.setSendCost(BigDecimalUtils.val(watch.getTotalTimeSeconds()));
task.setLastUpdatedDate(new Date());
task.setTryAcc(task.getTryAcc() + 1);
biz.updateTask(task);
}
System.out.println("-------------end SapFinanceSendTask job--------------");
return rs;
}
}
关键:把Port转换成BindingProvider,然后给port赋值,如下:
public SIWTYPOST getPort() throws MalformedURLException {
if (_port != null) return _port;
URL wsdlURL = new URL(wsdlPath);
QName SERVICE_NAME = new QName("http://**.com/SWCAS/I080302WarrantyPost", "SI_WTY_POSTService");
SIWTYPOSTService ss = new SIWTYPOSTService(wsdlURL, SERVICE_NAME);
_port = ss.getHTTPPort();
((BindingProvider) _port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "userName");
((BindingProvider) _port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password");
return _port;
}
PS:原代码主要关注初始化,与及getHttpPort两个方法。说实话,原代码真的很臭,希望不要再见。。