xstream - correct way to save XML in UTF-8

10,972

Look at this code:

outputStream = new FileOutputStream(file);
writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
xStream.toXML(object, outputStream);

You're creating a writer which will use UTF-8 - but then completely ignoring it!

Try this instead:

xStream.toXML(object, writer);

Also as a matter of style, I'd encourage you to consider the following:

  • Don't compare results with Boolean constants; just use if (foo) or if (!foo) instead
  • Catching Exception is very rarely a good idea; catch specific exceptions instead
  • Returning a Boolean value to indicate success or failure isn't idiomatic Java; generally if something fails, an exception is better
  • If the first close fails, you're quitting the method before the second close call, which probably isn't what you want. (In fact, closing the OutputStreamWriter` will close the stream anyway, but consider the principle of the thing.)
  • Setting local variables to null at the end of a method is unnecessary and clutters up your code
Share:
10,972
Lumii
Author by

Lumii

WeNote - Notes, To-do lists, Reminders & Calendar JStock Android JStock - Free Stock Market Software WeFocus - Focus, Pomodoro, Do one thing at a time

Updated on June 30, 2022

Comments

  • Lumii
    Lumii almost 2 years

    Previously, to read XML in UTF-8 encoding through xstream, I am using DomDriver as follow :

    XStream xStream = new XStream(new DomDriver("UTF-8"));
    

    However, later I realize this is VERY slow. I use the following way :

    Optimize loading speed of xstream

    This works fine at least.

    However, later, I realize the same technique cannot be applied to write XML. I will get all ??? characters.

    This is the last workable code using DomDriver during write

    public static boolean toXML(Object object, File file) {
        XStream xStream = new XStream(new DomDriver("UTF-8"));
        OutputStream outputStream = null;
    
        try {
            outputStream = new FileOutputStream(file);
            xStream.toXML(object, outputStream);
        }
        catch (Exception exp) {
            log.error(null, exp);
            return false;
        }
        finally {
            if (false == close(outputStream)) {
                return false;
            }
            outputStream = null;
        }
    
        return true;
    }
    

    The above code works fine. In order to match with the read method which doesn't use DomDriver, I change the code to

    public static boolean toXML(Object object, File file) {
        XStream xStream = new XStream();
        OutputStream outputStream = null;
        Writer writer = null;
    
        try {
            outputStream = new FileOutputStream(file);
            writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
            xStream.toXML(object, outputStream);
        }
        catch (Exception exp) {
            log.error(null, exp);
            return false;
        }
        finally {
            if (false == close(writer)) {
                return false;
            }
            if (false == close(outputStream)) {
                return false;
            }
            writer = null;
            outputStream = null;
        }
    
        return true;
    }
    

    This time, all my Chinese characters changes to ???

    May I know anything I had done wrong?