Spring Boot-服务器无法识别HTTP标头SOAPAction的值
我想使用jaxb消费肥皂服务. jaxb生成的请求是
I want to consume soap service using jaxb. The generated request from jaxb is
<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>
但响应是标题中所述的肥皂异常.
But the response is a soap exception as stated in the title.
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)
以下是我的肥皂配置代码.源示例: https://howtodoinjava.com/spring-boot/spring-soap-client-webservicetemplate/
Below is my soap config code. Source example: 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;
}
请帮助我.谢谢.
您面临的问题是,位于 http://www.dneonline.com/calculator.asmx 要求使用SOAPAction
标头.而且由于您不提供服务,因此服务不知道如何路由请求.
The issue you're facing is that the web service at http://www.dneonline.com/calculator.asmx expects a SOAPAction
header. And since you're not providing one the service have no idea how to route the request.
您要遵循的教程不需要SOAPAction
标头即可进行路由.
The tutorial you're following doesn't require the SOAPAction
header to do the routing.
如果您查看如何在 WSDL ,您将在其中找到SOAPAction
标头的期望值.该服务提供的所有其他操作都相同.
If you take a look at how the Add
operation is specified in the the WSDL, you'll find the expected value of the SOAPAction
header there. Same for all the other operations the service provides.
<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
类与教程,您可以删除String url
作为callWebservice
方法的输入,因为已经通过SoapConnector
bean中的client.setDefaultUri("http://www.dneonline.com/calculator.asmx");
进行了设置.而是添加String soapAction
作为输入参数,为您提供以下内容
Assuming that your SoapConnector
class is identical to the one in the tutorial you can remove the String url
as input to the callWebservice
method since that is already set via the client.setDefaultUri("http://www.dneonline.com/calculator.asmx");
in the SoapConnector
bean. Instead, add String soapAction
as an input parameter, giving you the following
public class SOAPConnector extends WebServiceGatewaySupport {
public Object callWebService(Object request, String soapAction){
return getWebServiceTemplate().marshalSendAndReceive(url, new SoapActionCallback(soapAction));
}
}
然后,删除wsdlurl
作为soapConnector.callWebService
的输入(无论如何还是错误的),并为要使用的操作添加soapHeader
值,让您保持这一点
Then, remove the wsdlurl
as input to soapConnector.callWebService
(it was wrong anyway) and add the soapHeader
value for the operation you want to use instead, leaving you with this
@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
以外的其他操作,则必须调整此解决方案以使其通用.
Of course, if you want to use other operations besides Add
you'll have to tweak this solution to make it generic.