最近一直开发一个webservice的接口,因为是第一次接触webservice,并且仍是在结合spingBoot和CXF框架的状况下开发的,因此刚开始有点懵逼,遇到了各类问题。可是,终究仍是完成了,以此分享一下个人开发过程。html
根据项目使用的构建工具,添加相应的jar包,由于个人项目用到是gradle,添加依赖以下:web
compile group: 'org.apache.cxf', name: 'cxf', version: '2.7.6'
复制代码
接口目录结构以下: spring
@XmlRootElement(name = "ReceiveDisposalPlanMassageRequest")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ReceiveDisposalPlanMassageRequest", propOrder = {
"year",
"disposalNumber",
"planName",
"planCode",
"orgId",
"orgName",
"estimateAmount",
"baseAmount",
"fillUserId",
"fillUserName",
"remark",
"billType",
"dataAreaName",
"creatorId",
"creator",
"auctionMaterialList",
"disposalPlanAttachmentList"
})
public class ReceiveDisposalPlanMassageRequest {
@XmlElement(required = true)
private String year;//年度
@XmlElement(required = true)
private String disposalNumber;//处置批次号
@XmlElement(required = true)
private String planName;//处置计划名称
@XmlElement(required = true)
private String planCode;//处置计划编号
@XmlElement(required = true)
private String orgId;//物资所属单位ID
@XmlElement(required = true)
private String orgName;//物资所属单位名称
@XmlElement(required = true)
private Double estimateAmount;//预估金额
@XmlElement(required = true)
private Double baseAmount;//底价
@XmlElement(required = true)
private String fillUserId;//填报人ID
@XmlElement(required = true)
private String fillUserName;//填报人
@XmlElement(required = false)
private String remark;//备注
@XmlElement(required = true)
private String billType;//登记类型
@XmlElement(required = true)
private String dataAreaName;//产权持有单位
@XmlElement(required = true)
private String creatorId;//制单人ID
@XmlElement(required = true)
private String creator;//制单人
@XmlElement(required = true)
private List<AuctionMaterial> auctionMaterialList;//物资明细列表
@XmlElement(required = true)
private List<SyncAttachmentVO> disposalPlanAttachmentList;//附件列表
//省略set,get方法
}
复制代码
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SoaResponse", propOrder = {
"status",
"message"
})
public class SoaResponse {
@XmlElement(nillable = true)
protected int status; //同步结果
@XmlElement(nillable = true)
protected String message; //返回信息
//省略set,get方法
}
复制代码
关于@XmlAccessorType,@XmlType,@XmlElement相关注解的用处,能够参考如下教程: JABX 教程apache
@WebService(name = "ReceiveDisposalPlanMassageSer",targetNamespace = Constants_soa.NAME_SPACE)
public interface ReceiveDisposalPlanMassageFacade {
@WSDLDocumentation("接收处置计划信息")
@WebResult(name = "receiveDisposalPlanMassageResponse", targetNamespace = Constants_soa.NAME_SPACE)
@RequestWrapper(localName = "request")
@ResponseWrapper(localName = "response")
@WebMethod()
public SoaResponse receiveDisposalPlanMassage(@WebParam(name = "receiveDisposalPlanMassageRequest", targetNamespace = Constants_soa.NAME_SPACE)ReceiveDisposalPlanMassageRequest receiveDisposalPlanMassageRequest) throws SoaFault;
}
复制代码
@WebService(name = "ReceiveDisposalPlanMassageSer",targetNamespace = Constants_soa.NAME_SPACE)
@Component("ReceiveDisposalPlanMassageSer")
public class ReceiveDisposalPlanMassageFacadeImpl implements ReceiveDisposalPlanMassageFacade {
private static final Logger logger = LoggerFactory.getLogger(ReceiveDisposalPlanMassageFacadeImpl.class);
@Autowired
private DisposalPlanFacade disposalPlanFacade;
@Autowired
private AuctionMaterialFacade auctionMaterialFacade;
@Autowired
private AttachmentFacade attachmentFacade;
@Override
public SoaResponse receiveDisposalPlanMassage(ReceiveDisposalPlanMassageRequest request)throws SoaFault {
SoaResponse response = new SoaResponse();
try {
if (request != null) {
//此处省略业务代码
}
response.setStatus(0);
response.setMessage("ok");
}catch (Exception e){
logger.error("服务器发生未知异常!" + e.getMessage());
response.setStatus(-1);
response.setMessage(e.getMessage());
}
return response;
}
}
复制代码
@Configuration
public class CxfConfig {
private static final Logger logger = LoggerFactory.getLogger(CxfConfig.class);
private String scanPath = "xxx";//此处是接口所在的包路径
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
SpringBus bus = new SpringBus();
// 日志打印
bus.getInInterceptors().add(new LoggingInInterceptor());
bus.getOutInterceptors().add(new LoggingOutInterceptor());
return bus;
}
/**
* 发布服务名称
* 访问该路径能够查看发布的服务
* @return
*/
@Bean
public ServletRegistrationBean disServlet() {
return new ServletRegistrationBean(new CXFServlet(), "/webservice/*");
}
@Bean
@ConditionalOnMissingBean
public WadlGenerator wadlGenerator() {
WadlGenerator wadlGenerator = new WadlGenerator();
return wadlGenerator;
}
@Bean
@ConditionalOnMissingBean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
@Bean
@ConditionalOnMissingBean
public JacksonJsonProvider jsonProvider(ObjectMapper objectMapper) {
JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(objectMapper);
return provider;
}
@Bean
@ConditionalOnMissingBean
public JAXBElementProvider xmlProvider() {
return new JAXBElementProvider();
}
/*
* 使用cxf发布soap服务
* */
@Bean
public List<Endpoint> endpoints(ApplicationContext ctx) {
ArrayList<Endpoint> endpoints = new ArrayList<Endpoint>();
try {
//从spring上下文里获取含有WebService注解的对象
List<Object> serviceBeans = new ArrayList<Object>(ctx.getBeansWithAnnotation(WebService.class).values());
if (ListUtils.isEmpty(serviceBeans)) {
logger.info("serviceBeans is empty");
return endpoints;
}
EndpointImpl endpoint = null;
//遍历serviceBeans 发布soap接口
for (Object webService : serviceBeans) {
String webServiceClassName = webService.getClass().getName();
boolean startsWith = webServiceClassName.startsWith(scanPath);
logger.info("SOAP endpoints:\nwebServiceClassName:{}\nscanPath:{}\nwebServiceClassName.startsWith(scanPath):{}",webServiceClassName,scanPath,startsWith);
if (startsWith) {
WebService annotation = AnnotationUtils.findAnnotation(webService.getClass(),WebService.class);
if (annotation == null){
continue;
}
String name = annotation.name();
if (StringUtil.isEmpty(name)) {
name = annotation.serviceName();
}
if (StringUtil.isEmpty(name)) {
logger.error("webservice " + webService.getClass().getSimpleName() + " 实现类没有 @WebService(name='xxx') 的注解");
continue;
}
endpoint = new EndpointImpl(springBus(), webService);
endpoint.publish("/" + name);
endpoints.add(endpoint);
}
}
} catch (Exception e) {
logger.error("cxf soap error……");
logger.error(e.getMessage(), e);
}
return endpoints;
}
/*
* 发布rest
* */
@Bean
@ConditionalOnMissingBean
public Server jaxRsServer(ApplicationContext ctx) {
try {
List<Object> serviceBeans = new ArrayList<Object>(ctx.getBeansWithAnnotation(Path.class).values());
if(ListUtils.isEmpty(serviceBeans)){
logger.info("found serviceBeans is empty in spring application context.");
return null;
}
logger.info("serviceBeans:{}",serviceBeans.size());
Iterator<Object> iterator = serviceBeans.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
String serviceBeanClassName = next.getClass().getName();
boolean startsWith = serviceBeanClassName.startsWith(scanPath);
logger.info("REST endpoints:\nserviceBeanClassName:{}\nscanPath:{}\nwebServiceClassName.startsWith(scanPath):{}",serviceBeanClassName,scanPath,startsWith);
if (!startsWith) {
iterator.remove();
}
}
if (ListUtils.isEmpty(serviceBeans)){
logger.info("found serviceBeans is empty in {}.",scanPath);
return null;
}
logger.info("serviceBeans:{}",serviceBeans.size());
List<Object> providers = new ArrayList<Object>(ctx.getBeansWithAnnotation(Provider.class).values());
providers.add(wadlGenerator());
Map<Object, Object> extensionMappings = new HashMap<>();
extensionMappings.put("xml", "application/xml");
extensionMappings.put("json", "application/json");
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
factory.setBus(springBus());
factory.setAddress("/rest");
factory.setServiceBeans(serviceBeans);
factory.setProviders(providers);
factory.setExtensionMappings(extensionMappings);
Server server = factory.create();
return server;
} catch (Exception e) {
logger.error("cxf rest error……");
logger.error(e.getMessage(), e);
return null;
}
}
}
复制代码
代码已经完了,接下来就是启动项目,访问服务。个人服务发布成功以后以下所示:json
以上内容就是我开发webservice接口的所有过程,但愿对你们有所帮助,谢谢!bash