2013-10-23 26 views
1

我试图编组一个对象并在此之后替换一些invarvalid char。在这个过程中,完成的xml没有被生成。我只能在所有生成的文件中看到1024个字符。XML在编组后不会完全假脱机文件

package com.test; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.StringReader; 
import java.util.Scanner; 
import javax.xml.XMLConstants; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.transform.stream.StreamResult; 
import javax.xml.validation.Schema; 
import javax.xml.validation.SchemaFactory; 
import org.apache.log4j.Logger; 
import org.xml.sax.SAXException; 
import com.sun.xml.bind.marshaller.NamespacePrefixMapper; 

public class MessageParserComponent { 
    private static final Logger LOGGER = Logger.getLogger(MessageParserComponent.class); 

      public File marshalIXml(final Object obj, final String xsdSchema, 
     final String xmlFileName, final JAXBContext ctx) { 
     File xml = new File(xmlFileName); 

     try { 
      xml.createNewFile(); 
      Marshaller marshaller = null; 
      marshaller = ctx.createMarshaller(); 
      marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); 
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 
       Boolean.TRUE); 
      marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, 
       "http://www.db.com/tf " + xsdSchema); 
      marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", 
       new NamespacePrefixMapper() { 
        @Override 
        public String getPreferredPrefix(String arg0, String arg1, 
         boolean arg2) { 
         return "tf"; 
        } 
       }); 

      marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, 
       "http://www.db.com/tf " + xsdSchema); 
      marshaller.setSchema(getSchema(xsdSchema)); 
      marshaller.marshal(obj, new StreamResult(xml)); 
      xml = replaceInvalidChar('\u0007', '\n', xml); 
      xml = replaceInvalidString("ns2", "xsi", xml); 
     } catch (IOException e) { 
      LOGGER.error(e); 
     } catch (JAXBException e) { 
      LOGGER.error(e); 
     } catch (SAXException e) { 
      LOGGER.error(e); 
     } 
     return xml; 
    } 

    private Schema getSchema(String xsdSchema) throws SAXException { 
     SchemaFactory fact = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     Schema schema = fact.newSchema(this.getClass().getClassLoader() 
              .getResource(xsdSchema)); 
     return schema; 
    } 

    private static File replaceInvalidString(String Target, String Dest, 
     File Source) throws IOException { 
     String xml_string; 
     xml_string = new Scanner(Source).useDelimiter("\\Z").next(); 
     xml_string = xml_string.replace(Target, Dest); 
     FileOutputStream fi = new FileOutputStream(Source); 
     fi.write(xml_string.getBytes()); 
     return Source; 
    } 

    public static File replaceInvalidChar(char Target, char Dest, File Source) 
     throws IOException { 
     String xml_string; 
     xml_string = new Scanner(Source).useDelimiter("\\Z").next(); 
     xml_string = xml_string.replace(Target, Dest); 
     FileOutputStream fi = new FileOutputStream(Source); 
     fi.write(xml_string.getBytes()); 
     return Source; 
    } 
} 

是否有字符串替换有限制吗?
我是否以错误的方式创建文件?

注:在UNIX日志文件夹

我存储的文件我有Java 6中,JAXB 2.2

任何形式的帮助表示高度赞赏。

+0

也许新的Scanner(Source).useDelimiter(“\\ Z”)。next()只返回1024字节的数据。请编入ByteArrayInputStream,然后从其中创建String并调用replace()方法进行替换。然后将String保存到您的文件中。 –

+0

谢谢@Stanislav Mamontov,但我觉得它会扫描输入文件并复制到字符串中。无论如何,我会检查并回复你。 –

+0

在其他博客中看到了类似的问题,他说,因为使用“/ z”作为分隔符的单个阅读应该会读取所有内容,直到“输入结束”,因此很容易只做一次阅读并将其留在该处,如示例以上都列出了。 在大多数情况下没问题,但是我发现至少有一种情况,读到“输入结束”不读取整个输入 - 当输入是一个SequenceInputStream时,每个InputStreams都显示为单独的“自己输入的结束”。 –

回答

0

问题出在扫描仪上,它试图找到EOF并且没有假脱机整个文件。这在本地开发环境中不会发生。在UNIX服务器中,在我的应用程序部署的地方,“输入结束”是不同的,这导致了这个问题。

File f1 = new File(path); 
    StringBuilder f2 = new StringBuilder(); 
     Scanner scanner = new Scanner(f1).useDelimiter("\\Z"); 

     while (scanner.hasNext()) { 
      f2.append(scanner.next()); 

这完成了这个把戏。 与其他Buttered阅读器相比,我不知道扫描器(仅包含1024个字符)的性能部分。

提高性能的任何其他解决方案都非常受欢迎。

0

只需检查您是否使用jaxb注释正确注释了您的对象。 你为什么要设置Marshaller属性?你想使用外部模式来编组你的对象吗?你为什么不让jaxb处理所有这些事情(如果你的对象在同一个工作空间中可用)。

此示例程序可能对您有所帮助。 http://www.mkyong.com/java/jaxb-hello-world-example/

,并检查这对太..

JAXB Marshaller : StringWriter output has a truncated tag value 截断标签值

+0

我们需要为其他接口期望的每个元素设置自定义前缀,以设置编组器属性。现在谈到我们的问题,这不是因为编组人员,因为@Stanislav Mamontov说,在不同的环境中,扫描器将以不同的方式运行,导致完全生成的xml被截断为1024个字符。 –

0

当你打开一个FileOutputStream你负责收。您应该更改您的代码以包含close()呼叫。

FileOutputStream fi = new FileOutputStream(Source); 
    fi.write(xml_string.getBytes()); 
    fi.close(); 
+0

感谢您的提醒,我早先得到它,并已关闭流。 –

+0

这会解决主要问题吗? –

+0

@PavanSky - 应该。 –