CXF忽略服务targetNamespace及对参数targetNamespace进行修改
环境
1.**cxf版本:3.3.5**
2.**SpringBoot**
服务targetNamespace及参数targetNamespace
1.服务targetNamespace
注解@WebService的属性
2.参数targetNamespace
注解@WebParam的属性
新增拦截器
package com.csdn.net.config.webservice;
import com.csdn.net.common.utils.StringUtils;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.service.model.ServiceInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class IgnoreTargetNamespaceInInterceptor extends AbstractPhaseInterceptor<Message> {
private static Logger log = LoggerFactory.getLogger(IgnoreTargetNamespaceInInterceptor.class);
public IgnoreTargetNamespaceInInterceptor() {
super(Phase.PRE_STREAM);
}
@Override
public void handleMessage(Message message) throws Fault {
// 因为产品升级,将所有的targetNamespace进行统一,故之前对接的接口现在就不能用了,
// 最好是能忽略targetNamespace,但是参数targetNamespace不支持配置忽略(没找到),故采用替换的方式
// 当然,如果有其他需求也可以通过正则匹配进行查找、替换
InputStream inputStream = message.getContent(InputStream.class);
if (null != inputStream) {
try {
String content = IOUtils.toString(inputStream);
if (!StringUtils.isBlank(content)) {
content = content.replaceAll("http://service.test.csdn.net", "http://service.csdn.net");
InputStream ism = new ByteArrayInputStream(content.getBytes());
message.setContent(InputStream.class, ism);
}
} catch (IOException e) {
log.error("解析ws报文失败", e);
} finally {
}
}
// 这里是对服务targetNamespace进行忽略的配置
for (ServiceInfo si : message.getExchange().getService().getServiceInfos()) {
//这个就是忽略客户端不带命名空间的关键,可查看类DocLiteralInInterceptor的handleMessage方法
si.setProperty("soap.force.doclit.bare", Boolean.TRUE);
}
}
}
配置拦截器
package com.csdn.net.config.webservice;
import com.csdn.net.core.web.SpringContextHolder;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.interceptor.FaultOutInterceptor;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.message.Message;
import org.apache.cxf.transport.servlet.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Configuration
public class WebServiceConfig {
private final static Logger log = LoggerFactory.getLogger(WebServiceConfig.class);
@Bean
@ConditionalOnMissingBean(ServletRegistrationBean.class)
public ServletRegistrationBean disServlet() {
// 这里增加了WebService接口默认路径前缀,方便对WebService进行权限管理
return new ServletRegistrationBean(new CXFServlet(), "/ws/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
@ConditionalOnMissingBean(SpringBus.class)
public SpringBus springBus() {
SpringBus springBus = new SpringBus();
return springBus;
}
@Bean
@ConditionalOnMissingBean(FaultOutInterceptor.class)
public FaultOutInterceptor faultOutInterceptor() {
return new FaultOutInterceptor();
}
/**
* 扫描所有WebService注解的类,然后进行发布
*/
@Bean("endpoints")
@ConditionalOnMissingBean(name = "endpoints")
public Map<String, Endpoint> endpoint() {
String[] beanNames =
SpringContextHolder.getApplicationContext()
.getBeanNamesForAnnotation(WebService.class);
Map<String, Endpoint> endpoints = new HashMap<>(beanNames.length);
EndpointImpl endpoint = null;
String[] addresses;
for (int i = 0; i < beanNames.length; i++) {
Object object = SpringContextHolder.getBean(beanNames[i]);
// 获取服务发布的路径,通过注解实现
addresses = this.getWsAddress(object);
if (addresses != null) {
for (int i1 = 0; i1 < addresses.length; i1++) {
endpoint = new EndpointImpl(springBus(), object);
if (!addresses[i1].startsWith("/")) {
endpoint.publish("/" + addresses[i1]);
} else {
endpoint.publish(addresses[i1]);
}
// 设置忽略targetNamespace拦截器
List<Interceptor<? extends Message>> inInterceptors = endpoint.getInInterceptors();
inInterceptors.add(new IgnoreTargetNamespaceInInterceptor());
endpoint.setInInterceptors(inInterceptors);
endpoints.put(addresses[i1], endpoint);
}
}
}
log.info("Publish Service {}", endpoints.keySet());
return endpoints;
}
private String[] getWsAddress(Object object) {
// 这里我写了个注解,在创建WebService的类文件上(与@WebService注解同位置)增加WsAddress注解,通过该注解配置服务的发布路径
WsAddress wsAddress = object.getClass().getAnnotation(WsAddress.class);
if (null != wsAddress) {
return wsAddress.value();
} else {
return null;
}
}
}

本文介绍如何在CXF 3.3.5 SpringBoot环境下,忽略服务targetNamespace并自定义参数targetNamespace拦截,同时配置了新的拦截器来处理ws报文,包括替换targetNamespace和针对WebService接口的发布路径管理。

7731

被折叠的 条评论
为什么被折叠?



