0

Я пытаюсь вызвать внешний веб-сервис (не мой) из своего приложения GWT, работающего с App Engine.Почему я получаю ClassCastException с использованием HttpURLConnection в AppEngine?

Я знаю, что это невозможно сделать от клиента из-за 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. Но это должно быть на сервере (не так ли?)

Любые мысли были бы высоко оценены! Заранее спасибо

ответ

1

Ваша проблема не имеет ничего общего с GWT: пока вы работаете на сервере, вы можете использовать любую «нормальную» Java, и она будет работать, если у AppEngine не будет ограничений.

Кажется, вы импортировали версию Apache HttpClient версии repackaged в свой класс. Вы не должны этого делать: загрузите свой собственный HttpClient .jar, добавьте его в зависимости и используйте его.

AppEngine также имеет некоторые проблемы с HttpClient. Доступен адаптер here, который устраняет большинство проблем.

+0

Я не импортировал «переупакованную» версию Apache самостоятельно, я думаю, что это где-то в библиотеке AppEngine. – Felix

+0

- Извините, я нажал слишком быстро - Поскольку я работаю с Maven, я добавил [зависимость от HTTP-клиента HTTP] (http://mvnrepository.com/artifact/com.google.http-client/google-http -client/1.20.0), но проблема остается. Наконец, я постараюсь сделать все возможное со ссылкой, которую вы мне дали. Это старый и иногда устаревший код, но если он все еще работает, я беру его. Спасибо вам за помощь! – Felix

+0

@ Феликс уверен, что старый, но я использую его в производстве в течение многих лет без проблем! У службы fetch есть много досадных ограничений, и, кроме перехода на Compute Engine, мы не можем многое сделать ... – Marcelo

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() 
       ... 
      } 

код работает и до настоящего времени.

Редактировать

Вот остальная часть решения при использовании прокси-сервера. Mine использует только 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(); 

Еще раз спасибо за вашу помощь, я очень благодарен!

 Смежные вопросы

  • Нет связанных вопросов^_^