• 周五. 12月 2nd, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Using springboot to read and write the front interface of server XML file

[db:作者]

1月 6, 2022

brief introduction

Usually when we modify the configuration file of a service , You need to log in to the server , Go to the specified directory and edit the configuration file, such as xml Make changes , It’s OK to operate once in a while , But frequent operation is a bit of a hassle .
So we directly put this function into the front-end interface to operate , To improve the efficiency of operation and maintenance .

Ideas

  1. Backend pass I/O To connect the server XML The file is read and sent to the front end
  2. The front end receives back xml The file is on the front end web Rendering in the editor
  3. The front end will change the xml The file is sent back to the back end again
  4. The back end sends back the received xml Write back the server configuration file

image.png

rely on

1.springBoot
2.dom4j(xml Read and write library )
3.vue-element-admin
4.ace.js(web Editor )

Realization

Back end

Import dependence

<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>

stay resources New under the directory hdfs-site.xml, And write the following to test

test demo The middle path is dead , Later, it can be changed to dynamic configuration

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<!-- Appoint HDFS Number of copies -->
<property>
<name>dfs.replication</name>
<value>1.2</value>
</property>
<!-- Appoint Hadoop Secondary name node host configuration -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>java151:50090</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
</configuration>

newly build XmlUtil Tool class

import org.dom4j.*;
import org.dom4j.io.*;
import java.io.*;
public class XmlUtil {
/**
* obtain xml file
*/
public static Document getDocument(String filename) {
File xmlFile = new File(filename);
Document document = null;
if (xmlFile.exists()) {
try {
SAXReader saxReader = new SAXReader();
document = saxReader.read(xmlFile);
} catch (Exception e) {
e.printStackTrace();
}
}
return document;
}
/**
* write in xml node , New if not , Existence covers
*/
public static void coverElement(String filePath, Document document) throws Exception {
if (document != null) {
OutputFormat format = OutputFormat.createPrettyPrint();
File xmlFile = new File(filePath);
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream(xmlFile), format);
writer.write(document);
writer.close();
}
}
}

newly build getXmlFile Interface , With the help of dom4j Of asXML() take xml With character string Form back to the front end ,Result Class can be implemented according to the project return requirements

@ApiOperation(value = " obtain xml file ", notes = " obtain xml file ")
@GetMapping(value = "/getXmlFile")
public Object getXmlFile(HttpServletRequest request, HttpServletResponse response) throws Exception {
String filePath = "src/main/resources/hdfs-site.xml";
Document document = XmlUtil.getDocument(filePath);
String docXmlText = document.asXML();// Output xml character string
return new Result(true, 20000, " obtain hdfs-site.xml success ", docXmlText);
}

newly build putXmlFile Interface , With the help of DocumentHelper.parseText Convert the string returned by the front end to xml

@ApiOperation(value = " modify xml file ", notes = " modify xml file ")
@ResponseBody()
@PostMapping(value = "/putXmlFile")
public Object putXmlFile(@RequestBody XmlDO body, HttpServletResponse response) throws Exception {
Document document = DocumentHelper.parseText(body.getData());// String rotation xml
String filePath = "src/main/resources/hdfs-site.xml";
XmlUtil.coverElement(filePath, document);
return new Result(true, 20000, " modify hdfs-site.xml success ", body.getData());
}

XmlDO

import lombok.Data;
@Data
public class XmlDO {
private String type;
private String data;
}

front end

Plugins depend on

"xml-formatter": "^2.4.0"
"lodash": "^4.17.20",

stay api New under the directory xml.js Interface ,url According to their own actual situation can be modified

import request from '@/utils/request'
export function getXmlFile() {
return request({
url: '/api/test/getXmlFile',
method: 'get'
})
}
export function putXmlFile(data) {
return request({
url: '/api/test/putXmlFile',
method: 'post',
data
})
}

Import ace.js, Including the theme and the language
public/index.html write in

//css
<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/ace/1.4.9/theme-xcode.css">
//js
<script src="https://cdn.bootcdn.net/ajax/libs/ace/1.4.9/ace.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/ace/1.4.9/ext-beautify.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/ace/1.4.9/ext-language_tools.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/ace/1.4.9/theme-xcode.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/ace/1.4.9/mode-xml.js"></script>

New editor component src/components/codeEditor/index.vue, lodash Depend on oneself isntall

