java - JAXB 如何避免对象的重复/覆盖

标签 java xml jaxb

我有一个 html 表单,用于选择应存储在 xml 文件中的用户名和密码。这是存储用户名详细信息的类:

@XmlRootElement(name = "Emp")
@XmlType(propOrder = {"username", "passowrd"})

    public class UserBean {

        String username;
        String passowrd;

         @XmlElement(name = "username")
        public String getUsername() {
            return username;
        }

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

         @XmlElement(name = "password")
        public String getPassowrd() {
            return passowrd;
        }
        public void setPassowrd(String passowrd) {
            this.passowrd = passowrd;
        }


        @Override
        public String toString() {
            return "UserBean [username=" + username + ", passowrd=" + passowrd + "]";
        }

    }

这是我获取用户名详细信息并尝试将它们存储在 xml 文件中的 servlet:

@WebServlet("/Data")
public class Data extends HttpServlet {
    private static final long serialVersionUID = 1L;


    private static final String FILE_NAME = "jaxb-emp.xml";


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

          UserBean emp = new  UserBean ();

         String userName = request.getParameter("username");
         String password = request.getParameter("password");

            emp.setUsername(userName);
            emp.setPassowrd(password);


             jaxbObjectToXML(emp);

             UserBean empFromFile = jaxbXMLToObject();
             System.out.println(empFromFile.toString());



         RequestDispatcher rd=request.getRequestDispatcher("index.jps");
         rd.forward(request, response);

    }



     private static UserBean jaxbXMLToObject() {
            try {
                JAXBContext context = JAXBContext.newInstance(UserBean.class);
                Unmarshaller un = context.createUnmarshaller();
                UserBean emp = (UserBean) un.unmarshal(new File(FILE_NAME));
                return emp;
            } catch (JAXBException e) {
                e.printStackTrace();
            }
            return null;
        }


        private static void jaxbObjectToXML(UserBean emp) {

            try {
                JAXBContext context = JAXBContext.newInstance(UserBean.class);
                Marshaller m = context.createMarshaller();
                //for pretty-print XML in JAXB
                m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

                // Write to System.out for debugging
                // m.marshal(emp, System.out);

                // Write to File
                m.marshal(emp, new File(FILE_NAME));
            } catch (JAXBException e) {
                e.printStackTrace();
            }
        }
}

每次启动 tomcat 并输入用户数据时,它都会覆盖该文件。问题是,我的目的是拥有多个用户名并避免重复。

最佳答案

您可以使用容器类来存储 UserBean。

算法:

  1. 将所有存储的 Bean 读取到容器
  2. 如果用户名不重复则添加
  3. 将容器写入文件。

Note: It is not safe to store passwords as plait text. You should think about security.

容器:

@XmlRootElement(name = "Department")
@XmlAccessorType(value = XmlAccessType.FIELD)
public class DepartmentBean {

    @XmlElement(name = "Emp", type = UserBean.class)
    @XmlElementWrapper(name = "Emps")
    private List<UserBean> users;

    public List<UserBean> getUsers() {
        return users;
    }

    public void addIfAbsent(UserBean userBean) {
        if (users.stream().anyMatch(x -> x.getUsername().equals(userBean.getUsername()))) {
            System.err.println("User " + userBean + " is already exist, do nothing");
        } else {
            users.add(userBean);
        }
    }
}

xml 示例(Department 和 Emps 标记都应始终位于文件中):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Department>
    <Emps>
        <Emp>
            <username>Name</username>
            <password>pass</password>
        </Emp>
    </Emps>
</Department>

使用示例:

public static void main(String... args) throws Exception {
    DepartmentBean departmentBean = read();
    UserBean user = new UserBean();
    user.setPassword("pass");
    user.setUsername("user2");

    departmentBean.addIfAbsent(user);
    write(departmentBean);
}

public static DepartmentBean read() throws JAXBException {
    JAXBContext context = JAXBContext.newInstance(DepartmentBean.class, UserBean.class);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    return (DepartmentBean) unmarshaller.unmarshal(new StreamSource(new File("1.xml")));
}

public static void write(DepartmentBean department) throws JAXBException {
    JAXBContext context = JAXBContext.newInstance(DepartmentBean.class, UserBean.class);
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    marshaller.marshal(department, new File("1.xml"));
}

关于java - JAXB 如何避免对象的重复/覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50193482/

相关文章:

java - 用 HSQLDB 替换 mysql 特定功能

java - 单击 fragment 中的后退按钮后 ListView 正在更新

java - 无法生成签名的APK?

Java:带有注释的 Jersey (JAX-RS) 和 JAXB_FORMATTED_OUTPUT?

java - 如何使用 gradle-jaxb-plugin 的 jaxb 插件扩展

java - EJB @Local 和 @Stateless 在一起

java - 如何选择目录中的上一张或下一张图像?

xmlstarlet 不适用于 xml 版本 1.1 文件。有什么可以与 Bash 一起使用的替代方案吗?

C# xml序列化

xsd - 创建一个通用的 xsd 生成的类以供其他包使用