Web Services Spring Boot -服务器无法识别HTTP标头SOAPAction的值

kx1ctssn  于 2022-11-15  发布在  Spring
关注(0)|答案(2)|浏览(159)

我想使用jaxb使用soap服务。

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
      <ns2:Add xmlns:ns2="http://tempuri.org/">
         <ns2:intA>10</ns2:intA><ns2:intB>20</ns2:intB>
      </ns2:Add>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

但回应是一个肥皂例外,正如标题所说。

Caused by: org.springframework.ws.soap.client.SoapFaultClientException: System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: .
   at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
   at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
   at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
   at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)

下面是我的soap配置代码。源代码示例:https://howtodoinjava.com/spring-boot/spring-soap-client-webservicetemplate/

public class ConsumeSoapApplication {
            public static String wsdlurl = "http://www.dneonline.com/calculator.asmx?wsdl";
            public static void main(String[] args) {
                try {
                    JAXBContext.newInstance(com.dxc.service.soap.service.calc.ObjectFactory.class.getPackage().getName(),
                            com.dxc.service.soap.service.calc.ObjectFactory.class.getClassLoader());
                } catch (JAXBException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                SpringApplication.run(ConsumeSoapApplication.class, args);
            }

            @Bean
            CommandLineRunner lookup(SoapConnector soapConnector) {
                return args -> {
                    Integer a = 10;
                    Integer b = 20;
                    if(args.length>0){
                        a = Integer.parseInt(args[0]);
                        b = Integer.parseInt(args[1]);
                    }

                    Add add = new Add();
                    add.setIntA(a);
                    add.setIntB(b);
                    AddResponse addRes = (AddResponse) soapConnector.callWebService(wsdlurl, add);
                    System.out.println("Got Response As below ========= : ");
                    System.out.println("Added result : "+addRes.getAddResult());
                };
            }
        }

@Configuration
public class SoapConfig {    
    @Bean
        public Jaxb2Marshaller marshaller() {
            try {
                JAXBContext jb = JAXBContext.newInstance(com.dxc.service.soap.service.calc.ObjectFactory.class.getPackage().getName(),
                        com.dxc.service.soap.service.calc.ObjectFactory.class.getClassLoader());
                //Jaxb2Marshaller marshaller = (Jaxb2Marshaller) jb.createMarshaller();
                Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
                marshaller.setPackagesToScan("com.dxc.service.soap.service.calc");
                //marshaller.setContextPath("com.dxc.service.soap.calc");
                return marshaller;
            } catch (JAXBException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }   
            return null;
        }

        @Bean
        public SoapConnector soapConnector(Jaxb2Marshaller marshaller) {
            SoapConnector client = new SoapConnector();
            client.setDefaultUri("http://www.dneonline.com/calculator.asmx");
            client.setMarshaller(marshaller);
            client.setUnmarshaller(marshaller);
            return client;
        }

请帮帮我。谢谢。

3zwjbxry

3zwjbxry1#

您所面临的问题是http://www.dneonline.com/calculator.asmx的web服务需要一个SOAPAction头,而由于您没有提供一个头,因此服务不知道如何路由请求。
您正在学习的教程不需要使用SOAPAction头来执行路由。
如果你看一下Add操作是如何在WSDL中指定的,你会在那里找到SOAPAction头的期望值。

<wsdl:operation name="Add">                                                           
  <soap:operation soapAction="http://tempuri.org/Add" style="document" />             
  <wsdl:input>                                                                        
    <soap:body use="literal" />                                                       
  </wsdl:input>                                                                       
  <wsdl:output>                                                                       
    <soap:body use="literal" />                                                       
  </wsdl:output>                                                                      
</wsdl:operation>

假设您的SoapConnector类与the tutorial中的类相同,您可以删除作为callWebservice方法输入的String url,因为它已经通过SoapConnector bean中的client.setDefaultUri("http://www.dneonline.com/calculator.asmx");进行了设置。

public class SOAPConnector extends WebServiceGatewaySupport {

    public Object callWebService(Object request, String soapAction){
        return getWebServiceTemplate().marshalSendAndReceive(url, new SoapActionCallback(soapAction));
    }
}

然后,删除作为soapConnector.callWebService的输入的wsdlurl(无论如何它都是错误的),并为要使用的运算添加soapHeader值,剩下的就是

@Bean
CommandLineRunner lookup(SoapConnector soapConnector) {
    return args -> {
        Integer a = 10;
        Integer b = 20;
        if(args.length>0){
            a = Integer.parseInt(args[0]);
            b = Integer.parseInt(args[1]);
        }

        Add add = new Add();
        add.setIntA(a);
        add.setIntB(b);
        AddResponse addRes = (AddResponse) soapConnector.callWebService(add, "http://tempuri.org/Add");
        System.out.println("Got Response As below ========= : ");
        System.out.println("Added result : "+addRes.getAddResult());
    };
}

当然,如果您希望使用Add之外的其他操作,则必须调整此解决方案以使其通用。

z2acfund

z2acfund2#

@Misantorp回答是调用SOAP Web服务的解决方案,其中必须传递操作。我使用了相同的建议,可以调用w3School的温度转换器。
[链接] https://github.com/suhelm/SPRINGBOOT/tree/main/SOAP_temparature_converter

相关问题