我不太明白为什么显式构造 CSV 字符串(使用 StringBuilder)会比使用 JAXB 内置函数更昂贵。
如果性能是您的限制因素,那么我认为您应该考虑创建自定义序列化程序(例如基于 StringBuilder)和 SAX 处理程序来解析 XML。
如果您有幸更改协议,那么您可能想查看Grizzly framework、Avro 和Google ProtoBuf - 它们需要更多维护,但如果您追求性能,那么这些应该更快。
与往常一样,您应该使用这两种方法进行 A/B 性能测试,然后再将任何东西固定下来;)
回到原来的话题,下面是一个关于如何使用自定义适配器的例子:
import static org.junit.Assert.assertEquals;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.junit.Test;
public class Example
{
public String serialize( DataObject d ) throws JAXBException {
StringWriter buffer = new StringWriter();
JAXBContext.newInstance(DataObject.class).createMarshaller().marshal(d, buffer);
return buffer.toString();
}
@Test
public void testSerialize( ) throws JAXBException {
String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><dataObject>"
+ "<FirstField>field1 content with special characters &<>'\"</FirstField>"
+ "<Second><!CDATA[[ <!-- now we're just nasty --> ]]></Second>"
+ "<Custom>a,b,c</Custom></dataObject>";
assertEquals(expected, serialize(new DataObject()).replaceAll("(\r)?\n(\r)?", "\n"));
}
}
@XmlRootElement
@XmlAccessorType( XmlAccessType.FIELD )
class DataObject
{
@XmlElement( name = "FirstField" )
private final String field1 = "field1 content with special characters &<>'\"";
@XmlElement( name = "Second" )
private final String field2 = "<!CDATA[[ <!-- now we're just nasty --> ]]>";
@XmlElement( name = "Custom" )
@XmlJavaTypeAdapter( value = CustomAdapter.class )
// you can move this over the type
private final CustomType type = new CustomType("a", "b", "c");
}
@XmlAccessorType( XmlAccessType.FIELD )
class CustomType
{
private final String a;
private final String b;
private final String c;
public CustomType( String a, String b, String c ) {
this.a = a;
this.b = b;
this.c = c;
}
public String getA( ) {
return a;
}
public String getB( ) {
return b;
}
public String getC( ) {
return c;
}
}
class CustomAdapter extends XmlAdapter<String, CustomType>
{
@Override
public String marshal( CustomType v ) throws Exception {
return String.format("%s,%s,%s", v.getA(), v.getB(), v.getC());
}
@Override
/** Please don't use this in PROD :> */
public CustomType unmarshal( String v ) throws Exception {
String[] split = v.split(",");
return new CustomType(split[ 0 ], split[ 1 ], split[ 2 ]);
}
}
这应该会让你继续前进,除非我完全误解了你的问题。