您好我正在开发一个swing聊天应用程序,其中聊天记录存储在xml文件中。 我可以获取xml文件,并在NetBeans项目中完成后将其显示在表中
但是当转换为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文件放在Project目录的src文件夹中。问题似乎在docBuilder.parse()中,因为每次在函数中生成异常并且它只接受字符串而不是url,因为系统路径该文件与文件的javapath不同。
我只需要在执行期间访问jar中的xml文件。通过访问,我的意思是恰好在jar文件中的xml文件的文件路径,而不需要文件内容。
答案 0 :(得分: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) {
答案 1 :(得分:0)
从IDE运行时,您实际上不会创建jar文件,因此您可以从目录结构中获取资源。打包应用程序时,您将创建jar文件,资源突然相对于zip文件。从这样的资源中读取是可能的,但不应该写,因为它会改变你的包。
您可能需要的是在jar位置之外配置一个特定位置,用于检索和编写xml文件。