Spring Boot+MVC实战指南
上QQ阅读APP看书,第一时间看更新

Spring框架内部大量使用反射与操作XML技术,以至于MyBatis也高度依赖这两种技术。掌握这两种技术有助于高效理解与学习Java EE框架。

本书的全部案例均在IntelliJ IDEA开发工具中进行测试,项目类型为Maven。

本节介绍反射技术的基本使用,创建maven-archetype-quickstart类型的Maven项目reflectTest。

创建实体类Userinfo,代码如下:

package com.ghy.www.entity;

public class Userinfo {

    private long id;
    private String username;
    private String password;

    public Userinfo() {
        System.out.println("public Userinfo()");
    }

    public Userinfo(long id) {
        super();
        this.id = id;
    }

    public Userinfo(long id, String username) {
        super();
        this.id = id;
        this.username = username;
    }

    public Userinfo(long id, String username, String password) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        System.out.println("public Userinfo(long id, String username, String password)");
        System.out.println(id + " " + username + " " + password);

    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void test() {
        System.out.println("public void test1()");
    }

    public void test(String address) {
        System.out.println("public void test2(String address) address=" + address);
    }

    public String test(int age) {
        System.out.println("public String test3(int age) age=" + age);
        return "我是返回值";
    }
}

创建实体类Userinfo2,代码如下:

package com.ghy.www.entity;

public class Userinfo2 {

    private long id;
    private String username;
    private String password;

    private Userinfo2() {
        System.out.println("public Userinfo()");
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

1.正常创建对象并调用方法

正常创建对象并调用方法的写法如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

public class Test1 {
    public static void main(String[] args) {
        Userinfo userinfo = new Userinfo();
        userinfo.setId(100);
        userinfo.setUsername("中国");
        userinfo.setPassword("中国人");

        System.out.println(userinfo.getId());
        System.out.println(userinfo.getUsername());
        System.out.println(userinfo.getPassword());
    }
}

但在某些情况下,预创建对象的类名以字符串的形式存储在XML文件中,比如Servlet技术中的web.xml文件部分的示例代码如下:

<servlet>
    <servlet-name>InsertUserinfo</servlet-name>
    <servlet-class>controller.InsertUserinfo</servlet-class>
</servlet>

Servlet对象就是由Tomcat读取这段XML配置代码并解析出“controller.InsertUserinfo”字符串,然后使用反射技术动态创建出InsertUserinfo 类的对象。可见反射技术无处不在,是学习框架技术非常重要的知识点。

下面我们来模拟一下Tomcat处理的过程。

在resources文件夹中创建文件createClassName.txt,内容如下:

com.ghy.www.entity.Userinfo

创建运行类Test2,代码如下:

package com.ghy.www.test1;

import java.io.IOException;
import java.io.InputStream;

public class Test2 {
    public static void main(String[] args) throws IOException {
        byte[] byteArray = new byte[1000];
        InputStream inputStream = Test2.class.getResourceAsStream("/createClassName.txt");
        int readLength = inputStream.read(byteArray);
        String createClassName = new String(byteArray, 0, readLength);
        System.out.println(createClassName);
        inputStream.close();
    }
}

程序运行结果如下:

com.ghy.www.entity.Userinfo

变量createClassName存储的就是类名“com.ghy.www.entity.Userinfo”字符串,这时如果使用图1-1所示的代码就是错误的,会出现编译错误,Java编译器根本不允许使用这种写法创建com.ghy.www.entity.Userinfo类的对象,但需求是必须把类名“com.ghy.www.entity.Userinfo”对应的对象创建出来,对于这种情况可以使用反射技术来解决。反射是在运行时获得对象信息的一种技术。

图片 1

图1-1 错误的代码

2.获得Class类的对象的方式

在使用反射技术之前,必须要获得某一个*.class类对应Class类的对象。

Class类封装了类的信息(属性、构造方法和方法等),而Class类的对象封装了具体的*.class类中的信息(属性、构造方法和方法等),有了这些信息,就相当于烹饪加工时有了制造食品的原料,就可以创建出类的对象。

有4种方式可以获得Class类的对象,代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

public class Test4 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class class1 = Userinfo.class;
        Class class2 = new Userinfo().getClass();
        Class class3 = Userinfo.class.getClassLoader().loadClass("com.ghy.www.entity.Userinfo");
        Class class4 = Class.forName("com.ghy.www.entity.Userinfo");
        System.out.println(class1.hashCode());
        System.out.println(class2.hashCode());
        System.out.println(class3.hashCode());
        System.out.println(class4.hashCode());
    }
}

