Accessing webservice without namespace org.apache.cxf.interceptor.Fault: UnmarshallingError: Unexpected element (uri: “”, local: “arg0”)

What you want to achieve: The client does not have a namespace when accessing the server.

Searching on Baidu adds an interceptor to the service. code show as below:

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); //This is the key to ignoring the fact that the client does not have a namespace
        }
      
    }
}

Program access error: org.apache.cxf.interceptor.Fault: UnmarshallingError: Unexpected element (uri:””, local:”arg0″)

Personal solution: Add the request stream to the handleMessage method in the above code, convert the request stream into a string, and process the information related to the namespace, parameters, and method names in the string. The reference code is as follows:

@Override
    public void handleMessage(Message message) throws Fault {
        for (ServiceInfo si : message.getExchange().getService().getServiceInfos()) {
            si.setProperty("soap.force.doclit.bare",true); //This is the key to ignoring the fact that the client does not have a namespace
        }
        // Get parameters
        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 parameters, json format
            reqParamsBuf.append(line);
        }
        String str = reqParamsBuf.toString();
        if(str.indexOf("xmlns:ns1") < 0){//Special processing, there is no namespace in the request, process the request flow
            //Modify the request flow according to the method of providing services
            //Namespace of processing method
            str = str.replace("><arg0"," xmlns:ns1="service.mvc.web.w.a.com"><arg0");
            //The number of parameters of the processing method
            str = str.replace("arg0", "ns1:arg0");
            str = str.replace("arg1", "ns1:arg1");
            //Processing method name
            str = str.replace("execute", "ns1:execute");
        }
        message.setContent(InputStream.class, new ByteArrayInputStream(str.getBytes()));
    }

All codes:

pom dependencies:

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

Code structure: (package-info.java and interface directory)

Configuration of 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 {

    /**
     * The servlet bean name cannot be injected into dispatcherServlet, otherwise dispatcherServlet will be overwritten.
     *
     * @return
     */
    @Bean
    public ServletRegistrationBean cxfServlet() {
        return new ServletRegistrationBean(new CXFServlet(), "/webservice/*");//The second parameter: Set the CXFServlet registration address
    }

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

    /**
     * Register the WebService interface to the webservice service
     *
     * @return
     */
    @Bean(name = "webServiceEndpoint")
    public Endpoint sweptPayEndpoint(TestWebService webService) {
        EndpointImpl endpoint = new EndpointImpl(springBus(), webService);
        endpoint.publish("/test");//Set the interface registration address
        endpoint.getInInterceptors().add(new ServerNameSpaceInterceptor());
        return endpoint;
    }
}

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

Implement class 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;

Interceptor 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); //This is the key to ignoring the fact that the client does not have a namespace
        }
        // Get parameters
        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 parameters, json format
            reqParamsBuf.append(line);
        }
        String str = reqParamsBuf.toString();
        if(str.indexOf("xmlns:ns1") < 0){//Special processing, there is no namespace in the request, process the request flow
            //Modify the request flow according to the method of providing services
            //Namespace of processing method
            str = str.replace("><arg0"," xmlns:ns1="service.mvc.w.w.a.com"><arg0");
            //The number of parameters of the processing method
            str = str.replace("arg0", "ns1:arg0");
            str = str.replace("arg1", "ns1:arg1");
            //Processing method name
            str = str.replace("execute", "ns1:execute");
        }
        message.setContent(InputStream.class, new ByteArrayInputStream(str.getBytes()));
    }
}

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. Java Skill TreeHomepageOverview 133681 people are learning the system