I wrote soap client service using Java.
Also I used Spring WS.
When I send request via SoapUI I get response.
When I send request using client code, I get error
org.springframework.ws.client.WebServiceTransportException: Temporary Redirect [307]
at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:699)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:609)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373)
Client Config
class SushiClientConfig {
private Jaxb2Marshaller jaxb2Marshaller(String pathToGeneratedClasses) {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath(pathToGeneratedClasses);
return jaxb2Marshaller;
}
WebServiceTemplate webServiceTemplate(String pathToGeneratedClasses, String uri) {
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMarshaller(jaxb2Marshaller(pathToGeneratedClasses));
webServiceTemplate.setUnmarshaller(jaxb2Marshaller(pathToGeneratedClasses));
webServiceTemplate.setDefaultUri(uri);
webServiceTemplate.setMessageSender(webServiceMessageSender());
return webServiceTemplate;
}
private WebServiceMessageSender webServiceMessageSender() {
HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender();
httpComponentsMessageSender.setReadTimeout(SushiConstants.TIMEOUT);
return httpComponentsMessageSender;
}
}
Can you help me?
I really don't know how to fix it. Thanks!
After hours of investigation, I decided to get just redirected URLs.
So issue is not resolved for SPRING-WS
Related
Good day. I am new to spring integration. I wrote a simple SOAP server, and I need to connect a client that communicates through JSON and a server that communicates via SOAP, but I’ve got confused in the technology that this framework provides. As I understand it there are JsonToObjectTransformer and ObjectToMapTransformer transformers. As I understand it is necessary to transform the data before transmitting it to the controller. Is it possible to do this with the help of transformers, or I can use other technologies in the spring integration. And can this be done only with the help of DSL?
Controller:
#Endpoint
public class CityEndpoint {
private static final String NAMESPACE_URI = "http://weather.com/senchenko";
private CityRepository cityRepository;
#Autowired
public CityEndpoint(CityRepository cityRepository) {
this.cityRepository = cityRepository;
}
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCityRequest")
#ResponsePayload
public GetCityResponse getCityResponse(#RequestPayload GetCityRequest request){
GetCityResponse response = new GetCityResponse();
response.setCity(cityRepository.findCity(request.getName()));
return response;
}
}
Config:
#EnableWs
#Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
servlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean(servlet, "/ws/*");
}
#Bean(name = "city")
public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema citySchema) {
DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
wsdl11Definition.setPortTypeName("CityPort");
wsdl11Definition.setLocationUri("/ws");
wsdl11Definition.setTargetNamespace("http://weather.com/senchenko");
wsdl11Definition.setSchema(citySchema);
return wsdl11Definition;
}
#Bean
public XsdSchema citySchema() {
return new SimpleXsdSchema(new ClassPathResource("xsd/weather.xsd"));
}
#Bean
#Transformer()
JsonToObjectTransformer jsonToObjectTransformer() {
return new JsonToObjectTransformer();
}
#Bean
#Transformer()
ObjectToMapTransformer objectToMapTransformer(){
return new ObjectToMapTransformer();
}
}
Addition
I solved the problem with redirection to SOAP, but still do not know the best way to convert JSON into an SOAP Envelope and back.
#Bean
public IntegrationFlow httpProxyFlow() {
return IntegrationFlows
.from(Http.inboundGateway("/service"))
.transform(t -> TEST_ENVOLOPE)
.enrichHeaders(h -> h.header("Content-Type", "text/xml; charset=utf-8"))
.handle(Http.outboundGateway("http://localhost:8080/ws")
.expectedResponseType(String.class))
.transform(t -> TEST_RESPONSE)
.get();
}
Your question isn't clear or you are not fully familiar with technologies you need to work.
The SOAP is fully about XML messages exchange. On the server side you have a specific MessageDispatcherServlet which converts an incoming HTTP request to the SOAP envelop fully in XML. There is just nothing about JSON at all.
Your CityEndpoint.getCityResponse() is triggered by the Spring WS Framework when an incoming SOAP request is unmarshalled from the XML into the domain model via JaxB according your XSD definition and generated model. There is just nothing about Spring Integration at all.
Your JsonToObjectTransformer and ObjectToMapTransformer just don't make any sense in this scenario. They are not involved in the SOAP request process.
Sorry to disappoint you in my answer, but it even not clear by your question how that JSON client is going to call SOAP service when JSON and XML are fully different and not compatible protocols.
I am using spring webservices for consuming a service. I am following this article https://spring.io/guides/gs/consuming-web-service/, I have created a client by extending WebServiceGatewaySupport and using that to invoke the service.
The first doubt I have is that I haven't generated any java classes from wsdl (other than jaxb objects for the types mentioned in wsdl). Don't I have to generate the stub (endpoint) classes on the client side? If not, then how does spring know which operation to be invoked as my wsdl has multiple operations?
Here is my code
public class SOAPConnector extends WebServiceGatewaySupport {
public Object callWebService(String url, Object request){
return getWebServiceTemplate().marshalSendAndReceive(url, request);
}
}
#Configuration
public class Config {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
// this is the package name specified in the <generatePackage> specified in
// pom.xml
marshaller.setContextPath("com.example.howtodoinjava.schemas.school");
return marshaller;
}
#Bean
public SOAPConnector soapConnector(Jaxb2Marshaller marshaller) {
SOAPConnector client = new SOAPConnector();
client.setDefaultUri("https://www.example.com/ExampleServiceBean");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
}
The second issue is that on executing above code I am getting following error message, can someone please help me how to fix it:
org.springframework.ws.soap.client.SoapFaultClientException: Message part Request was not recognized. (Does it exist in service WSDL?)
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:38)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:830)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:624)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:506)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:446)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:436)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:424)
I might be a missing a very basic thing as I am using spring webservices for the first time. Thanks in advance.
Hi I create code for consume SOAP service,
For Authentication Header I used Wss4jSecurityInterceptor for set Header information.
I am getting fail response like below
Exception in thread "main" org.springframework.ws.soap.client.SoapFaultClientException: Required element {http://www.w3.org/2005/08/addressing}Action is missing
My Configuration code as below
#Configuration
public class SoapClientConfig {
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.xyz.client");
marshaller.setCheckForXmlRootElement(false);
return marshaller;
}
#Bean
public MyClient myClient(Jaxb2Marshaller marshaller) throws Exception {
MyClient client = new MyClient();
client.setDefaultUri("https://localhost:8080/ws/service");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
ClientInterceptor[] interceptors = new ClientInterceptor[] {securityInterceptor()};
client.setInterceptors(interceptors);
return client;
}
#Bean
public Wss4jSecurityInterceptor securityInterceptor() {
Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
wss4jSecurityInterceptor.setSecurementActions("UsernameToken");
wss4jSecurityInterceptor.setSecurementMustUnderstand(true);
wss4jSecurityInterceptor.setSecurementPasswordType("PasswordText");
wss4jSecurityInterceptor.setSecurementUsername("XXXXXXXXXXX");
wss4jSecurityInterceptor.setSecurementPassword("XXXXXXXX");
return wss4jSecurityInterceptor;
}
}
Can anyone suggest me what I am missing?
If I try from SOAPUI its working fine. If I set WS-Addressing=false from SOAPUI also giving me same error, So Issue with set WS-Addressing property with above code. How can I?
Do you use WebServiceTemplate to send the request? If yes, you can do something like :
ActionCallback callback = new ActionCallback(
new URI("action uri"));
Here you should provide actual uri location of action instead "action uri". Then, do
getWebServiceTemplate().marshalSendAndReceive(request, callback)
Long time before worked on populating SOAP Header with dynamic value, for that you need to work on constructing the xml nodes using callback object...WebServiceMessageCallback
http://docs.spring.io/spring-ws/site/reference/html/client.html#d5e1848
In my scenario I need to construct the node using QName (Java) Node by Node.
I am trying to convert file:outbound-gateway configuration in XML to Java config, but can't find the correct API.
XML:
<file:outbound-gateway directory="file:myDir"
request-channel="inFiles" auto-create-directory="true"
delete-source-files="true" reply-channel="outFiles">
</file:outbound-gateway>
This is what I have so far on Java configuration. Not sure how to set request-channel and reply-channel:
#Bean
public MessageHandler fileOutBoundGateway() {
FileWritingMessageHandler gateway = new FileWritingMessageHandler(new File("myDir"));
gateway.setDeleteSourceFiles(true);
gateway.setAutoCreateDirectory(true);
// FIXME need to set request and reply channel
return gateway;
}
The request-channel (inputChannel) is an option of the endpoint. In your case you have only channel and MessageHandler, but there is still no endpoint.
Only what you need is service-activator:
#Bean
#ServiceActivator(inputChannel = "input")
public MessageHandler fileOutBoundGateway() {
FileWritingMessageHandler gateway = new FileWritingMessageHandler(new File("myDir"));
gateway.setDeleteSourceFiles(true);
gateway.setAutoCreateDirectory(true);
gateway.setOutputChannel(outputChannel());
return gateway;
}
Please, find more info in the Reference Manual.
Also pay attention, please, to the Java DSL.
I need to authentication SOAP header and give the response accordingly in my web service. The authentication header will verify the userId and password information.
If authenticated, then SOAP body of the request will be processed, else Invalid Authentication message will be returned
Below is my controller
package com.ws.controller;
#Endpoint
public class MyWSEndpoint
#Autowired(required=true)
private WSService service;
#PayloadRoot(localPart = "myWSRequest", namespace = Constants.TARGET_NAMESPACE)
public #ResponsePayload MyWSResponse getInfo(#RequestPayload MyWSRequest request) throws Exception
{
MyWSResponse response = new MyWSResponse();
response=service.getResponse();
return response;
}
}
i'm using Spring + SOAP
Please advise if i do right or better approach to solve.
Any working samples or projects will be much appreciated