CXF忽略服务targetNamespace及对参数targetNamespace进行修改

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

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;
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值