【问题标题】:Java Swing Assigning a variable to a URLJava Swing 将变量分配给 URL
【发布时间】:2018-05-22 19:06:07
【问题描述】:

您好,我正在开发一个摇摆聊天应用程序,其中聊天历史存储在一个 xml 文件中。 在 NetBeans 项目中完成后,我能够获取 xml 文件并将其显示在表格中

但是当转换为 jar 文件时,我无法使用 xml 文件。 我尝试了各种方法,例如 getClass().getResource() 方法,但它检索的是 URL 而不是字符串,如果使用 toString() 方法转换为字符串,它不能用作有效路径来解析xml 文件。

下面是代码-->

ServerFrame.java

     public class ServerFrame extends javax.swing.JFrame {

        public String historyFile;
        public HistoryFrame historyFrame;
        public History hist;  }

        public ServerFrame() {
           historyFile=this.getClass().getResource("History.xml").toString();}


 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

            hist = new History(historyFile);               
            historyFrame = new HistoryFrame(hist);
            historyFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
            historyFrame.setLocation(this.getLocation());
            historyFrame.setVisible(true);          
    }     

History.java

public class History {

    public String filePath;

    public History(String filePath){

        this.filePath = filePath;
    }

    public void addMessage(Message msg, String time){

        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(filePath);

            Node data = doc.getFirstChild();

            Element message = doc.createElement("message");
            Element _sender = doc.createElement("sender"); _sender.setTextContent(msg.sender);
            Element _content = doc.createElement("content"); _content.setTextContent(msg.content);
            Element _recipient = doc.createElement("recipient"); _recipient.setTextContent(msg.recipient);
            Element _time = doc.createElement("time"); _time.setTextContent(time);

            message.appendChild(_sender); message.appendChild(_content); message.appendChild(_recipient); message.appendChild(_time);
            data.appendChild(message);

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(filePath));
            transformer.transform(source, result);

       } 
           catch(Exception ex){
        System.out.println("Exceptionmodify xml");
       }
    }

    public void FillTable(HistoryFrame frame){

        DefaultTableModel model = (DefaultTableModel) frame.jTable1.getModel();

        try{
            File fXmlFile = new File(filePath);
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);
            doc.getDocumentElement().normalize();

            NodeList nList = doc.getElementsByTagName("message");

            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node nNode = nList.item(temp);
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element eElement = (Element) nNode;
                    model.addRow(new Object[]{getTagValue("sender", eElement), getTagValue("content", eElement), getTagValue("recipient", eElement), getTagValue("time", eElement)});
                }
            }
        }
        catch(Exception ex){
            System.out.println("Filling Exception");
        }
    }

我已将 xml 文件放在项目目录的 src 文件夹中。问题似乎出在 docBuilder.parse() 中,因为每次在函数中生成异常并且它只接受字符串而不是 url,因为系统路径文件的路径与文件的 javapath 不同。

我只需要在执行期间以某种方式访问​​ jar 中的 xml 文件。访问是指jar文件中xml文件的正确文件路径,不需要文件内容。

【问题讨论】:

    标签: java xml swing netbeans jar


    【解决方案1】:

    问题出在这里:

    StreamResult result = new StreamResult(new File(filePath));
    

    您似乎已经知道,URL 不是文件路径,您不能将其视为一个文件路径。您根本无法做到new File(filePath) 并期望它永远工作。您存储在filePath 中的字符串根本不是文件路径,而是 URL。

    但是您有一个更根本的问题:资源是只读的。你不能写信给它,句号。所有 Java 应用程序都部署在 .jar 或 .war 文件中,即使您可以访问原始存档(并且不能保证您可以),您也可能无权编写它(尤其是在 Windows 中,它可能会被锁定),即使您可以编写它,应用程序也不会看到更改。

    简而言之,您不应该尝试写入资源。

    相反,将您的资源视为一组默认值,并选择一个可靠的位置(例如临时文件或用户主目录中的文件)来写入新数据:

    File resultFile = File.createTempFile("history", ".xml");
    StreamResult result = new StreamResult(resultFile);
    

    附注:总是通过日志语句、异常链接或至少调用 printStackTrace() 公开捕获的异常的堆栈跟踪。另外,不要捕获 java.lang.Exception;您不应该抑制 NullPointerException、IndexOutOfBoundsException、IllegalArgumentException 等程序员错误。相反,只捕获您需要捕获的异常:

    } catch (ParserConfigurationException | SAXException | IOException | TransformerException ex) {
    

    【讨论】:

    • 感谢您的信息从来不知道 jar 文件中的资源无法写入。所以你说的是在外面创建一个单独的文件和jar文件并访问它吗?现在,如果我在将此 jar 文件转换为 .exe 文件时这样做,它仍然能够访问该单独的文件吗?exe 文件是否能够访问该 xml 文件?
    • 是的,.exe 文件应该具有与从 .jar 或 IDE 运行的 Java 程序相同的权限。请注意,临时文件不能保证在程序的生命周期之外存在,因此如果您需要它们在运行中持久存在,您应该将它们放在用户主目录的后代中;究竟哪个目录是合适的取决于操作系统。
    • 现在明白了
    【解决方案2】:

    从 IDE 运行时,您实际上不会创建 jar 文件,因此您可以从目录结构中获取资源。打包应用程序时,您将创建 jar 文件,并且资源突然相对于 zip 文件。从这样的资源中读取是可能的,但不应该进行写入,因为它会改变你的包。

    您可能需要在 jar 位置之外配置一个特定位置,以便检索和写入 xml 文件。

    【讨论】:

    • 如果我这样做,当 jar 文件转换为可执行的 .exe 文件时,我是否仍然能够访问该 xml 文件?如果没有,你有什么建议?
    • 通常我不建议从 jar 文件中制作 exe。这将它限制在 Windows 中,并且 jar 可以在任何地方运行。但除此之外,是的,为什么不呢?只要您在应用程序中使其可配置,您始终可以从 jar 文件外部读取文件...
    • 那么xml文件只要能被原jar文件访问,转换后的exe文件就可以访问吗?我的意思是将 jar 转换为 exe 会改变访问 xml 文件的方式吗?我只是想确保转换为 exe 不会影响 xml 文件的访问。
    猜你喜欢
    • 1970-01-01
    • 2014-06-04
    • 2012-01-06
    • 2010-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多