1

我正在尝试将 JSON 发布到 Web 服务,以便我可以获得 JSON 作为返回响应,我在 Google 中进行了搜索,但我发现的大部分响应是针对 Android 而不是核心 Java,这个问题是针对Swing 应用程序 我将在下面给出我使用的代码。

连接类

public class Connection extends Thread {

private String url1;
private JSONObject data;
String line;
//Constuctor to initialize the variables.

public Connection(String url1, JSONObject data) {
    this.url1 = url1;
    this.data = data;
    start();
}

public void run() {
    ConnectionReaderWriter();
}

//To fetch the data from the input stream
public String getResult() {
    return line;
}

public String ConnectionReaderWriter() {
    URL url;
    HttpURLConnection connection = null;
    ObjectOutputStream out;
    try {
        /*URL url = new URL(Url.server_url + url1);     //Creating the URL.       
         URLConnection conn = url.openConnection();    //Opening the connection.
         conn.setDoOutput(true);
         OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
         wr.write(data);  //Posting the data to the ouput stream.
         wr.flush();
         BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
         line=rd.readLine();     //Reading the data from the input stream.       
         wr.close();
         rd.close();*/
        url = new URL(Url.server_url + url1);     //Creating the URL.
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("api_key", "123456");
        connection.setUseCaches(false);
        connection.setDoInput(true);
        connection.setDoOutput(true);
        //Send request
        out = new ObjectOutputStream(connection.getOutputStream());
        out.writeObject(data);
        out.flush();
        out.close();
    } catch (MalformedURLException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
        String nonet = "No Network Connection";
        line = nonet;
    } catch (IOException ex) {
        Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
        String nonet = "No Server Connection";
        line = nonet;
    }
    return line;  //Return te stream recived from the input stream.
}
}

注释代码是我之前作为编码到 URL 的文本传递时使用的代码。函数调用如下

JSONObject json = new JSONObject();
                json.put("username", username);
                json.put("password", passwordenc);                    
                Connection conn = new Connection(Url.login, json);
                conn.join();

在执行时,我得到如下所示的异常

Jan 20, 2014 1:18:32 PM SupportingClass.Connection ConnectionReaderWriter
SEVERE: null
java.io.NotSerializableException: org.json.JSONObject
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at SupportingClass.Connection.ConnectionReaderWriter(Connection.java:74)
at SupportingClass.Connection.run(Connection.java:40)

请告诉我此代码中的问题或此方法的替代方法。

4

3 回答 3

0

我会给出答案:

替换out.writeObject(data);out.write(data.toString().getBytes());

您正在尝试编写JSONObject对象,并且该方法将尝试序列化该对象,但由于该类未实现 Serializable writeObject(),它将失败。JSONObject

于 2014-01-20T08:00:00.460 回答
0

JSON 是文本,因此不能使用 ObjectOutputStream。POST 方法使用内容的第一行作为参数,因此在实际内容之前需要一个空行:

    OutputStream stream = connection.getOutputStream();
    stream.write('\r');
    stream.write('\n');
    out = new OutputStreamWriter(stream, "UTF-8");
    out.write(data.toString());
    out.flush();
    out.close();

编辑:实际上我们需要 CR LF,所以 println() 可能不起作用。

于 2014-01-20T08:10:35.813 回答
0

如果你觉得原生使用很尴尬HttpURLConnection,你可以使用抽象库。那里有很多强大的。其中之一是DavidWebb。您可以在该页面的末尾找到一长串备选方案。

使用此库,您的代码将更短且更具可读性:

JSONObject nameAndPassword = new JSONObject();
// set name and password

Webb webb = Webb.create();
JSONObject result = webb.post("your_serverUrl")
        .header("api_key", "123456")
        .useCaches(false)
        .body(nameAndPassword)
        .ensureSuccess()
        .asJsonObject()
        .getBody();

该代码仅显示将在您run()的 Thread 方法中运行的部分。不需要设置Content-Type标题,因为这是通过检测您设置为主体的对象类型自动完成的。Accept标题也是如此。

我假设您从 REST 服务收到一个 JSON 对象,因为您将“Accept”标头设置为“application/json”。为了接收一个普通的字符串,可以写String result = ... .asString().getBody().

顺便说一句,该库是在考虑 Android 的情况下开发的,但它也可以与 Swing 或服务器端一起使用。也许您选择另一个库(例如 Jersey Client),因为您对大小没有限制。DavidWebb 重约 20 KB,而大多数其他库为您的部署工件增加了数百 KB。

另一件事:你使用JSONObject. 对于小型 Web 服务,这不是问题,但是如果您必须编组许多和/或大对象,您可以考虑使用 JAXB + JacksonGson。更少的代码,更少的错误,更多的乐趣!

于 2014-01-20T08:56:11.050 回答