连接—如何在保持httpurlconnection活动的同时避免java.net.protocole异常

y1aodyip  于 2021-07-06  发布在  Java
关注(0)|答案(0)|浏览(218)

免责声明-我是java和网络新手
我想用httpurlconnection创建一个post请求。
因为我将进行许多这样的查询,所以我决定将连接创建为一个singleton(类 ModelServerConn ),这样我就可以打开它一次,而不必关闭它。

public class ModelServerConn {
    HttpURLConnection conn;
    private static final ModelServerConn instance = new ModelServerConn();

    //private constructor to avoid client applications to use constructor
    private ModelServerConn(){
        this.conn = setupConn();
    }

    public static ModelServerConn getInstance(){
        return instance;
    }

    private HttpURLConnection setupConn() {
        try {
            return setupConn(HttpServerDetails.getItfAddr());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static HttpURLConnection setupConn(String addr) throws IOException {

        URL url = new URL(addr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);
        return conn;
    }
}

接下来,我编写了一个类,它将使用这个打开的连接来查询服务器。

public class HttpServerQuery {

    private static String decodeMessage(HttpURLConnection conn) throws IOException  {
        InputStream in = conn.getInputStream();
        String encoding = conn.getContentEncoding();
        encoding = encoding == null ? "UTF-8" : encoding;
        String body = IOUtils.toString(in, encoding);
        return body;
    }

    private static String buildQuery(List<NameValuePair> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;

        for (NameValuePair pair : params)
        {
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
        }
        return result.toString();
    }

    public static double executeQuery(List<NameValuePair> params) throws IOException  {

        // open connection / get existing connection
        ModelServerConn server = ModelServerConn.getInstance();
        HttpURLConnection conn = server.conn;

        // get output stream
        OutputStream os = conn.getOutputStream();

        // query server
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
        writer.write(buildQuery(params));
        writer.flush();
        writer.close();
        os.close();
        conn.connect();

        // get input stream and read
        String responseStr = decodeMessage(conn);
        String trimmedResponseStr = responseStr.substring(1, responseStr.length()-2);
        return Double.parseDouble(trimmedResponseStr);
    }
}

我可以这样查询:

List<NameValuePair> params1 = new ArrayList<NameValuePair>();
params1.add(new BasicNameValuePair("s", "glasses"));

System.out.println(HttpServerQuery.executeQuery(params1));

但在它开始工作后,当我再次运行它时,我得到一个 ProtocolException .

---------------------------------------------------------------------------
java.net.ProtocolException: Cannot write output after reading input.
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1371)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1350)
    at HttpServerQuery.executeQuery(#49:1)
    at .(#162:1)

为什么会这样?如何成功保持连接?
我的理解是如果你 openConnection -> getOutputStream -> write -> getInputStream -> read 那你就不会犯这个错误了。我相信这就是我在做的,但显然不是。
我复习过这样或这样的答案,但都没用。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题