Отправка нескольких HTTP-запросов в Java - проблема с OuputStreamWriter? - PullRequest
0 голосов
/ 01 июля 2011

Я использую Java для отправки HTTP-запросов веб-сервисам.Мне удается отправить один, но я не могу отправить два.Это часть моего кода (некоторые части удалены для читабельности:

try {
String data =  "<soap:Envelope xmlns:soap= ... datas xml ... </soap:Envelope>";
URL url = new URL(".......url........");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.addRequestProperty("Content-Type", "text/xml");
conn.addRequestProperty("SOAPAction", .......action.......");
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); // fail here for the second request

//write parameters
writer.write(data);
writer.flush();

// Get the response
StringBuffer answer = new StringBuffer();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {answer.append(line);
}
    writer.close();
reader.close();

//Output the response
String str=answer.toString();
// conn.disconnect(); // Should I put it ?
label.setText(str);
} 

catch (Exception ex) {label.setText(ex.getMessage());}

. Этот запрос работает нормально. Если я поставлю то же самое после и проведу несколько тестов, я обнаружу, что он не работает (я изменяюимена переменных, в случае ...). Я обнаружил, что он завершается с ошибкой в ​​строке с OuputStreamWriter. Я получаю эту ошибку с getMessage в исключении:

доступ запрещен (java.net.SocketPermission.... url ..... подключение, разрешение)

Как я могу это исправить? Я выясняю, можно ли отправлять несколько запросов ... Полезен ли здесь методnectnect ()?

Я пытался отправить запрос через другой класс (на самом деле, у меня есть веб-страница и javascript вызывают запросы один за другим), и он тоже не работает ..

СпасибоВы очень за любой совет или помощь!

===================== РЕДАКТИРОВАТЬ =======================

Вот целый апплет:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import netscape.javascript.JSException;
import netscape.javascript.JSObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class Test extends JApplet {
private JSObject jso;
private JLabel label = new JLabel();

public void init(){
    this.setSize(300, 80);

    label.setHorizontalAlignment(JLabel.CENTER);
    label.setForeground(Color.blue);
    label.setText("hello world");

    this.getContentPane().add(label, BorderLayout.NORTH);
}

public void doJavascript(){
    label.setText("hellooooooooo");
}


public void closeConnect(String SECTK, String SESSID){
    jso = JSObject.getWindow(this);
    label.setHorizontalAlignment(JLabel.CENTER);
    label.setForeground(Color.blue);
    try{
     String data ="dataaaaa";
     label.setText("yes2");
 URL url = new URL(".........url.............");
 HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 conn.addRequestProperty("Content-Type", "text/xml");
 conn.addRequestProperty("SOAPAction", ".....url........");
 conn.setDoOutput(true);
 label.setText("yes25");
 OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
 label.setText("yes3");
 writer.write(data);
 writer.flush();

 StringBuffer answer = new StringBuffer();
 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
 String line;
 while ((line = reader.readLine()) != null) {
     answer.append(line);
 }
 writer.close();
 reader.close();
 //Output the response*/
    String str=answer.toString();
    conn.disconnect();
    label.setText(str);
 } 
 catch (Exception ex) {
// label.setText("nooo");
 label.setText(ex.getMessage());
}
this.getContentPane().add(label, BorderLayout.NORTH);
}
}

Если я вызываю doJavascript из файла javascript, он работает. Если я вызываю closeConnect из того жеФайл javascript, он не работает, и я получаю в своем ярлыке «yes25», который находится перед «OuputStreamWriter» ...

Надеюсь, это понятно.

Спасибо за любыепомощь или совет

Ответы [ 2 ]

0 голосов
/ 13 июля 2011

Я исправил это: существует проблема безопасности для вызовов из javascript в java для некоторых видов методов - например, http-запросов: http://jdk6.java.net/plugin2/liveconnect/#SECURITY_MODEL

Таким образом, код должен быть изменен следующим образом:

final HttpURLConnection conn = (HttpURLConnection) url.openConnection();

и

OutputStreamWriter writer;
                // This is needed as code called from Javascript does not have the rights to do this
                try
                {
                    writer = 
                        AccessController.doPrivileged(
                            new PrivilegedExceptionAction<OutputStreamWriter>() {
                                public OutputStreamWriter run() throws IOException {
                                    return new OutputStreamWriter(conn.getOutputStream());
                                }
                            }
                        );
                }
                catch (PrivilegedActionException e) {
                    // e.getException() should be an instance of IOException,
                    // as only "checked" exceptions will be "wrapped" in a
                    // PrivilegedActionException.
                    throw (IOException) e.getException();
                }

и

StringBuffer answer = new StringBuffer();
                BufferedReader reader;
                // This is needed as code called from Javascript does not have the rights to do this
                try
                {
                     reader = new BufferedReader(
                        AccessController.doPrivileged(
                            new PrivilegedExceptionAction<InputStreamReader>() {
                                public InputStreamReader run() throws IOException {
                                    return new InputStreamReader(conn.getInputStream());
                                }
                            }
                        )
                    );
                }
                catch (PrivilegedActionException e) {
                    // e.getException() should be an instance of IOException,
                    // as only "checked" exceptions will be "wrapped" in a
                    // PrivilegedActionException.
                    throw (IOException) e.getException();
                }
0 голосов
/ 02 июля 2011

Второй запрос направляется на другой сервер, чем тот, с которого был загружен апплет? Если так, то это проблема.

Апплеты не могут подключаться или извлекать ресурсы с любого стороннего сервера (любого сервера, кроме сервера, с которого он был создан).

http://download.oracle.com/javase/tutorial/deployment/applet/security.html

Я бы порекомендовал решить эту проблему с помощью RMI, чтобы апплет связывался с сервером, и чтобы сервер делал фактические запросы XML от имени апплета. Это действительно легко сделать, и использование сервера загрузки в качестве прокси-сервера позволяет апплетам делать все, что не позволяет им менеджер безопасности.

...