Calling web service that sits on a load balancer w

2019-02-07 14:59发布

When I call a web service that sits on a load balancer with jax-ws, it returns

The server sent HTTP status code 302: Moved Temporarily

and then fails, but when I use SoapUI it works fine.

Is there a way that I can configure the service to handle this correctly?

I generated the webservice code using wsimport and make the call as such

NotificationWebService service = new NotificationWebService(wsdlLocation, qName);
NotificationWebServiceSoap serviceSoap = service.getNotificationWebServiceSoap();
String xmlString = serviceSoap.getRSAPublicKeyXMLString();

I'm stuck and I haven't been able to find a solution anywhere so any help would be appreciated.

3条回答
【Aperson】
2楼-- · 2019-02-07 15:39

Reason is the redirection issue on web service call control gets transfered from HTTP to HTTPS. Edit your WSDL file you will find the below code:

original code:

soap:address location="http://www.google.com/Services/Services_xyz.asmx"

changed code:

soap:address location="https://www.google.com/Services/Services_xyz.asmx"

Just change the location attribute HTTP to HTTPS and generate the new stub using the changed WSDL file location.

查看更多
Anthone
3楼-- · 2019-02-07 15:48

So after lots of investigation I finally figured out what the problem was. It was all down to redirecting from http to https. From articles I found on the web (can't remember the urls anymore), is that the libraries that the wsdl2java and wsimport stub generators use to do the webservice communication don't allow a http to https redirect follow due to security reasons.

So even though I was generating the stubs from a https wsdl location ie. https://wsdl.location.com?wsdl, when I ran the code to do a webservice call, it was trying to make the call to http://wsdl.location.com which resulted in a redirect request to https://wsdl.location.com, But the http library does not allow that. So it just forwards the 302 http code up as an exception.

Also, there are two web-service urls. One is a testing service which is normal http url and then there is a production server which is over https. So to work around this is all I did is configure the service on the fly to use the end-point I have specified (which is now the https address) by using the BindingProvider class. This also allows me to specify on the fly depending on which environment that is making to call, to use the test url or the production one ie.

NotificationWebService service = new NotificationWebService();
NotificationWebServiceSoap serviceSoap = service.getNotificationWebServiceSoap();

BindingProvider bindingProvider = (BindingProvider) serviceSoap;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://wsdl.location.com");

String xmlString = serviceSoap.getRSAPublicKeyXMLString();

So in short, if anyone encounters this problem. Make sure if the end point you need point to is on https, that you are making a direct https call and not a http call that will ask for an https redirect. You can check this by examining the serviceSoap while debugging. It will say to which url it is making the call.

I didn't look into or go with the option to configure wsdl2java and wsimport to generate the stubs and force the stubs to use the https call so that I could configure multiple url end-points for different environments.

查看更多
beautiful°
4楼-- · 2019-02-07 16:03

Yes. You didn't say what you're using for the transport, but if it's something like HttpClient you need to set it up to follow redirects. You may need to fiddle with the auto-generated code, or alternatively, perhaps try a higher level abstraction, like Spring Web Services or CXF.

查看更多
登录 后发表回答