话不多说,直接上代码:
WebService 配置类
@Configuration
public class WebServiceConfig{
@Value("${WebService.url.publish}")//发布的webservice地址
String webServiceUrl;
@Bean
public ServletRegistrationBean disServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFServlet(), "/SWLH/*");//地址后面的url
return servletRegistrationBean;
}
@Bean(name = Bus.DEFAULT_BUS_ID)//spring bus
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), new SWLHOpenServiceWeb());//发布的类
endpoint.getInInterceptors().add(new ArtifactInInterceptor());//前置拦截器
endpoint.getOutInterceptors().add(new ArtifactOutInterceptor());//出口拦截器
endpoint.publish(webServiceUrl);
System.out.println("Webservice Started.");
return endpoint;
}
}
业务逻辑处理类
@Service
public class SWLHOpenService {
public static final Logger logger = LoggerFactory.getLogger(SWLHOpenService.class);
/**
* @param req
*/
public Response execute(Request req) {
Response southResponse = Response.builder()
.orderid(req.getOrderid())
.state(0)
.strError(SerConstants.OK)
.retTime(SerConstants.ymdhmsWithFormat.format(LocalDateTime.now()))
.build();
try {
InitConfig.getInstance().getGetPool().execute(new SWLHOpenServiceThread(req,southResponse));
}catch (Exception e){
logger.error("execute thread exception ",e);
}
return southResponse;
}
}
因为此处需要异步返回,所以使用线程池去做实际业务处理。
WebService发布类
@WebService(targetNamespace = "urn:finishOrder")
public class SWLHOpenServiceWeb {
public static final Logger logger = LoggerFactory.getLogger(SWLHOpenServiceWeb.class);
@WebMethod(operationName="FinishOrder")
public Response finishOrder(
@WebParam(name = "orderid") String orderid
,@WebParam(name = "state") int state
,@WebParam(name = "remark3") String remark3
,@WebParam(name = "Backtime") String Backtime) {
SWLHOpenService SWLHOpenService = (SWLHOpenService)MainApplication.applicationContext.getBean("SWLHOpenService");
Request req = Request.builder().orderid(orderid).state(state).remark3(remark3).build();
Response str = SWLHOpenService.execute(req);
return str;
}
}
注解里面还有很多的配置,如图:
可根据需要自行配置,
MainApplication是springboot的启动类
重点来了,前置拦截器类:
@Slf4j
public class ArtifactInInterceptor extends AbstractPhaseInterceptor<Message> {
/**
* <p>Description: </p>
*/
public ArtifactInInterceptor() {
super(Phase.RECEIVE);//此拦截器根据不同的phase进行拦截,也可以实现不同的效果
}
/* (non-Javadoc)
* <p>Title: handleMessage</p>
* <p>Description: </p>
* @param message
* @throws Fault
* @see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message.Message)
*/
@Override
public void handleMessage(Message message) throws Fault {
InputStream is = message.getContent(InputStream.class);
if (is != null) {
try {
String str = IOUtils.toString(is,"UTF-8");//此处可以更换字符集,这样就可以接收不同字符集的请求。
// 原请求报文
log.info("====> 接收到报文\r\n" + str);
InputStream ism = new ByteArrayInputStream(str.getBytes("UTF-8"));
message.setContent(InputStream.class, ism);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
前置拦截器,可以输出原报文,打印日志,也可以更改接收到的报文体,也可以将接收到的报文转换字符集,功能多多,可根据需要自行处理。
后置拦截器类:
public class ArtifactOutInterceptor extends AbstractPhaseInterceptor<Message> {
private static final Logger log = LoggerFactory.getLogger(ArtifactOutInterceptor.class);
public ArtifactOutInterceptor() {
//这儿使用pre_stream,意思为在流关闭之前
super(Phase.PRE_STREAM);
}
@Override
public void handleMessage(Message message) {
try {
OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);
message.getInterceptorChain().doIntercept(message);
CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
InputStream in = csnew.getInputStream();
String xml = IOUtils.toString(in);
xml=xml.replace("<return>", "").replace("</return>", "");//替换成你需要的格式
//这里对xml做处理,处理完后同理,写回流中
IOUtils.copy(new ByteArrayInputStream(xml.getBytes("UTF-8")), os);
cs.close();
os.flush();
message.setContent(OutputStream.class, os);
} catch (Exception e) {
log.error("Error when split original inputStream. CausedBy : " + "\n" + e);
}
}
private class CachedStream extends CachedOutputStream {
public CachedStream() {
super();
}
@Override
protected void doFlush() throws IOException {
currentStream.flush();
}
protected void doClo4se() throws IOException {
}
@Override
protected void onWrite() throws IOException {
}
}
}
同样,后置拦截器也可以截取发送的报文进行报文转换,字符集转换,等等