Java 返回调用者已有实例的对象的输入流
我有一个设计问题 我正在使用Java 返回调用者已有实例的对象的输入流,java,Java,我有一个设计问题 我正在使用HttpURLConnection类来浏览网站。为了获得一个HttpURLConnection实例,我有一个本地getter方法。这负责设置所有请求属性,包括可能的cookie。无论如何,在这个应用程序的整个生命周期中,我使用了多个HttpURLConnection实例。而且,决不存在多个打开的连接 无论如何,我还有另一种本地方法,用于以HTTP POST的形式发送请求。代码如下: private final InputStream sendRequest(final
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;
}
如您所见,一旦我写完内容,我就会在连接上打开一个输入流并返回它。我这样做的原因是,如果我不打开连接上的输入流,应用程序将挂起。因此,我将让调用者决定是否要解析传入内容。另外,调用方需要连接实例,因为我让他们自行断开连接(即关闭连接)
所以,我想我的问题是,这是一个糟糕的设计吗?也就是说,打开调用方已有实例的连接对象的输入流,然后返回它?好吧,如果您的类实际使用HTTP服务器处理了所有的I/O,并将HTTP响应体(如果有的话)返回给调用方,这将是有意义的。
现在,
sendRequest
方法没有多大用处,因为调用者无论如何都必须处理HTTP和I/O细节很遗憾你不被允许使用,但是一点OOP可能会帮助你理清代码
引入一个ResponseHandler
接口供调用方实现。您可能还希望在公共静态
字段中提供一些现成的实现(如果是线程安全的),或者通过工厂方法为常见情况提供一些现成的实现,例如“给我一个字符串”(在创建InputStreamReader
时,请确保参考响应的内容编码
标题的“字符集”部分)和“给我一个字节[]”
不要只将InputStream
提供给ResponseHandler
,因为您可能需要访问响应头以进行字符编码等
同样,使用HttpClient会更好:/
(以下代码缺少参数的基本健全性检查,请添加它们)
公共接口响应处理器{
T handleResponse(httpurl连接连接);
}
public T sendRequest(最终HttpURLConnection连接,最终字符串内容,
最终负责人(处理人)
抛出IOException{
OutputStream out=null;
试一试{
out=conn.getOutputStream();
//使用平台编码,可能需要显式
//指定“UTF-8”
out.write(content.getBytes());
out.flush();
返回处理程序。处理程序响应(conn);
}最后{
//为简洁起见省略了结束语
}
}
编辑:如果你能设法摆脱调用代码中的
HttpUrlConnection
,那就更好了。检查一下你是否能用String
来处理URL和Map
来处理参数,也许可以把它包装在HttpRequest
对象中。你可以切换到你需要的地方我们有单独的类来构建请求、执行请求和处理响应。这将避免传递多功能一体的类,即HttpURLConnection
。另外,不要printStackTrace()
,让sendRequest()
如果你不能在那里处理,就抛出IOException
。调用方必须处理IOException
,如果他要从InputStream
@PhilippReichart读取,那么无论如何,不幸的是,我不被允许使用Apache的HttpClient:/。关于IOException
,我想如果我是这样会更友好一些mply捕获到异常并在无法打开输入流的情况下返回null
。不允许是不好的:/仍然,抛出IOException
——调用方在读取时必须处理它,并且可能处于更好的位置来处理它。另外:sendRequest()中的代码更少
。另外,使用、log4j等正确记录异常,因为printStackTrace()
将切断长堆栈跟踪并使调试变得不必要的困难。这一点很好。我想我可以编写两种方法:1)发送请求,打开输入流,但不尝试解析;2)发送请求,打开输入流,将其解析为,比方说一个StringBuilder
,然后返回解析后的内容?我可以不明白为什么需要第一种方法。应该将处理网络部分的代码与处理业务逻辑的代码解耦。我建议扩展代码以处理HTTP事务,并发回一个封装回复的定义良好的对象。这样,处理HTTP的代码就完全与其他代码分离(与I/O和网络中的应用程序的其余部分一样)。呼叫者是否要关闭连接或其他内容应设置为配置参数。这是我的观点
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
}
}