程序运行结果如下:

public Userinfo()
460141958
460141958
460141958
460141958

从打印结果可以分析出,同一个*.class类对应的Class类的对象是同一个,单例的。

3.通过Class对象获得Field、Constructor和Method对象

一个*.class类包含Field、Constructor和Method信息,可以通过Class对象来获取这些信息。

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test5 {
    public static void main(String[] args) {
        Class userinfoClass = Userinfo.class;
        // 属性列表
 Field[] a = userinfoClass.getDeclaredFields();
        System.out.println(a.length);
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i].getName());
        }
        System.out.println();
        // 构造方法列表
 Constructor[] b = userinfoClass.getConstructors();
        System.out.println(b.length);
        System.out.println();
        // 方法列表
 Method[] c = userinfoClass.getDeclaredMethods();
        System.out.println(c.length);
        for (int i = 0; i < c.length; i++) {
            System.out.println(c[i].getName());
        }
    }
}

程序运行结果如下:

3
id
username
password

4

9
getId
test
test
test
getPassword
getUsername
setPassword
setId
setUsername

4.使用Class.newInstance()方法创建对象

方法Class.newInstance()调用的是无参构造方法。

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

public class Test6 {
    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        // 本实验不用new来创建对象,原理就是使用反射技术
 String newObjectName = "com.ghy.www.entity.Userinfo";
        Class class4 = Class.forName(newObjectName);
        // newInstance()开始创建对象
 Userinfo userinfo = (Userinfo) class4.newInstance();
        userinfo.setUsername("美国");
        System.out.println(userinfo.getUsername());
    }
}

程序运行结果如下:

public Userinfo()
美国

5.对Field进行赋值和取值

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

import java.lang.reflect.Field;

public class Test7 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
        String newObjectName = "com.ghy.www.entity.Userinfo";
        Class class4 = Class.forName(newObjectName);
        Userinfo userinfo = (Userinfo) class4.newInstance();

        String fieldName = "username";
        String fieldValue = "法国";
        Field fieldObject = userinfo.getClass().getDeclaredField(fieldName);
        System.out.println(fieldObject.getName());
        fieldObject.setAccessible(true);
        fieldObject.set(userinfo, fieldValue);
        System.out.println(userinfo.getUsername());
        System.out.println(fieldObject.get(userinfo));
    }
}

程序运行结果如下:

public Userinfo()
username
法国
法国

6.获得构造方法对应的Constructor对象及调用无参构造方法

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Test8 {
    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        String newObjectName = "com.ghy.www.entity.Userinfo";
        Class class4 = Class.forName(newObjectName);
        Constructor constructor1 = class4.getDeclaredConstructor();
        Userinfo userinfo1 = (Userinfo) constructor1.newInstance();
        Userinfo userinfo2 = (Userinfo) constructor1.newInstance();
        Userinfo userinfo3 = (Userinfo) constructor1.newInstance();
        System.out.println(userinfo1.hashCode());
        System.out.println(userinfo2.hashCode());
        System.out.println(userinfo3.hashCode());
    }
}

程序运行结果如下:

public Userinfo()
public Userinfo()
public Userinfo()
460141958
1163157884
1956725890

7.通过Constructor对象调用有参构造方法

示例代码如下:

