0
点赞
收藏
分享

微信扫一扫

java读写xml文件

java读写xml文件

背景
为什么要使用java读写xml呢?存储文件难道不是用数据库吗?俗话说存在即合理。在一些简单的项目中,比如小公司的展示页面,几乎没有数据需要存储,注意——是几乎没有,而不是没有,像站长统计(就是统计一下有多少人访问了我的网站),就一个数据你也搭建一个数据库?我只能说你任性,服务器可是需要money的,能省一点是一点,这年头地主家也没有余量啊!
为了简单而又能把问题搞清楚,建一个web工程
​所需jar:dom4j-1.6.1下载路径
先看一下目录结构:
java读写xml文件_读取xml
一、建一个index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>站长统计</title>
</head>

<body>
<!-- 从xml读取的信息显示在这里 -->
访问人数 :<%=session.getAttribute("countNum")%><br>
</body>
</html>

二、在src目录下建一个xml文件,名称随意,你开心就好

java读写xml文件_java_02

xml里面的内容能简单就简单
count就是访问人数

<?xml version="1.0" encoding="UTF-8"?>
<users>
<count>0</count>
</users>

三、接下来就是核心步骤——读取xml文件并对其进行读写操作
你可以建一个工具类,我的叫DealXML.java

package com.hulang.test;

import java.io.File;
import java.io.FileWriter;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 简单的分析之后我觉得这个类应该这么写<br><br>
* 包含一个加载xml的方法<br><br>
* 一个读取我们所需数据的方法<br><br>
* 一个写入数据方法<br><br>
* @author Administrator
*
*/
public class DealXML {

/**
* 加载xml文件 返回document对象<p>
* 因为后续的操作我们都可以根据document对象获取根节点
* @return Element
* @throws DocumentException
*/
public Document loadXML() throws DocumentException{
//创建一个SAXReader对象
SAXReader saxReader = new SAXReader();
String filepath = this.getClass().getResource("/countuser.xml").getPath();
//根据指定的路径创建file对象
File xmlFile=new File(filepath);
//获取document对象,如果文档无节点,则会抛出Exception提前结束
Document document=saxReader.read(xmlFile);
return document;
}
/**
* 读取xml里面的数据
* @return
*/
public int getUserNum(){
Document document = null;
try {
document = loadXML();
} catch (DocumentException e) {
e.printStackTrace();
}
Element root = null;
//获取根节点
root = document.getRootElement();
//通过根节点获取我们所需要的<count>10</count> 节点元素
Element memberElm=root.element("count");
//然后把里面的值取出来并返回
return Integer.parseInt(memberElm.getText());
}
/**
* 往xml里面写数据
* @param num
*/
public void setUserNum(int num){
Element root = null;
Document document = null;
try {
document = loadXML();
} catch (DocumentException e) {
e.printStackTrace();
}
root = document.getRootElement();
Element memberElm=root.element("count");
memberElm.setText(num+"");
/**
* 程序运行到此时 ,我们只是在内存中改变的了count的值<p>
* 在xml文件中的值仍旧没有改变
*/
//所以我们要把修改的数据写回文件
writeToXml(document);
}
/**
* 执行setUserNum(int num)方法后,count的值
* 在Document对象中是改变了的,我们要做到事情就是
* 把改变的值覆盖原文件的值
* @param document
*/
private void writeToXml(Document document) {
String filepath = this.getClass().getResource("/countuser.xml").getPath();
try {
/** 将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(filepath)));
writer.write(document);
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

写到这里有个问题还是挺纠结的——读取文件时的路径问题
我这里是这样写的

String filepath = this.getClass().getResource("/countuser.xml").getPath();

这段代码的说道说道:this.getClass()我们都知道得到是是该类运行时的对象this.getClass().getResource(String filepath)这个就有点费劲了;你说我是该写绝对路径还是相对路径?是用“.还是用“/”一脸懵逼,很久不看源码的我这回竟然手贱按了一下F3
java读写xml文件_数据_03
半天没缓过神来,吓得我赶紧翻开了英汉大辞典(百度翻译),明白了它大概说的是:首先这个方法是查找带有给定名称的资源滴;然后如果查找与给定类相关的资源,则它的规则是通过定义类的 class loader 实现滴,并且此方法委托给此对象的类加载器;如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResource(java.lang.String)
在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:
如果 name 以 ‘/’ (‘\u002f’) 开始,则绝对资源名是 ‘/’ 后面的 name 的一部分。
否则,绝对名具有以下形式:modified_package_name/name(也就是包名/文件名),其中 modified_package_name 是此对象的包名,该名用 ‘/’ 取代了 ‘.’
很明显,我们这里用的是ClassLoader.getSystemResource(java.lang.String)
我们打印一下xml文件的路径:
/E:/Workspaces/JavaDealXML/WebRoot/WEB-INF/classes/countuser.xml
这个就是xml在服务器的绝对位置
反正是对了,就这么着把,以后再慢慢深究
四、现在xml可以读取了,里面的元素也可以操作了,剩余的事情就是放到页面上去,想了一个不是很好的办法,建一个Servlet,在Servlet完成人数的读取和写入,为了让Servlet和我的首页面index.jsp搭上关系,我们在web.xml配置Servlet的时候把绑定为index.jsp上源码:

package com.hulang.test;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class getUserNunServlet extends HttpServlet {

/**
* Constructor of the object.
*/
public getUserNunServlet() {
super();
}

/**
* 注销时写入人数 <br>
*/
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
}


public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DealXML dealXML = new DealXML();
//读取当前人数
int num = dealXML.getUserNum();
//页面显示人数
request.getSession().setAttribute("countNum", num+1);
//加一写回文件
dealXML.setUserNum(num+1);
//为了避免循环 随便重定向到一个页面,这个页面随便整点啥
request.getRequestDispatcher("index1.jsp").forward(request,response);
}
/**
* @throws ServletException if an error occurs
*/
public void init() throws ServletException {
}

}

getUserNunServlet在web.xml里面的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>getUserNunServlet</servlet-name>
<servlet-class>com.hulang.test.getUserNunServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getUserNunServlet</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

</web-app>

结果出炉:
java读写xml文件_数据_04

就这样,有疑问群里找我:511906138


举报

相关推荐

0 条评论