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

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

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

  1. public class ModelServerConn {
  2. HttpURLConnection conn;
  3. private static final ModelServerConn instance = new ModelServerConn();
  4. //private constructor to avoid client applications to use constructor
  5. private ModelServerConn(){
  6. this.conn = setupConn();
  7. }
  8. public static ModelServerConn getInstance(){
  9. return instance;
  10. }
  11. private HttpURLConnection setupConn() {
  12. try {
  13. return setupConn(HttpServerDetails.getItfAddr());
  14. } catch (MalformedURLException e) {
  15. e.printStackTrace();
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. return null;
  20. }
  21. private static HttpURLConnection setupConn(String addr) throws IOException {
  22. URL url = new URL(addr);
  23. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  24. conn.setReadTimeout(10000);
  25. conn.setConnectTimeout(15000);
  26. conn.setRequestMethod("POST");
  27. conn.setDoInput(true);
  28. conn.setDoOutput(true);
  29. return conn;
  30. }
  31. }

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

  1. public class HttpServerQuery {
  2. private static String decodeMessage(HttpURLConnection conn) throws IOException {
  3. InputStream in = conn.getInputStream();
  4. String encoding = conn.getContentEncoding();
  5. encoding = encoding == null ? "UTF-8" : encoding;
  6. String body = IOUtils.toString(in, encoding);
  7. return body;
  8. }
  9. private static String buildQuery(List<NameValuePair> params) throws UnsupportedEncodingException {
  10. StringBuilder result = new StringBuilder();
  11. boolean first = true;
  12. for (NameValuePair pair : params)
  13. {
  14. if (first)
  15. first = false;
  16. else
  17. result.append("&");
  18. result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
  19. result.append("=");
  20. result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
  21. }
  22. return result.toString();
  23. }
  24. public static double executeQuery(List<NameValuePair> params) throws IOException {
  25. // open connection / get existing connection
  26. ModelServerConn server = ModelServerConn.getInstance();
  27. HttpURLConnection conn = server.conn;
  28. // get output stream
  29. OutputStream os = conn.getOutputStream();
  30. // query server
  31. BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
  32. writer.write(buildQuery(params));
  33. writer.flush();
  34. writer.close();
  35. os.close();
  36. conn.connect();
  37. // get input stream and read
  38. String responseStr = decodeMessage(conn);
  39. String trimmedResponseStr = responseStr.substring(1, responseStr.length()-2);
  40. return Double.parseDouble(trimmedResponseStr);
  41. }
  42. }

我可以这样查询:

  1. List<NameValuePair> params1 = new ArrayList<NameValuePair>();
  2. params1.add(new BasicNameValuePair("s", "glasses"));
  3. System.out.println(HttpServerQuery.executeQuery(params1));

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

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

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

暂无答案!

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

相关问题