У меня проблема с отправкой данных через HTTPS в Java. Ответ сервера будет одинаковым независимо от того, отправляю я «запрос» или нет. Может кто укажет в чем проблема ...

Благодарность!

Основной класс:

package bind;

public class Main {

    public static final String urlString = "https://www.sms.ethz.ch/cgi-bin/sms/send.pl";

    public static void main(String[] args) {

 Message msg = new Message("Alles klar?");
 URL url = new URL(urlString);

 String[][] values = new String[3][2];
 values[0][0] = "action";
 values[0][1] = "listoriginators";
 values[1][0] = "username";
 values[1][1] = "xxxxxx";
 values[2][0] = "password";
 values[2][1] = "xxxxxx";


 Query query = new Query(values);
 System.out.println("Query: " + query.getQuery());

 Request request = new Request(url.getURL(), query.getQuery());


    }
}

Запросить класс:

package bind;

public class Request {
    static private int ic = 0;
    private URL url;

    protected Request(java.net.URL URL, String query){
 ic++;
 if(CONSTANTS.SHOW_LOGS) { System.out.println("log: new instance of 'Message'"); }

 // connect
 try {

     System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
     java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

     javax.net.ssl.HttpsURLConnection connection = (javax.net.ssl.HttpsURLConnection) URL.openConnection();
     connection.setDoInput(true);
     connection.setDoOutput(true);
     connection.setRequestMethod("POST");
     connection.setFollowRedirects(true);

     connection.setRequestProperty("Content-Length", String.valueOf(query.length()));
     connection.setRequestProperty("Content-Type", "application/x-www- form-urlencoded");
     connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

     java.io.DataOutputStream output = new java.io.DataOutputStream(connection.getOutputStream());

     output.writeBytes(query); // <<-- NOTHING CHANGES IF I COMMENT THIS OUT OR NOT !!??!?!

     System.out.println("log: response code: " + connection.getResponseCode());
     System.out.println("log: response message: " + connection.getResponseMessage());

     java.io.DataInputStream input = new java.io.DataInputStream(connection.getInputStream());
     for(int i = input.read(); i != -1; i = input.read()) {
  System.out.print((char)i);
     }
     System.out.print("\n");
     input.close();

 } catch(java.io.IOException e) {
     if(CONSTANTS.SHOW_LOGS) {
  System.out.println("error: unable to connect");
  System.out.println(e);
  e.printStackTrace();
     }
 }

    }
}

Класс URL:

public class URL {
    static private int ic = 0;
    private String URLString;
    private java.net.URL url;

    protected URL(String a_url){
 ic++;

 if(CONSTANTS.SHOW_LOGS) { System.out.println("log: new instance of 'URL'"); }

 setURLString(a_url);
 createURL();
    }

    private void setURLString(String a_url) {
 URLString = a_url;
    }

    private void createURL() {
 try {
     url = new java.net.URL(URLString);
 } catch(java.net.MalformedURLException e) {
     System.out.println("error: invalid URL");
     System.out.println(e);
     e.printStackTrace();
 }
    }

    private void showURL() {
 System.out.println("URL: " + url.getHost() + url.getPath());
    }

    public java.net.URL getURL() {
 return url;
    }

}

PS: в основном отсюда: http: //www.java-samples.com/java/POST-toHTTPS-url-free-java-sample-program.htm

0
ostollmann 20 Мар 2010 в 04:17

2 ответа

Лучший ответ

Урк. Можно ли убедить вас использовать вместо этого общедоступный http-клиент Apache?

Эта ссылка более прямая.

Это намного меньше работы, чем отладка этого кода.

1
bmargulies 20 Мар 2010 в 04:23
Спасибо за совет. Я займусь этим. Спасибо!
 – 
ostollmann
20 Мар 2010 в 14:52
Просто хотел поблагодарить вас за совет об общих библиотеках Apache, они потрясающие! Спасибо!
 – 
ostollmann
25 Мар 2010 в 19:40

Вы забыли flush() или, лучше, close() поток после этого (который уже выполняет неявный сброс). Очистка необходима, потому что данные могут быть внутренне буферизованы до определенной длины, а очистка заставляет весь буфер фактически записываться на выход.

Итак, измени

 output.writeBytes(query);

К

 output.writeBytes(query);
 output.close();

На самом деле, обычная идиома - закрывать потоки в блоке finally блока try по мере их получения, чтобы вы могли гарантировать, что они закроются всякий раз, когда IOException происходит во время написать. Закрытие важно, потому что оно освобождает системные ресурсы.

Stream stream = null; // Can be InputStream, OutputStream, Reader or Writer.
try {
    stream = new SomeStream();
    // ...
} finally {
    if (stream != null) try { stream.close(); } catch (IOException logOrIgnore) {} // You can if necessary bake an utility method taking Closeable or take a look for commons IO.
}

Также см. руководство по Sun Java IO для получения дополнительных уроков и руководств. .

2
BalusC 20 Мар 2010 в 06:48
Спасибо за ответ, но это ничего не меняет. Я действительно пробовал это раньше (не знаю, почему я удалил это снова). Я мог бы попробовать упомянутые выше bmargulies HTTP-клиента Apache Commons.
 – 
ostollmann
20 Мар 2010 в 14:51
Вы звонили output.close() перед звонком connection.getInputStream(), не так ли?
 – 
BalusC
21 Мар 2010 в 07:27
Извините за поздний ответ, я использовал библиотеки Apache, упомянутые bmargulies, поэтому я вроде как снял эту проблему. Но я добавил его в строку сразу после output.writeBytes (query), все равно не сработало. Я думаю, это может иметь какое-то отношение к ssl ... В любом случае я перешел на библиотеки Apache, и они отлично работают. Спасибо за помощь :-)
 – 
ostollmann
25 Мар 2010 в 19:39
Без проблем. Не забудьте отметить его ответ как принятый, иначе этот вопрос останется без ответа.
 – 
BalusC
25 Мар 2010 в 19:58