package com.ghy.www.test1;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Test9 {
    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        String newObjectName = "com.ghy.www.entity.Userinfo";
        Class class4 = Class.forName(newObjectName);
        Constructor constructor = class4.getDeclaredConstructor(long.class, 
String.class, String.class);
        System.out.println(constructor.newInstance(11, "a1", "aa1").hashCode());
        System.out.println(constructor.newInstance(12, "a2", "aa2").hashCode());
        System.out.println(constructor.newInstance(13, "a3", "aa3").hashCode());
        System.out.println(constructor.newInstance(14, "a4", "aa4").hashCode());
    }
}

程序运行结果如下:

public Userinfo(long id, String username, String password)
11 a1 aa1
460141958
public Userinfo(long id, String username, String password)
12 a2 aa2
1163157884
public Userinfo(long id, String username, String password)
13 a3 aa3
1956725890
public Userinfo(long id, String username, String password)
14 a4 aa4
356573597

8.使用反射动态调用无参无返回值方法

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test10 {
    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        String newObjectName = "com.ghy.www.entity.Userinfo";
        Class class4 = Class.forName(newObjectName);
        Userinfo userinfo = (Userinfo) class4.newInstance();
        String methodName = "test";
        Method method = class4.getDeclaredMethod(methodName);
        System.out.println(method.getName());
        method.invoke(userinfo);
    }
}

程序运行结果如下:

public Userinfo()
test
public void test1()

9.使用反射动态调用有参无返回值方法

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test11 {
    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        String newObjectName = "com.ghy.www.entity.Userinfo";
        Class class4 = Class.forName(newObjectName);
        Userinfo userinfo = (Userinfo) class4.newInstance();
        String methodName = "test";
        Method method = class4.getDeclaredMethod(methodName, String.class);
        System.out.println(method.getName());
        method.invoke(userinfo, "我的地址在北京!");
    }
}

程序运行结果如下:

public Userinfo()
test
public void test2(String address) address=我的地址在北京!

10.使用反射动态调用有参有返回值方法

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.entity.Userinfo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test12 {
    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        String newObjectName = "com.ghy.www.entity.Userinfo";
        Class class4 = Class.forName(newObjectName);
        Userinfo userinfo = (Userinfo) class4.newInstance();
        String methodName = "test";
        Method method = class4.getDeclaredMethod(methodName, int.class);
        System.out.println(method.getName());
        Object returnValue = method.invoke(userinfo, 999999);
        System.out.println("returnValue=" + returnValue);
    }
}

程序运行结果如下:

public Userinfo()
test
public String test3(int age) age=999999
returnValue=我是返回值

11.反射破坏了OOP

创建单例模式,代码如下:

package com.ghy.www.objectfactory;

//单例模式
//保证当前进程中只有1个OneInstance类的对象
public class OneInstance {
    private static OneInstance oneInstance;

    private OneInstance() {
    }

    public static OneInstance getOneInstance() {
        if (oneInstance == null) {
            oneInstance = new OneInstance();
        }
        return oneInstance;
    }
}

由于构造方法是private(私有)的,因此不能new实例化对象,只能调用public static OneInstance getOneInstance()方法获得自身的对象,而且可以保证单例,测试代码如下:

package com.ghy.www.test1;

import com.ghy.www.objectfactory.OneInstance;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

public class Test13 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        OneInstance o1 = OneInstance.getOneInstance();
        OneInstance o2 = OneInstance.getOneInstance();
        OneInstance o3 = OneInstance.getOneInstance();
        System.out.println(o1);
        System.out.println(o2);
        System.out.println(o3);
    }
}

程序运行结果如下:

com.ghy.www.objectfactory.OneInstance@1b6d3586
com.ghy.www.objectfactory.OneInstance@1b6d3586
com.ghy.www.objectfactory.OneInstance@1b6d3586

但是,使用反射技术会破坏面向对象编程(OOP),导致创建多个OneInstance类的对象。

示例代码如下:

package com.ghy.www.test1;

