我使用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
頭之後。