<template>
<div :id="Id" ref="editor" :style="{ 'max-height': height }" class="ace-editor" />
</template>
<script>
import uniqueId from 'lodash/uniqueId'
export default {
name: 'AceEditor',
props: {
value: {
type: String,
default: ''
},
height: {
type: String,
default: '300px'
},
readOnly: {
type: Boolean,
default: false
},
mode: {
type: String,
default: 'json'
}
},
data() {
this.editor = null
this.Id = uniqueId('aceEditor')
return {
annot: []
}
},
computed: {
code: {
// Data update notifies the parent component to update data
set(val) {
this.$emit('input', val)
},
get() {
return this.value
}
}
},
watch: {
code() {
// Data changes in the parent component , Synchronize to ace Editor
// aceEditor.setValue After calling, all text content will be selected by default , Special handling of the cursor is required
// Cache cursor position
const position = this.editor.getCursorPosition()
this.syncData()
this.editor.clearSelection()
this.editor.moveCursorToPosition(position)
},
mode(mode) {
this.changeMode(mode)
},
readOnly(b) {
this.setReadOnly(b)
}
},
mounted() {
this.initEditor()
},
methods: {
initEditor() {
// eslint-disable-next-line no-undef
this.editor = ace.edit(this.Id)
this.editor.setTheme('ace/theme/xcode')
// Synchronize data while editing
this.editor.session.on('change', () => {
this.code = this.editor.getValue()
})
this.editor.getSession().on('changeAnnotation', () => {
this.annot = this.editor.getSession().getAnnotations()
this.$emit('annot', this.annot)
for (var key in this.annot) {
// eslint-disable-next-line no-prototype-builtins
if (this.annot.hasOwnProperty(key)) { console.log(this.annot[key].text + 'on line ' + ' ' + this.annot[key].row) }
}
})
// font size
this.editor.setFontSize(14)
this.syncData()
this.syncOptions()
},
changeMode(modeName) {
const mode = {
yaml: 'ace/mode/yaml',
json: 'ace/mode/json',
xml: 'ace/mode/xml',
javascript: 'ace/mode/javascript'
}
this.editor.session.setMode(mode[modeName])
},
setReadOnly(readOnly) {
this.editor.setReadOnly(readOnly)
},
syncOptions() {
this.setReadOnly(this.readOnly)
this.changeMode(this.mode)
},
syncData() {
this.editor.setValue(this.code)
}
}
}
</script>
<style scoped>
.ace-editor {
position: relative;
height: 800px;
border: 1px solid #ccc;
border-radius: 2px;
}
.ace-editor /deep/ .ace_print-margin {
display: none;
}
</style>

New page src/views/xmlTest/index.vue

<template>
<div id="contain">
<div>
<div id="select">
<h3> Modify the configuration file (xml)</h3>
<el-button type="primary" @click="testApi"> modify </el-button>
</div>
<aceEditor
v-model="resquestCode"
height="800px"
mode="xml"
@annot="annot"
/>
</div>
</div>
</template>
<script>
import { getXmlFile, putXmlFile } from '@/api/xml'
import aceEditor from '@/components/codeEditor'
export default {
name: '',
components: { aceEditor },
props: {},
data() {
return {
errcode: [],
resquestCode: ``
}
},
watch: {
},
mounted() {
this.getXml()
},
methods: {
isError() {
if (this.errcode.length > 0) {
this.$message.error(` Code No. ${this.errcode[0].row + 1} Line syntax error ,${this.errcode[0].text}`)
return true
}
return false
},
testApi() {
if (!this.isError()) {
this.format()
this.select()
}
},
getXml() {
getXmlFile().then(res => {
console.log('res: ', res)
this.resquestCode = res.data || ''
this.format()
})
},
annot(e) {
this.errcode = e
},
format() {
var format = require('xml-formatter')
this.resquestCode = format(this.resquestCode, {
collapseContent: true
})
},
select() {
putXmlFile({ data: this.resquestCode }).then(res => {
console.log('res: ', res)
this.$message.success(' Modification successful ')
})
}
}
}
</script>
<style lang="scss">
#contain {
margin: 0 20px;
display: block !important;
#select {
.el-select .el-input {
width: 100px;
}
.input-with-select .el-input-group__prepend {
background-color: #fff;
}
}
}
#editor {
width: 100%;
height: 300px;
}
</style>

Add routing configuration

 {
path: '/xml',
component: Layout,
children: [
{
path: '',
name: 'xml',
component: () => import('@/views/xmlTest/index'),
meta: { title: 'xml', icon: 'xml' }
}
]
}

Interface

image.png

image.png

More questions are welcome to join the front end communication group 749539640

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注