- 环境
- 服务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配置拦截器{ 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("endpoints")
@ConditionalOnMissingBean(name = "endpoints")
public Map endpoint() {
String[] beanNames =
SpringContextHolder.getApplicationContext()
.getBeanNamesForAnnotation(WebService.class);
Map 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> 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;
}
}
}