import com.ghy.www.objectfactory.OneInstance;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Test14 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        Class classRef = Class.forName("com.ghy.www.objectfactory.OneInstance");
        Constructor c = classRef.getDeclaredConstructor();
        c.setAccessible(true);
        OneInstance one1 = (OneInstance) c.newInstance();
        OneInstance one2 = (OneInstance) c.newInstance();
        System.out.println(one1);
        System.out.println(one2);
    }
}

程序运行结果如下:

com.ghy.www.objectfactory.OneInstance@1b6d3586
com.ghy.www.objectfactory.OneInstance@4554617c

这里创建了两个OneInstance类的对象,没有保证单例性。虽然构造方法是private的,但依然借助反射技术创建了多个对象。

12.方法重载

使用反射可以调用重载方法。

示例代码如下:

package com.ghy.www.test1;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test15 {
    public void testMethod(String username) {
        System.out.println("public String testMethod(String username)");
        System.out.println(username);
    }

    public void testMethod(String username, String password) {
        System.out.println("public String testMethod(String username, String password)");
        System.out.println(username + " " + password);
    }

    public static void main(String[] args)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        Class class15Class = Test15.class;
        Object object = class15Class.newInstance();
        Method method1 = class15Class.getDeclaredMethod("testMethod", String.class);
        Method method2 = class15Class.getDeclaredMethod("testMethod", String.class, String.class);
        method1.invoke(object, "法国");
        method2.invoke(object, "中国", "中国人");
    }
}

程序运行结果如下:

public String testMethod(String username)
法国
public String testMethod(String username, String password)
中国 中国人

提起标记语言,人们首先会想起HTML,HTML提供了很多标签来实现Web前端界面的设计,但HTML中的标签并不允许自定义,如果想定义一些自己独有的标签,HTML就不再可行了,这时可以使用XML来进行实现。

XML(eXtensible Markup Language,可扩展标记语言)可以自定义标记名称与内容,在灵活度上相比HTML改善很多,经常用在配置以及数据交互领域。

在开发软件项目时,经常会接触XML文件,比如web.xml文件中就有XML代码,而Spring框架也使用XML文件存储配置。XML代码的主要作用就是配置。

创建maven-archetype-quickstart类型的Maven项目xmlTest,添加如下依赖:

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

在resources文件夹中创建struts.xml配置文件,代码如下:

<mymvc>
    <actions>
        <action name="list" class="controller.List">
            <result name="toListJSP">
                /list.jsp
            </result>
            <result name="toShowUserinfoList" type="redirect">
                showUserinfoList.ghy
            </result>
        </action>

        <action name="showUserinfoList" class="controller.ShowUserinfoList">
            <result name="toShowUserinfoListJSP">
                /showUserinfoList.jsp
            </result>
        </action>
    </actions>
</mymvc>

1.解析XML文件

创建Reader类,代码如下:

package com.ghy.www.test1;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

public class Reader {
    public static void main(String[] args) {
        try {
           SAXReader reader = new SAXReader();
           Document document = reader.read(reader.getClass()
                  .getResourceAsStream("/struts.xml"));

           Element mymvcElement = document.getRootElement();
           System.out.println(mymvcElement.getName());
           Element actionsElement = mymvcElement.element("actions");
           System.out.println(actionsElement.getName());
           System.out.println("");
           List<Element> actionList = actionsElement.elements("action");
           for (int i = 0; i < actionList.size(); i++) {
              Element actionElement = actionList.get(i);
              System.out.println(actionElement.getName());
              System.out.print("name="
                     + actionElement.attribute("name").getValue());
              System.out.println("action class="
                     + actionElement.attribute("class").getValue());

              List<Element> resultList = actionElement.elements("result");
              for (int j = 0; j < resultList.size(); j++) {
                 Element resultElement = resultList.get(j);
                 System.out.print("  result name="
                        + resultElement.attribute("name").getValue());
                 Attribute typeAttribute = resultElement.attribute("type");
                 if (typeAttribute != null) {
                    System.out.println(" type=" + typeAttribute.getValue());
                 } else {
                    System.out.println("");
                 }
                 System.out.println("   " + resultElement.getText().trim());
                 System.out.println("");
              }

              System.out.println("");
           }

        } catch (DocumentException e) {
           // 自动生成catch块
 e.printStackTrace();
        }
    }
}

