我有一个设计问题。
我正在使用HttpURLConnection
课来浏览网站。为了获得HttpURLConnection
实例,我有一个本地 getter 方法。它负责设置所有请求属性,包括可能的cookie。无论如何,在整个应用程序的生命周期中,我使用了多个HttpURLConnection
个实例。并且从不有多个开放连接。
无论如何,我有另一种本地方法以 HTTP POST 的形式发送请求。这是代码:
private final InputStream sendRequest(final HttpURLConnection conn, final String content){
InputStream in = null;
DataOutputStream out = null;
try{
// Write data out to the stream
out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(content);
out.flush();
// Get the input stream
in = conn.getInputStream();
}
catch(IOException e){
e.printStackTrace();
}
finally{
try
{
if(out != null){
out.close();
}
}
catch(IOException e){
e.printStackTrace();
}
}
return in;
}
正如您所看到的,只要我写完内容,就会在连接上打开输入流并返回它。我这样做的原因是如果我不打开连接上的输入流,应用程序将挂起。因此,我将它留给调用者,以确定他们是否要解析传入的内容。此外,调用者需要连接实例,因为我将它留给他们断开连接(即关闭连接)。
所以,我想我的问题是,这是一个糟糕的设计吗?也就是说,打开调用者已有实例的连接对象的输入流然后返回它?
答案 0 :(得分:1)
遗憾的是你不能使用Apache HttpClient,但是一点OOP可以帮助你解开你的代码。
为调用者引入ResponseHandler
接口来实现。您可能还希望在public static
字段(如果是线程安全的)中提供一些开箱即用的实现,或者通过工厂方法提供常见情况,例如“给我一个字符串”(请务必查阅“ charset“创建Content-Encoding
时的响应的InputStreamReader
标题的一部分”和“给我一个字节[]”。
不要仅向InputStream
提供ResponseHandler
,因为您可能需要访问字符编码的响应标头等。
同样,对于HttpClient来说,这真的会好得多:/
(以下代码缺少对参数的基本完整性检查,请添加它们)
public interface ResponseHandler<T> {
T handleResponse(HttpURLConnection conn);
}
public <T> T sendRequest(final HttpURLConnection conn, final String content,
final ResponseHandler<T> handler)
throws IOException {
OutputStream out = null;
try {
out = conn.getOutputStream();
// uses platform encoding, might want to explicitly
// specify "UTF-8"
out.write(content.getBytes());
out.flush();
return handler.handleResponse(conn);
} finally {
// closing out omitted for brevity
}
}
编辑:如果您能够以某种方式设法摆脱调用代码中的HttpUrlConnection
,那就更好了。看看你是否可以获得URL的String
和参数的Map<String, Object>
,可以将其包含在HttpRequest
对象中。
答案 1 :(得分:0)
恕我直言,如果你的班级实际上用HTTP服务器处理全部 I / O并将HTTP响应主体(如果有的话)返回给调用者那么它是有意义的。
现在sendRequest
方法没什么用,因为调用者无论如何都必须处理HTTP和I / O细节