7

私が持っているとしましょう

class Student
{
String name;
int    age;
String teacher;
}

それで :

public class App1
{
    public static void main(String[] args)
    {
        Student st = new Student();
        st.setName("toto");

        XStream xs = new XStream();

        xs.alias("student",Student.class);

        System.out.println(xs.toXML(st));
    }

}

私に与える:

<student>
  <name>toto</name>
  <age>0</age>
</student>

null値を処理する方法はありますか?つまり :

<student>
  <name>toto</name>
  <age>0</age>
  <teacher></teacher>
</student>

私がやればそれは可能です

st.setTeacher("");

ただし、教師がnullの場合はそうではありません。

カスタムコンバーターを試してみましたが、null値がコンバーターに送信されていないようです。

4

3 に答える 3

3

XStream 1.4.7、カスタム フィールド名に @XStreamAlias アノテーション、カスタム コンバーターに @XStreamConverter (日付やその他のカスタム Bean を表すため) を使用しています。ただし、null 値のカスタム コンバーターは呼び出されませんでした。私の目標は、null フィールドを含むオブジェクトのすべてのフィールドをシリアル化することでした。XML を非整列化する必要はありませんでした。

カスタム ReflectionConverter を作成することで、なんとかそれを行うことができました。XStream ライブラリから ReflectionConverter を拡張し、doMarshal メソッドをオーバーライドしました。私が変更した唯一のことは、null info.values に対して writeField メソッドを呼び出すことでした。

new Object() {
{
    for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) {
        FieldInfo info = (FieldInfo) fieldIter.next();
        if (info.value != null) {
            //leave the code unchanged
            ...
        } else {
            //add this to write null info.value to xml
            Log.info("MyCustomReflectionConverter -> serialize null field: " + info.fieldName);
            writeField(info.fieldName, null, info.type, info.definedIn, info.value);
        }
    }
    //... leave the rest of the code unchanged
}
};

その後、そのような xStream インスタンスを作成しました (コンバーターを非常に低い優先度で登録することが非常に重要です)。

StaxDriver driver = new StaxDriver(new NoNameCoder()) {
    @Override
    public StaxWriter createStaxWriter(XMLStreamWriter out) throws XMLStreamException {
        // the boolean parameter controls the production of XML declaration
        return createStaxWriter(out, false);
    }
};

XStream xStream = new XStream(driver);
xStream.autodetectAnnotations(true);//needed to process aliases
//register MyCustomReflectionConverter
MyCustomReflectionConverter reflectionConverter = new MyCustomReflectionConverter (xStream.getMapper(), new SunUnsafeReflectionProvider());
xStream.registerConverter(reflectionConverter, XStream.PRIORITY_VERY_LOW);

ここで彼のソリューションを提供してくれたMark Naboursに感謝します

それが役に立てば幸い。誰かがこれに対するより良い解決策を見つけましたか?

于 2015-06-05T13:16:36.867 に答える
1

まず、次のように、Studentクラスに getter メソッドと setter メソッドを提供します。

public class Student{
   String name;
   int age;
   String teacher;
   public void setName(String name){
       this.name = name;
   }
   public String getName(){
      return name;
   }
.......
......//Like that mention other getter and setter method
}

これで、次のようにコンバーター クラスを作成する必要があります。

public class StudentConverter implements Converter{
    public boolean canConvert(Class clazz) {
         return clazz.equals(Test.class);
    }
    public void marshal(Object value, HierarchicalStreamWriter writer,
         MarshallingContext context) {
       Student student = (Student ) value;
       writer.startNode("name");
       writer.setValue(test.getName());
       writer.endNode();
       writer.startNode("age");
       writer.setValue(test.getAge());
       writer.endNode();
       writer.startNode("teacher");
       writer.setValue("");
       writer.endNode();
   }
    public Object unmarshal(HierarchicalStreamReader reader,
         UnmarshallingContext context) {
       Student student = new Student();
       test.setName(reader.getNodeName());
       test.setAge(reader.getNodeName());
       test.setTeacher(reader.getNodeName());
       return student;
    }
}

Your main class will the like that:

public class App1{
    public static void main(String args[]) {
        XStream stream = new XStream(new StaxDriver());
        Student st = new Student();
        st.setName("ABC");
        t.setAge(21);
        stream.registerConverter(new StudentConverter());
        stream.alias("student", Student.class);
        System.out.println(stream.toXML(st));
   }

}

それがあなたの答えであることを願っています....幸せな学習:)

于 2015-02-18T07:25:24.097 に答える
0

空の文字列を入れることができます

String teacher = "";

または最適化されたもの:)

String teacher = StringUtils.EMPTY;
于 2016-06-17T10:16:40.717 に答える