I wan't to post a CSV file to a web service using the Jersey Client without having to buffer the csv content in memory.
So I started of with some code similar to this:
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);
I would like to avoid buffering the entire CSV content in memory before sending to the server, I am aware that I can send a File object using the client and jersey will deal with loading and sending the file, however in thi开发者_运维知识库s case the CSV content will be generated automatically so what I would really like to do is just simply write it to an OutputStream which goes directly to the server rather than into memory... is there a way I can do this using the Jersey client?
It seems Jersey doesn't support writing direct to the OutputStream however after much digging and merging of a few different thinks I learned along the way I managed to come up with this class.
Jersey supports passing an InputStream into the post method on WebResource which is read and the content written to the request body.
I am producing a CSV file from a ResultSet so I wrote a class that extends InputStream and when read() is called it gets a record from the ResultSet and builds a line of the CSV file and returns just one character from the line. Each time read() is called the next character is returned until the whole line is returned at which point the next record is read from the database and the process repeated until there are no records left.
I am using a library called OpenCSV to build the lines of the CSV file
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;
}
}
精彩评论