我使用NetBeans生成的Web服务客户端代码,客户端式的JAX-WS,这样我就可以调用Web服务的API。的Java Web服务客户端 - 让Http状态代码307
然而,当我调用Web服务API,我得到异常: com.sun.xml.internal.ws.client.ClientTransportException:服务器发送HTTP状态码307:临时重定向
我为什么得到这个?什么是解决方法?我知道问题不在Web服务本身,因为我可以通过soapUI和.Net很好地得到响应。
我使用NetBeans生成的Web服务客户端代码,客户端式的JAX-WS,这样我就可以调用Web服务的API。的Java Web服务客户端 - 让Http状态代码307
然而,当我调用Web服务API,我得到异常: com.sun.xml.internal.ws.client.ClientTransportException:服务器发送HTTP状态码307:临时重定向
我为什么得到这个?什么是解决方法?我知道问题不在Web服务本身,因为我可以通过soapUI和.Net很好地得到响应。
面对大约一个月前同样的问题。使用Apache CXF生成
Web服务客户端类和Web服务返回的HTTP 状态307,这就导致了同样的异常。
使用soapUI属性Follow Redirects
设置为true
的相同Web服务方法的调用已成功并返回了所需的数据。
一段时间谷歌搜索后,它看起来像有没有财产,使下面的JAX-WS重定向这一点。
所以,下面是当前工作的代码,虽然我不知道这是符合任何标准:
假设生成的客户端类的样子:现在
// generated service class
public class MyWebServiceClient extends javax.xml.ws.Service {
// ...
private final QName portName = "...";
// ...
public RetrieveMyObjects getRetrieveMyObjects() {
return super.getPort(portName, RetrieveMyObject.class);
}
// ...
}
// generated port interface
// annotations here
public interface RetrieveMyObjects {
// annotations here
List<MyObject> getAll();
}
,在执行下面的代码:
MyWebServiceClient wsClient = new MyWebServiceClient("wsdl/location/url/here.wsdl");
RetrieveMyObjectsPort retrieveMyObjectsPort = wsClient.getRetrieveMyObjects();
wsClient
应该返回实例,它是RetrieveMyObjects
两个实例3210 javax.xml.ws.BindingProvider
接口。它在JAX-WS的表面没有任何地方,但是似乎很多代码都是基于这个事实。我们可以再保证他\她通过执行类似:
if(!(retrieveMyObjectsPort instanceof javax.xml.ws.BindingProvider)) {
throw new RuntimeException("retrieveMyObjectsPort is not instance of " + BindingProvider.class + ". Redirect following as well as authentication is not possible");
}
现在,当我们确信retrieveMyObjectsPort
是javax.xml.ws.BindingProvider
例如,我们可以把普通的HTTP POST请求给它,模拟SOAP请求(虽然它看起来令人难以置信不正确&难看,但这部作品在我的情况,我没有找到更好的东西,而谷歌搜索),并检查网络服务是否将发送重定向状态作为响应:
// defined somewhere before
private static void checkRedirect(final Logger logger, final BindingProvider bindingProvider) {
try {
final URL url = new URL((String) bindingProvider.getRequestContext().get(ENDPOINT_ADDRESS_PROPERTY));
logger.trace("Checking WS redirect: sending plain POST request to {}", url);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setInstanceFollowRedirects(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "text/html; charset='UTF-8'");
connection.setDoOutput(true);
if(connection.getResponseCode() == 307) {
final String redirectToUrl = connection.getHeaderField("location");
logger.trace("Checking WS redirect: setting new endpoint url, plain POST request was redirected with status {} to {}", connection.getResponseCode(), redirectToUrl);
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, redirectToUrl);
}
} catch(final Exception e) {
logger.warn("Checking WS redirect: failed", e);
}
}
// somewhere at the application start
checkRedirect(logger, (BindingProvider) retrieveMyObjectsPort);
现在,这个方法的作用是:它需要的retrieveMyObjectsPort
BindingProvider.ENDPOINT_ACCESS_PROPERTY
即网址whic h此端口方法将发送SOAP请求并发送如上所述的普通HTTP POST请求。然后它检查响应状态是否为307 - Temporary Redirect
(其他状态等302或301也可以被包括在内),并且如果它是,获取的URL的web服务被重定向,其并设置新的端点为指定的端口。
在我的情况下,该checkRedirect
方法为每个Web服务端口接口调用一次,然后一切似乎很好地工作:
http://example.com:50678/restOfUrl
https://example.com:43578/restOfUrl
(请注意,存在Web服务客户端身份验证) - 端口的端点设置为该URL声明:我对web服务相当陌生,这是我成功实现的,由于缺乏针对此问题的解决方案,所以如果出现问题,请纠正我的错误。
希望这有助于
是的,我知道这个帖子是老了,但我已经有类似的错误,也许想到有人会从我的解决方案中受益。
的一个困扰我最多的是:这原来是说一个不完整的响应头
com.sun.xml.ws.client.ClientTransportException: The server sent HTTP status code 200: OK
。显然,jax-ws会进行一些验证,包括验证HTTP头。而我使用的服务器只是发送一个空头。
它的工作就像一个魅力加'application/soap+xml'
到Content-Type
头之后。