我不想使用Jersey客户端将CSV文件发布到Web服务,而无需在内存中缓冲csv内容。
所以我开始使用类似的代码:
String csvContent = [the buffered CSV content];
Client c = Client.create();
WebResource r = c.resouce("http://example.com/services/service");
r.type("text/csv").post(csvContent);
我想避免在发送到服务器之前缓冲内存中的整个CSV内容,我知道我可以使用客户端发送一个File对象,并且jersey将处理加载和发送文件,但是在这种情况下CSV内容将自动生成,所以我真正想做的只是简单地将它写入一个直接连接到服务器而不是内存的OutputStream ......我有可能使用Jersey客户端吗?
答案 0 :(得分:1)
看起来泽西岛并不支持直接向OutputStream写作,但经过多次挖掘和合并之后,我学到了很多东西,我设法提出了这个课程。
Jersey支持将InputStream传递给WebResource上的post方法,该方法被读取并且内容被写入请求主体。
我正在从ResultSet生成CSV文件,因此我编写了一个扩展InputStream的类,当调用read()时,它从ResultSet获取一条记录并构建一行CSV文件并从该行返回一个字符。每次调用read()时,都会返回下一个字符,直到返回整行,此时从数据库中读取下一条记录并重复该过程,直到没有记录为止。
我正在使用名为OpenCSV的库来构建CSV文件的行
public class ResultSetCsvInputStream extends InputStream {
private ResultSet rs;
private int columns;
private int ch;
private byte[] line;
/**
* Construct a new SchemaInputStream
* @param rs
* @throws SQLException
*/
public ResultSetCsvInputStream(ResultSet rs) throws SQLException {
this.rs = rs;
// write column names
ResultSetMetaData meta = rs.getMetaData();
columns = meta.getColumnCount();
String[] colNames = new String[columns];
for(int i = 0; i < colNames.length; i++) {
colNames[i] = meta.getColumnName(i+1);
}
writeLine(colNames);
}
private void writeLine(String[] ln) {
StringWriter strWriter = new StringWriter();
CSVWriter csv = new CSVWriter(strWriter);
csv.writeNext(ln);
line = strWriter.toString().getBytes(Charset.forName("UTF8"));
ch = 0;
}
@Override
public int read() throws IOException {
if(rs == null)
return -1;
// read the next line
if(line == null || ch >= line.length) {
// query next line
try {
if(rs.next()) {
String[] record = new String[columns];
for(int i = 0; i < record.length; i++) {
record[i] = rs.getString(i+1);
}
writeLine(record);
}
else {
rs = null;
return -1;
}
} catch (SQLException e) {
throw new IOException(e);
}
}
// read next character
return line[ch++] & 0xFF;
}
}