0

I am using Spring framework, and use streamresolution to return a .txt file for user to download.

The result of data is fine, however, there is a 't' in front of every column of data, and besides the last column, there is a 'w' in the end of every column.

I can't not understand why because the data seems fine, and I didn't told the program to create the letter.

Here is my code:

// A list of String, which are the data, it might looks like 20200810,a,b,c,100,55,.....
// the whole is a String contains comma
List<String> dataList = (List<String>) parameters.get("myData");

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
StreamingResolution streamingResolution = null;

ObjectOutputStream oos = new ObjectOutputStream(outputStream);

oos.writeObject("\n");
for (String s : dataList) {
    oos.writeObject(s.trim());
    oos.writeUTF("\n");
}

streamingResolution = new StreamingResolution("text/plain", new ByteArrayInputStream(outputStream.toByteArray()));

streamingResolution.setCharacterEncoding(CharEncoding.UTF_8);
            
String year = Integer.toString((Integer.parseInt(end.substring(0, 4));
String day = year + end.substring(4, 6);

oos.close();

return streamingResolution.setFilename(day + ".txt");

while I download the data, 202108.txt it might looks like

t ?0210810,a,b,c,100,55w

t ?0210810,d,e,f,99,60

could anyone please tell me why there would be a 't' in the front and a 'w' in the end? And how to fix this?

Thanks a lot.

rubedo
  • 3
  • 2

1 Answers1

1

This code uses an ObjectOutputStream, which is used to write serialized Java data in a binary format. It is not a plain text format, and should not be used in this way. The extra characters are bytes that are defined in the Java Object Serialization Specification.

To write plain text, you can use the java.io.PrintStream class instead. For example:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(outputStream, false, StandardCharsets.UTF_8);

printStream.println();
for (String s : dataList) {
    printStream.println(s.trim());
}
printStream.flush();

StreamingResolution streamingResolution = new StreamingResolution("text/plain", new ByteArrayInputStream(outputStream.toByteArray()));

streamingResolution.setCharacterEncoding(CharEncoding.UTF_8);

Note that I also simplified the code by moving the streamingResolution local variable declaration to where it is assigned.

This is a straightforward translation of the code provided, to show you how to use the PrintStream class, however it may not be the best way to write it. The StreamingResolution class appears to be part of the Stripes Framework. It is intended for streaming large responses to the client. However, this implementation does not actually stream the response, it accumulates it into a byte array. A better way to implement this would be to subclass the StreamingResponse class, as described in the Stripe documentation, to write directly to the response:

return new StreamingResolution("text/plain") {
    public void stream(HttpServletResponse response) throws Exception {
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.println();
        for (String s : dataList) {
            out.println(s.trim());
        }
        out.flush();
    }
}.setFilename(day + ".txt");
Tim Moore
  • 8,958
  • 2
  • 23
  • 34
  • Thank you very much for your great answer. It did solved my problem, thanks. I have changed my code, and use PrintStream, the program worked fine, and the result is exactly what I want. Thanks. Only thing I change is that while I use new PrintStream, it said that the parameter should be (outputstream, boolean, string), so I wrote `PrintStream printStream = new PrintStream(outputStream, false, UTF-8);` The below code seems even more better, since I alread got one work code, I would like to try another. Thank you for your answer again. – rubedo Aug 10 '21 at 05:38
  • My pleasure. I'm glad it helped! I should have mentioned, the `PrintStream` constructor I used was introduced in Java 10. Using the version that takes a `String` is totally fine, too, and more backwards compatible. – Tim Moore Aug 10 '21 at 05:41
  • Oh, I see. I have tried both of the code, and they work very well. The streamingResponse seems to be faster than another. Thank you for the answer and the great example code. ^^ – rubedo Aug 11 '21 at 05:54