访问webservice不带命名空间org.apache.cxf.interceptor.Fault: UnmarshallingError: 意外的元素 (uri:““, local:“arg0“)

 想要实现:客户端访问服务端时不带命名空间。

在百度上搜索,是给服务添加一个拦截器。代码如下:

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 java.io.*;

public class ServerNameSpaceInterceptor extends AbstractPhaseInterceptor<Message> {

    public ServerNameSpaceInterceptor()
    {
        super(Phase.RECEIVE);
    }


    @Override
    public void handleMessage(Message message) throws Fault {
        for (ServiceInfo si : message.getExchange().getService().getServiceInfos()) {
            si.setProperty("soap.force.doclit.bare",true); //这个就是忽略客户端不带命名空间的关键
        }
      
    }
}

程序访问报错:org.apache.cxf.interceptor.Fault: UnmarshallingError: 意外的元素 (uri:"", local:"arg0")

个人解决方案:在上述代码中的handleMessage方法中添加获取请求流,将请求流转成字符串,处理字符串中命名空间、参数、方法名相关信息,参考代码如下:

@Override
    public void handleMessage(Message message) throws Fault {
        for (ServiceInfo si : message.getExchange().getService().getServiceInfos()) {
            si.setProperty("soap.force.doclit.bare",true); //这个就是忽略客户端不带命名空间的关键
        }
        // 获取参数
        InputStream is = message.getContent(InputStream.class);

        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        StringBuffer reqParamsBuf = new StringBuffer();
        String line = "";

        while (true) {
            try {
                if (!((line = in.readLine()) != null)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            //post参数,json格式
            reqParamsBuf.append(line);
        }
        String str = reqParamsBuf.toString();
        if(str.indexOf("xmlns:ns1") < 0){//特殊处理,请求中没有命名空间,处理请求流
            //根据提供服务的方法修改请求流
            //处理方法的命名空间
            str = str.replace("><arg0"," xmlns:ns1=\"service.mvc.web.w.a.com\"><arg0");
            //处理方法的参数个数
            str = str.replace("arg0", "ns1:arg0");
            str = str.replace("arg1", "ns1:arg1");
            //处理方法名
            str = str.replace("execute", "ns1:execute");
        }
        message.setContent(InputStream.class, new ByteArrayInputStream(str.getBytes()));
    }

所有代码:

pom依赖:

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
            <version>3.4.4</version>
        </dependency>

代码结构:(package-info.java和接口同级目录)

webService的配置:webServiceConfig.java

package com.a.walk.web.mvc.config;

import com.a.walk.web.mvc.service.ServerNameSpaceInterceptor;
import com.a.walk.web.mvc.service.TestWebService;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;

@Configuration
public class WebServiceConfig {

    /**
     * 注入servlet  bean name不能dispatcherServlet 否则会覆盖dispatcherServlet
     *
     * @return
     */
    @Bean
    public ServletRegistrationBean cxfServlet() {
        return new ServletRegistrationBean(new CXFServlet(), "/webservice/*");//第二个参数:设置CXFServlet注册地址
    }

    @Bean(name = Bus.DEFAULT_BUS_ID)
    public SpringBus springBus() {
        return new SpringBus();
    }

    /**
     * 注册WebService接口到webservice服务
     *
     * @return
     */
    @Bean(name = "webServiceEndpoint")
    public Endpoint sweptPayEndpoint(TestWebService webService) {
        EndpointImpl endpoint = new EndpointImpl(springBus(), webService);
        endpoint.publish("/test");//设置接口注册地址
        endpoint.getInInterceptors().add(new ServerNameSpaceInterceptor());
        return endpoint;
    }
}

接口TestWebService.java:

package com.a.w.web.mvc.service;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(targetNamespace = "service.mvc.web.walk.ao.com",name = "testWebService")
public interface TestWebService {
    @WebResult(name = "execute", targetNamespace = "service.mvc.web.walk.a.com")
    @WebMethod
    String execute(String funcName,String value);
}

实现类TestWebServiceImpl.java:

package com.a.w.web.mvc.service.impl;

import com.a.w.web.mvc.service.TestWebService;
import org.springframework.stereotype.Service;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@Service
@WebService(targetNamespace = "service.mvc.web.w.a.com", serviceName = "Services",endpointInterface = "com.a.w.web.mvc.service.TestWebService")
public class TestWebServiceImpl implements TestWebService {
    @WebResult(name = "execute", targetNamespace = "service.mvc.web.w.as.com")
    @WebMethod
    public String execute(String funcName, String value) {
        return funcName;
    }
}

package-info.java:

@javax.xml.bind.annotation.XmlSchema(//namespace = "http://com.mypro.service",
        attributeFormDefault = XmlNsForm.QUALIFIED,
        elementFormDefault= XmlNsForm.QUALIFIED)
package com.a.w.web.mvc.service;

import javax.xml.bind.annotation.XmlNsForm;

拦截器ServerNameSpaceInterceptor.java:

package com.a.w.web.mvc.service;

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 java.io.*;

public class ServerNameSpaceInterceptor extends AbstractPhaseInterceptor<Message> {

    public ServerNameSpaceInterceptor()
    {
        super(Phase.RECEIVE);
    }


    @Override
    public void handleMessage(Message message) throws Fault {
        for (ServiceInfo si : message.getExchange().getService().getServiceInfos()) {
            si.setProperty("soap.force.doclit.bare",true); //这个就是忽略客户端不带命名空间的关键
        }
        // 获取参数
        InputStream is = message.getContent(InputStream.class);

        BufferedReader in = new BufferedReader(new InputStreamReader(is));
        StringBuffer reqParamsBuf = new StringBuffer();
        String line = "";

        while (true) {
            try {
                if (!((line = in.readLine()) != null)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            //post参数,json格式
            reqParamsBuf.append(line);
        }
        String str = reqParamsBuf.toString();
        if(str.indexOf("xmlns:ns1") < 0){//特殊处理,请求中没有命名空间,处理请求流
            //根据提供服务的方法修改请求流
            //处理方法的命名空间
            str = str.replace("><arg0"," xmlns:ns1=\"service.mvc.w.w.a.com\"><arg0");
            //处理方法的参数个数
            str = str.replace("arg0", "ns1:arg0");
            str = str.replace("arg1", "ns1:arg1");
            //处理方法名
            str = str.replace("execute", "ns1:execute");
        }
        message.setContent(InputStream.class, new ByteArrayInputStream(str.getBytes()));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值