使用jersey restful网络服务生成.csv文件

时间:2018-08-31 15:23:14

标签: csv jersey

我正在尝试生成一个.csv文件作为对宁静的Web服务的响应(使用Jersey)。到目前为止,我已经可以获取一个List<HashMap<String, String>>了,密钥应该是CSV标头,值应该是CSV数据。

我正在使用Jackson API进行CSV生成。
代码流为:

  1. 我从列表中List<HashMap<String, String>>的DAO类中获取数据是myArrList
    我的第一个疑问是在实际情况下提供这样的文件位置是否是个好主意?我还能怎么做?如何在不实际在本地系统中创建文件的情况下发送带有数据的文件?

    File file = new File( "C:/Users/.../Downloads/RadioObjectData.csv");
    Writer writer = null;
    ResponseBuilder response = null;
    Reader reader = null;
    
    //Copy List of Map Object into CSV format at specified File location.
    try
    {
         writer = new FileWriter( file, false);
         reader = new FileReader( file);
         csvWriter( myArrList, writer);
         // csvReader( reader);
         response = Response.ok( (Object)file);
         response.header( "Content-Disposition", "attachment; filename=\"RadioObjectData.csv\"");
         // return response.build();
    }
    catch (IOException e)
    {
         // TODO Auto-generated catch block
         e.printStackTrace();
    }
    //Read CSV format from specified File location and print on console..
    return response.build();
    

    现在,我将此List发送到csvWriter方法,以在系统中创建一个.csv文件,以便随后我可以将此相同文件发送为对Web服务的响应。这种方法好吗?)

    public static void csvWriter( List<HashMap<String, String>> listOfMap, Writer writer) throws IOException
    {
      CsvSchema schema = null;
      CsvSchema.Builder schemaBuilder = CsvSchema.builder();
      if (listOfMap != null && !listOfMap.isEmpty())
      {
         for (String col: listOfMap.get( 0).keySet())
         {
            schemaBuilder.addColumn( col);
         }
         schema = schemaBuilder.build().withLineSeparator( "\r").withHeader();
      }
      CsvMapper mapper = new CsvMapper();
      mapper.writer( schema).writeValues( writer).writeAll( listOfMap);
      writer.flush();
    }
    
  2. 现在将在给定位置的.csv驱动器中创建一个C文件。
    我希望将此CSV作为响应发送之前在 base64 中进行编码。

如何实现所有这些目标?

1 个答案:

答案 0 :(得分:0)

只需使用StreamingOutput作为Response实体。

interface StreamingOutput {
    void write(OutputStream out);
}

您只需实现此接口,并将其传递给Response.ok()方法。在这种情况下,您要做的只是将OutputStream包裹在OutputStreamWriter中,以便可以将其传递给CsvMapper.writeValues(Writer)方法。

StreamingOutput entity = new StreamingOutput() {
    @Override
    public void write(OutputStream out) {
        Writer writer = new BufferedWriter(
                new OutputStreamWriter(out, StandardCharsets.UTF_8));
        csvWriter(myArrList, writer);
        out.flush();
    }
};
return Response.ok(entity)
        .header(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"RadioObjectData.csv\"")
        .build();

这就是您所需要的。无需任何中间存储。

更新

如果要对CSV文件进行Base64编码,可以执行的操作是写入ByteArrayOutputStream,然后使用这些字节通过Base64类进行编码。编码后,只需将编码后的字节写入StreamingOutput OutputStream。这是一个例子。

StreamingOutput entity = new StreamingOutput() {
    @Override
    public void write(OutputStream out) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedWriter baosWriter = new BufferedWriter(
                new OutputStreamWriter(baos, StandardCharsets.UTF_8));

        csvWriter(myArrList, baosWriter);
        byte[] bytes = baos.toByteArray();
        byte[] base64Encoded = Base64.getEncoder().encode(bytes);

        out.write(base64Encoded);
        out.flush();
    }
};