最近一直開發一個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