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
    }
}