本文代码依赖dom4j-1.6.1.jar
在修改xml过程中遇见utf-8第一次被修改之后,再次修改提示错误--org.dom4j.DocumentException: 2 字节的 UTF-8 序列的字节 2 无效。 Nested exception: 2 字节的 UTF-8 序列的字节 2 无效。
在网上找资料说需要将xml改成GBK,结果试了一下果然没有问题,但是项目需要使用utf-8所以不能将xml修改为GBK。
所以尝试调用SAXReader.read(),传入不同类型参数,最终BufferedReader可以解决此问题。具体代码如下
public static void changeSSOConfigure(String appkey,String appSecret,String codeUrl,String tokenUrl,String userUrl){
String path = ParamConfig.class.getResource("/").getPath().replace("classes/", "") + "config/ParamConfig_dbaudit.xml";
SAXReader sr = new SAXReader(); // 需要导入jar包:dom4j
sr.setEncoding("utf-8");//这里设置文件编码
// https://blog.csdn.net/nrsc272420199/article/details/77204188
try {
// FileInputStream in = new FileInputStream(new File(path));
// InputStreamReader reader = new InputStreamReader(in,"utf-8");
// Document document = sr.read(reader);
File file = new File(path);
Document document = sr.read(new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")));// 读取XML文件
// Document document = sr.read(path);
// 获取根元素
Element element = document.getRootElement();
@SuppressWarnings("unchecked")
List<Element> list = element.elements();
for (Element entryElement : list) {
String key = entryElement.attributeValue("key");
if(key.equals("nsfocus.cloud.app_key")){
entryElement.setText(appkey);
}else if(key.equals("nsfocus.cloud.app_secret")){
entryElement.setText(appSecret);
}else if(key.equals("nsfocus.cloud.auth.code.url")){
entryElement.setText(codeUrl);
}else if(key.equals("nsfocus.cloud.auth.token.url")){
entryElement.setText(tokenUrl);
}else if(key.equals("nsfocus.cloud.auth.user.url")){
entryElement.setText(userUrl);
}
}
saveDocument(document,new File(path));
} catch (DocumentException e) {
// 编码问题
// 你在eclipse里面新建一个xml文件
// 把这些复制进去可以解决这个问题
// 原因:
// 你如果是用UE、记事本等工具来写XML,虽然保存的编码是UTF-8,但是会在文件的第一行加入一些信息(具体是什么信息,我不清楚。应该是关于文件编码的信息),所以报第一行出错。
// 你可以用UE的二进制打开原文件和eclipse建的文件,看看二者的编码,应该在第一行是不同的。
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
System.out.println("修改前:APP_KEY:"+APP_KEY);
System.out.println("修改前:APP_SECRET:"+APP_SECRET);
System.out.println("修改前:AUTH_TOKEN_URL:"+AUTH_TOKEN_URL);
System.out.println("修改前:AUTH_CODE_URL:"+AUTH_CODE_URL);
System.out.println("修改前:AUTH_USER_URL:"+AUTH_USER_URL);
APP_KEY = appkey;
APP_SECRET = appSecret;
AUTH_TOKEN_URL = codeUrl;
AUTH_CODE_URL = tokenUrl;
AUTH_USER_URL = userUrl;
System.out.println("修改后:APP_KEY:"+APP_KEY);
System.out.println("修改后:APP_SECRET:"+APP_SECRET);
System.out.println("修改后:AUTH_TOKEN_URL:"+AUTH_TOKEN_URL);
System.out.println("修改后:AUTH_CODE_URL:"+AUTH_CODE_URL);
System.out.println("修改后:AUTH_USER_URL:"+AUTH_USER_URL);
}
}
其中主要代码就是
File file = new File(path);
Document document = sr.read(new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8")));// 读取XML文件
下面是保存xml代码
public static void saveDocument(Document document, File xmlFile) throws IOException {
// Writer osWrite = new OutputStreamWriter(new FileOutputStream(xmlFile));// 创建输出流
OutputFormat format = OutputFormat.createPrettyPrint(); // 获取输出的指定格式
format.setEncoding("UTF-8");// 设置编码 ,确保解析的xml为UTF-8格式
// XMLWriter writer = new XMLWriter(osWrite, format);// XMLWriter// 指定输出文件以及格式
XMLWriter writer = new XMLWriter(new FileOutputStream(xmlFile), format);
writer.write(document);// 把document写入xmlFile指定的文件(可以为被解析的文件或者新创建的文件)
writer.flush();
writer.close();
// osWrite.close();
}
主要就是用FileOutputStream并指定编码格式
OutputFormat format = OutputFormat.createPrettyPrint(); // 获取输出的指定格式
format.setEncoding("UTF-8");// 设置编码 ,确保解析的xml为UTF-8格式
XMLWriter writer = new XMLWriter(new FileOutputStream(xmlFile), format);
本来已经想当然的认为这是dom4j的bug,不支持对编码为utf-8的xml反复读写,故在此记录,留作后用!!!