Java SoapFaultClientException:找不到标头
一个SOAPWeb服务,它接受以下格式的请求-Java SoapFaultClientException:找不到标头,java,spring,spring-boot,jaxb,maven-jaxb2-plugin,Java,Spring,Spring Boot,Jaxb,Maven Jaxb2 Plugin,一个SOAPWeb服务,它接受以下格式的请求- <?xml version = "1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" xmlns:ns="http://...." xmlns:ns1="http://...." xmlns:ns2
<?xml version = "1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
xmlns:ns="http://...." xmlns:ns1="http://...." xmlns:ns2="http://...."
xmlns:ns3="http://....">
<SOAP-ENV:Header>
<ns:EMContext>
<messageId>1</messageId>
<refToMessageId>ABC123</refToMessageId>
<session>
<sessionId>3</sessionId>
<sessionSequenceNumber>2021-02-24T00:00:00.000+5:00</sessionSequenceNumber>
</session>
<invokerRef>CRS</invokerRef>
</ns:EMContext>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:getEmployee>
<ns:empId>111</ns:empId>
</ns1:getEmployee>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
配置-
@Configuration
public class EmpConfig {
@Bean
public Jaxb2Marshaller marshaller(){
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath("com.crsardar.java.soap.client.request");
return jaxb2Marshaller;
}
@Bean
public MyClient getClient(Jaxb2Marshaller jaxb2Marshaller){
MyClient myClient = new MyClient();
myClient.setDefaultUri("http://localhost:8080/ws");
myClient.setMarshaller(jaxb2Marshaller);
myClient.setUnmarshaller(jaxb2Marshaller);
return myClient;
}
}
应用程序-
如何将EMContext头添加到SOAP请求?服务器正在抱怨,因为您的Web服务客户端没有在SOAP消息中发送
EMContext
SOAP头
不幸的是,目前SpringWeb服务缺乏对以类似于使用JAXB处理SOAP主体信息的方式包含SOAP头的支持
作为一种解决方法,您可以使用WebServiceMessageCallback
。从:
为了适应SOAP头的设置和消息上的其他设置,WebServiceMessageCallback接口允许您在消息创建之后、发送之前访问消息
在您的情况下,您可以使用以下内容:
公共类MyClient扩展了WebServiceGatewaySupport{
公共GetEmployeeResponse getEmployee(字符串url,对象请求){
//获取所需信息
字符串messageId=“1”;
字符串refToMessageId=“ABC123”;
字符串sessionId=“3”;
字符串sessionSequenceNumber=“2021-02-24T00:00:00.000+5:00”;
字符串invokerRef=“CRS”;
GetEmployeeResponse res=(GetEmployeeResponse)this.getWebServiceTemplate().MarshallSendReceive(url,请求,新WebServiceMessageCallback()){
@凌驾
public void doWithMessage(WebServiceMessage消息)引发IOException、TransformerException{
//包括EMContext的SOAP头内容
试一试{
SoapMessage SoapMessage=(SoapMessage)消息;
SoapHeader=soapMessage.getSoapHeader();
StringSource headerSource=新StringSource(
"" +
“”+messageId+“”+
“”+refToMessageId+“”+
"" +
“”+会话ID+“”+
“”+sessionSequenceNumber+“”+
"" +
“”+invokerRef+“”+
""
);
Transformer Transformer=TransformerFactory.newInstance().newTransformer();
transform(headerSource,header.getResult());
}捕获(例外e){
//根据需要处理异常
e、 printStackTrace();
}
}
});
返回res;
}
}
类似的问题已经在SO上发布。例如,回顾或.< /P>您是否通过SOAPUI进行了呼叫?从何处获得请求片段?它来自另一个环境吗?@nirajha是的,它来自不同的环境。这是一个非常古老且非常大的项目,WSDL没有得到正确的维护。若我在SoapUI中使用上述输入,我将得到正确的结果。如果我使用java.net.HttpURLConnection,将完整的输入(如上所述,带有标题)作为字节写入OutputStream,并从InputStream读取(取自java.net.HttpURLConnection),那么也会得到正确的响应。尝试使用JAXB2复制相同的内容,即使用WSDL提供JAXB2生成的“EMContext Header is missing”类,没有任何称为EMContext的内容,并且在任何类上都没有EMContext的getter或setter。正如我所提到的,这是一个非常古老和非常大的项目,WSDL没有得到正确的维护。它仍然会给出相同的错误。谢谢你的反馈。“真奇怪,@CRSardar,它本该起作用的。”。请问,您能否验证邮件是否确实包含标题?为此,在
application.properties
文件中包含以下配置就足够了:logging.level.org.springframework.ws.client.MessageTracing.sent=DEBUG
。拜托,你能试试看发生了什么事吗?此外,如果您在doWithMessage
方法中调试代码,那么所有代码都正确执行了?@jccampanero感谢您的快速响应。我使用ObjectFactory的方法以其他方式添加了头。现在我在WebServiceTemplate.doSendAndReceive()上获得NullPointerException,日志记录为logging.level.org.springframework.ws.client.MessageTracing.sent=DEBUG和logging.level.org.springframework.ws=DEBUG,我只能看到发送的请求[SaajSoapMessage]{http://....}getEmployee]有没有办法记录完整的SOAP信封?请求和响应hi@CRSardar。我很高兴听到你设法找到另一种方法,包括标题。请你进一步解释一下你是怎么做的?是的,请使用logging.level.org.springframework.ws.client.MessageTracing.sent=TRACE
,而不是DEBUG
level。对不起,这应该是我在之前的评论中的第一个建议。请,您能试试吗?抱歉@CRSardar,我意识到您也要求我进行响应跟踪:请尝试logging.level.org.springframework.ws.client.MessageTracing.received=TRACE
@Configuration
public class EmpConfig {
@Bean
public Jaxb2Marshaller marshaller(){
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath("com.crsardar.java.soap.client.request");
return jaxb2Marshaller;
}
@Bean
public MyClient getClient(Jaxb2Marshaller jaxb2Marshaller){
MyClient myClient = new MyClient();
myClient.setDefaultUri("http://localhost:8080/ws");
myClient.setMarshaller(jaxb2Marshaller);
myClient.setUnmarshaller(jaxb2Marshaller);
return myClient;
}
}
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
CommandLineRunner lookup(MyClient myClient){
return args -> {
GetEmployeeRequest getEmployeeRequest = new GetEmployeeRequest();
getEmployeeRequest.setId(1);
GetEmployeeResponse employee = myClient.getEmployee("http://localhost:8080/ws", getEmployeeRequest);
System.out.println("Response = " + employee.getEmployeeDetails().getName());
};
}
}