我尝试从使用App Engine的GWT应用程序调用外部Web服务(不是我的)。
我知道由于SOP(同源策略)而无法从客户端执行此操作,并且RequestBuilder不是服务器上的解决方案。我按照the web site上的教程和using java.net以及
进行了操作这是客户端
AsyncCallback<CustomObject> callback = new AsyncCallback<CustomObjectCustomObject>() {
@Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
@Override
public void onSuccess(CustomObject result) {
// code omitted
}
};
service.callMethod(aString, callback);
这是服务器
try {
String xmlRequest = "xmlToSend";
URL url = new URL("https://www.externalWebService.com");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setAllowUserInteraction(false);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type","application/soap+xml");
conn.setRequestProperty( "Content-length", Integer.toString(xmlRequest.length()));
conn.setRequestProperty("charset", "utf-8");
conn.setConnectTimeout(10000);
OutputStream rawOutStream = conn.getOutputStream();
PrintWriter pw = new PrintWriter(rawOutStream);
pw.print(xmlRequest);
pw.flush();
pw.close();
if(conn.getResponseCode() != 200){
// Something...
}
我在conn.getResponseCode()
处发出同样的错误:
java.lang.ClassCastException: com.google.appengine.repackaged.org.apache.http.message.BasicHttpRequest cannot be cast to com.google.appengine.repackaged.org.apache.http.client.methods.HttpUriRequest
在没有提出真实请求的情况下,远程服务运行良好:它能够序列化并将对象返回给客户端。该问题与客户端和服务器之间的通信无关,它更像是AppEngine不支持HttpURLConnection。但它应该在服务器上(不是吗?)
任何想法都会得到高度赞赏!提前致谢
答案 0 :(得分:1)
您的问题与GWT无关:只要您在服务器上运行,您就可以使用任何“普通”Java,除非AppEngine有限制,否则它将起作用。
您的类中似乎已导入Apache {HttpClient的repackaged
版本。你不应该这样做:下载你自己的HttpClient .jar,将它添加到依赖项并使用它。
AppEngine在HttpClient方面也存在一些问题。有一个可用的适配器here可以解决大部分问题。
答案 1 :(得分:0)
谢谢@Marcelo,你是对的!
这是我找到的解决方案。
我在构建路径中添加了httpcore.jar
和httpclient.jar
,并为服务器编写了以下代码(客户端是相同的):
String xmlRequest = "xmlToSend";
CloseableHttpClient httpclient = HttpClients.custom().build();
//RequestConfig requestConfig = RequestConfig.custom()
// .setConnectionRequestTimeout(10000)
// .build();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out);
writer.write(xmlToSend);
writer.flush();
writer.close();
HttpPost request = new HttpPost("https://www.externalWebService.com/path");
request.setEntity(new ByteArrayEntity(out.toByteArray()));
//request.setConfig(requestConfig);
CloseableHttpResponse response = httpclient.execute(request);
if(response.getStatusLine().getStatusCode() == 200){
// retrieve content with a BufferReader
// from response.getEntity().getContent()
...
}
代码有效并且是最新的。
修改强>
使用代理时,这是解决方案的其余部分。我的只处理NTCredentials,否则可以使用UsernamePasswordCredentials
代替。
HttpHost proxy = new HttpHost("addresse.proxy.com", port);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(proxy),
new NTCredentials(System.getProperty("user.name") + ":" + password));
RequestConfig requestConfig = RequestConfig.custom()
.setProxy(proxy)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultRequestConfig(requestConfig)
.build();
再次感谢您的帮助,我真的很感激!