免责声明-我是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
那你就不会犯这个错误了。我相信这就是我在做的,但显然不是。
我复习过这样或这样的答案,但都没用。
暂无答案!
目前还没有任何答案,快来回答吧!