<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
public interface WebServices {
//发布地址
@WebMethod(exclude = true)
String getUrl();
}
@WebService(serviceName = "SceneInvestApiService",
targetNamespace = "http://service.investment.api.openapi.bi.com/")
@XmlSeeAlso(value = {RetireAgeQry.class,AssetPaymentQry.class, AssetInfoQry.class, ProductInfoQry.class,
PensionLevelDTO.class,InvestmentAdviceDto.class,InvestmentAdviceQry.class, ArrayList.class})
public interface SceneInvestApiService extends WebServices {
/**
*
* @param request 期望退休金试算请求实体
* @return 期望退休金试算返回实体
*/
@WebMethod
APIResult<ExpectAmountRes> expectAmountAnalyse(@WebParam(name = "request",targetNamespace = "http://service.investment.api.openapi.bi.com/", mode = WebParam.Mode.IN) ExpectAmountReq request);
/**
*
* @param request 养老资金缺口请求体
* @return 养老资金缺口试算返回实体
*/
@WebMethod
APIResult<PensionGapRes> pensionGapAnalyse(@WebParam(name = "request",targetNamespace = "http://service.investment.api.openapi.bi.com/",mode = WebParam.Mode.IN) PensionGapReq request);
}
@Slf4j
@Service("sceneInvestApiService")
@WebService(serviceName = "SceneInvestApiService",
targetNamespace = "http://service.investment.api.openapi.bi.com/",
endpointInterface = "com.bi.openapi.api.investment.service.SceneInvestApiService")
public class SceneInvestApiServiceImpl implements SceneInvestApiService {
@Override
public APIResult<ExpectAmountRes> expectAmountAnalyse(@WebParam(name = "request",targetNamespace = "http://service.investment.api.openapi.bi.com/", mode = WebParam.Mode.IN) ExpectAmountReq request) {
return APIResult.ok();
}
@Override
public APIResult<PensionGapRes> pensionGapAnalyse(@WebParam(name = "request",targetNamespace = "http://service.investment.api.openapi.bi.com/", mode = WebParam.Mode.IN) PensionGapReq request) {
return APIResult.ok();
}
}
/**
* @Author: K.Chan
* @Date: Created in 14:17 2022/7/12
* @Description: open-api自动发布接口启动类 需要发布的接口写到openapi模块中,实现{@link WebServices} 接口,重写地址即可。
* @attention: 发布时,入参和返回参数如果是内部类 不能是三层复杂参数。 内部类尽量放到外面引用 最好不要用 public static class className{}
*/
@Slf4j
@Component
public class AutoPublishBoot implements CommandLineRunner {
@Autowired
private SpringBus springbus;
@Autowired
private ApplicationContext applicationContext;
@Bean
public ServletRegistrationBean<CXFServlet> cxfServlet() {
//发布地址前缀
return new ServletRegistrationBean<>(new CXFServlet(), TOTAL_PATH);
}
@Override
public void run(String... args) throws Exception {
log.info("--------------自动发布开始--------");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info("--------------开始发布时间 :{}--------", sdf.format(new Timestamp(System.currentTimeMillis()).getTime()));
try {
//获取所有需要发布的bean
Map<String, WebServices> beansOfType = applicationContext.getBeansOfType(WebServices.class);
//用来标记注入endpoint的名称
int count = 1;
for (Map.Entry<String, WebServices> entry : beansOfType.entrySet()) {
//获取发布地址
String publishPath = entry.getValue().getUrl();
Endpoint endpoint = new EndpointImpl(springbus, entry.getValue());
log.info("[{}]:发布成功!",entry.getKey());
SpringUtil.registerBean(entry.getKey() + count, endpoint);
//发布接口
endpoint.publish(publishPath);
count++;
}
log.info("--------------自动发布结束--------");
log.info("--------------发布结束时间 :{}--------", sdf.format(new Timestamp(System.currentTimeMillis()).getTime()));
} catch (Exception e) {
throw new BIRuntimeException(String.format("webService动态发布失败![%s]", e.getMessage()));
}
}
}
上图中wealthservice是自动发布时的前缀。如果不写就是CXF自带的services/* ;srcb是你需要发布接口的实现类重写的地址;
通过http://ip:port/wealthservice/srcb?wsdl 在SoapUI中调用就可以看到发布的接口了
如果出现这种问题:那就是跨包问题导致类无法在webservice调用时透明。需要在接口类上加上注解然后里面加上报错信息中的类对象。
@WebService(serviceName = "SceneInvestApiService",
targetNamespace = "http://service.investment.api.openapi.bi.com/")
@XmlSeeAlso(value = {RetireAgeQry.class,AssetPaymentQry.class, AssetInfoQry.class, ProductInfoQry.class,
PensionLevelDTO.class,InvestmentAdviceDto.class,InvestmentAdviceQry.class, ArrayList.class})
public interface SceneInvestApiService extends WebServices {