gpt4 book ai didi

在 Netbeans 中生成的 Java Web 服务客户端 - 获取 Http 状态代码 307

转载 作者:行者123 更新时间:2023-12-01 05:45:07 26 4
gpt4 key购买 nike

我使用 Netbeans 生成 Web 服务客户端代码(客户端样式的 JAX-WS),因此我可以调用 Web 服务 API。

但是,当我调用 Web 服务 API 时,出现异常:com.sun.xml.internal.ws.client.ClientTransportException:服务器发送了 HTTP 状态代码 307:临时重定向

为什么我会得到这个?解决方法是什么?我知道问题不在于 Web 服务本身,因为我可以通过soapUI 和.Net 获得良好的响应。

最佳答案

大约一个月前遇到同样的问题。

Web 服务客户端类是使用 Apache CXF 生成的,Web 服务返回 HTTP状态 307,这导致了相同的异常。

使用具有属性Follow Redirects的soapUI调用相同的Web服务方法设置为true成功并返回所需数据。

经过谷歌搜索一段时间后,看起来 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 的实例& javax.xml.ws.BindingProvider接口(interface)。 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");
}

现在,当我们确定 retrieveMyObjectsPortjavax.xml.ws.BindingProvider 的实例我们可以向它发送普通的 HTTP POST 请求,模拟 SOAP 请求(虽然它看起来非常不正确且丑陋,但这在我的情况下有效,并且我在谷歌搜索时没有找到更好的东西)并检查 Web 服务是否会将重定向状态作为回复:

// 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);

现在,这个方法的作用是:它需要 BindingProvider.ENDPOINT_ACCESS_PROPERTYretrieveMyObjectsPort即此端口方法将向其发送 SOAP 请求并发送普通 HTTP POST 请求的 url,如上所述。然后检查响应状态是否为 307 - Temporary Redirect (还可能包括其他状态,如 302 或 301),如果是,则获取 Web 服务重定向到的 URL 并为指定端口设置新端点。

就我而言,这个 checkRedirect为每个 Web 服务端口接口(interface)调用一次方法,然后一切似乎都工作正常:

  1. http://example.com:50678/restOfUrl 等网址上检查重定向
  2. Web 服务重定向至类似 https://example.com:43578/restOfUrl 的 URL (请注意,存在 Web 服务客户端身份验证)- 端口端点设置为该 url
  3. 通过该端口执行的下一个 Web 服务请求将成功

免责声明:我对网络服务还很陌生,由于缺乏该问题的解决方案,这是我设法实现的,所以如果这里有问题,请纠正我。

希望这有帮助

关于在 Netbeans 中生成的 Java Web 服务客户端 - 获取 Http 状态代码 307,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6145096/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com