程序运行结果如下:

mymvc
actions

action
name=listaction class=controller.List
  result name=toListJSP
   /list.jsp

  result name=toShowUserinfoList type=redirect
   showUserinfoList.ghy

action
name=showUserinfoListaction class=controller.ShowUserinfoList
  result name=toShowUserinfoListJSP
   /showUserinfoList.jsp

2.创建XML文件

创建Writer类,代码如下:

package com.ghy.www.test1;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.FileWriter;
import java.io.IOException;

public class Writer {

    public static void main(String[] args) {
        try {
           Document document = DocumentHelper.createDocument();
           Element mymvcElement = document.addElement("mymvc");
           Element actionsElement = mymvcElement.addElement("actions");
           //
 Element listActionElement = actionsElement.addElement("action");
           listActionElement.addAttribute("name", "list");
           listActionElement.addAttribute("class", "controller.List");

           Element toListJSPResultElement = listActionElement
                  .addElement("result");
           toListJSPResultElement.addAttribute("name", "toListJSP");
           toListJSPResultElement.setText("/list.jsp");

           Element toShowUserinfoListResultElement = listActionElement
                  .addElement("result");
           toShowUserinfoListResultElement.addAttribute("name",
                  "toShowUserinfoList");
           toShowUserinfoListResultElement.addAttribute("type", "redirect");
           toShowUserinfoListResultElement.setText("showUserinfoList.ghy");
           //

 Element showUserinfoListActionElement = actionsElement
                  .addElement("action");
           showUserinfoListActionElement.addAttribute("name",
                  "showUserinfoList");
           showUserinfoListActionElement.addAttribute("class",
                  "controller.ShowUserinfoList");

           Element toShowUserinfoListJSPResultElement = showUserinfoListActionElement
                  .addElement("result");
           toShowUserinfoListJSPResultElement.addAttribute("name",
                  "toShowUserinfoListJSP");
           toShowUserinfoListResultElement.setText("/showUserinfoList.jsp");
           //

 OutputFormat format = OutputFormat.createPrettyPrint();
           XMLWriter writer = new XMLWriter(new FileWriter("ghy.xml"), format);
           writer.write(document);
           writer.close();

        } catch (IOException e) {
           e.printStackTrace();
        }

    }

}

程序运行后在项目中创建ghy.xml文件,如图1-2所示。

图片 1

图1-2 创建的ghy.xml文件

3.修改XML文件

创建Update类,代码如下:

package com.ghy.www.test1;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class Update {

    public static void main(String[] args) throws IOException {
        try {
           SAXReader reader = new SAXReader();
           Document document = reader.read(reader.getClass().getResourceAsStream("/struts.xml"));
           Element mymvcElement = document.getRootElement();
           Element actionsElement = mymvcElement.element("actions");
           List<Element> actionList = actionsElement.elements("action");
           for (int i = 0; i < actionList.size(); i++) {
              Element actionElement = actionList.get(i);
              List<Element> resultList = actionElement.elements("result");
              for (int j = 0; j < resultList.size(); j++) {
                 Element resultElement = resultList.get(j);
                 String resultName = resultElement.attribute("name").getValue();
                 if (resultName.equals("toShowUserinfoList")) {
                    Attribute typeAttribute = resultElement.attribute("type");
                    if (typeAttribute != null) {
                       typeAttribute.setValue("zzzzzzzzzzzzzzzzzzzzzz");
                       resultElement.setText("xxxxxxxxxxxxxxxxxxx");
                    }
                 }
              }
           }
           OutputFormat format = OutputFormat.createPrettyPrint();
           XMLWriter writer = new XMLWriter(new FileWriter("src\\ghy.xml"), format);
           writer.write(document);
           writer.close();
        } catch (DocumentException e) {
           e.printStackTrace();
        }
    }
}

程序运行后产生的ghy.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<mymvc>
    <actions>
        <action name="list" class="controller.List">
            <result name="toListJSP">/list.jsp</result>
            <result name="toShowUserinfoList" type="zzzzzzzzzzzzzzzzzzzzzz">xxxxxxxxxxxxxxxxxxx</result>
        </action>
        <action name="showUserinfoList" class="controller.ShowUserinfoList">
            <result name="toShowUserinfoListJSP">/showUserinfoList.jsp</result>
        </action>
    </actions>
</mymvc>

成功更改XML文件中的属性值与文本内容。

4.删除节点

创建Delete类,代码如下:

package com.ghy.www.test1;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class Delete {

    public static void main(String[] args) throws IOException {
        try {
           SAXReader reader = new SAXReader();
           Document document = reader.read(reader.getClass().getResourceAsStream("/struts.xml"));
           Element mymvcElement = document.getRootElement();
           Element actionsElement = mymvcElement.element("actions");
           List<Element> actionList = actionsElement.elements("action");
           for (int i = 0; i < actionList.size(); i++) {
              Element actionElement = actionList.get(i);
              List<Element> resultList = actionElement.elements("result");
              Element resultElement = null;
              boolean isFindNode = false;
              for (int j = 0; j < resultList.size(); j++) {
                 resultElement = resultList.get(j);
                 String resultName = resultElement.attribute("name").getValue();
                 if (resultName.equals("toShowUserinfoList")) {
                    isFindNode = true;
                    break;
                 }
              }
              if (isFindNode == true) {
                 actionElement.remove(resultElement);
              }
           }
           OutputFormat format = OutputFormat.createPrettyPrint();
           XMLWriter writer = new XMLWriter(new FileWriter("src\\ghy.xml"), format);
           writer.write(document);
           writer.close();
        } catch (DocumentException e) {
           e.printStackTrace();
        }
    }

}

程序运行后产生的ghy.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<mymvc>
    <actions>
        <action name="list" class="controller.List">
            <result name="toListJSP">/list.jsp</result>
        </action>
        <action name="showUserinfoList" class="controller.ShowUserinfoList">
            <result name="toShowUserinfoListJSP">/showUserinfoList.jsp</result>
        </action>
    </actions>
</mymvc>

节点被成功删除。

5.删除属性

创建DeleteAttr类,代码如下:

package com.ghy.www.test1;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class DeleteAttr {

    public static void main(String[] args) throws IOException {
        try {
           SAXReader reader = new SAXReader();
           Document document = reader.read(reader.getClass().getResourceAsStream("/struts.xml"));
           Element mymvcElement = document.getRootElement();
           Element actionsElement = mymvcElement.element("actions");
           List<Element> actionList = actionsElement.elements("action");
           for (int i = 0; i < actionList.size(); i++) {
              Element actionElement = actionList.get(i);
              List<Element> resultList = actionElement.elements("result");
              for (int j = 0; j < resultList.size(); j++) {
                 Element resultElement = resultList.get(j);
                 String resultName = resultElement.attribute("name").getValue();
                 if (resultName.equals("toShowUserinfoList")) {
                    Attribute typeAttribute = resultElement.attribute("type");
                    if (typeAttribute != null) {
                       resultElement.remove(typeAttribute);
                    }
                 }
              }
           }
           OutputFormat format = OutputFormat.createPrettyPrint();
           XMLWriter writer = new XMLWriter(new FileWriter("src\\ghy.xml"), format);
           writer.write(document);
           writer.close();
        } catch (DocumentException e) {
           e.printStackTrace();
        }
    }
}

程序运行后产生的ghy.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<mymvc>
    <actions>
        <action name="list" class="controller.List">
            <result name="toListJSP">/list.jsp</result>
            <result name="toShowUserinfoList">showUserinfoList.ghy</result>
        </action>
        <action name="showUserinfoList" class="controller.ShowUserinfoList">
            <result name="toShowUserinfoListJSP">/showUserinfoList.jsp</result>
        </action>
    </actions>
</mymvc>

XML文件中的type属性成功被删除。