Reading and writing a XML file in JSF

前端 未结 1 1367
半阙折子戏
半阙折子戏 2021-01-14 08:33

I found nothing online about how to read/write an XML document in JSF. I know something in JSP along with JSTL using XALAN. For example,

The following XML file is de

相关标签:
1条回答
  • 2021-01-14 09:15

    You can indeed use JAXB for this.

    Let's assume that you already have a javabean representing <fruit>. You can even reuse an existing JPA entity for this.

    public class Fruit {
    
        private String name;
        private BigDecimal price;
    
        // Add/generate getters+setters.
    }
    

    (note that javabean class and property names must exactly match XML element names <fruit>, <name> and <price>, otherwise you need a @XmlElement(name="actualXmlElementName") on either of those)

    Now, create another javabean representing <fruits>, purely for usage in JAXB (it namely requires a @XmlRootElement class representing the XML root element, even though the XML document basically only contains a list of entities).

    @XmlRootElement
    public class Fruits { // Classname must match <fruits>, otherwise set it as @XmlRootElement(name="fruits")
    
        @XmlElement(name="fruit") // Name must thus match <fruit>. We could also make the property name "fruit" so that we can omit @XmlElement, but a getFruit() method returning a list of fruits isn't self-documenting.
        private List<Fruit> list;
    
        public Fruits() {
            // Keep default c'tor alive.
        }
    
        public Fruits(List<Fruit> list) {
            this.list = list;
        }
    
        public List<Fruit> getList() { 
            return list;
        }
    
    }
    

    As to reading/writing, you can in JSF perfectly read from /WEB-INF as follows:

    InputStream input = externalContext.getResourceAsStream("/WEB-INF/fruits.xml");
    

    But writing is a story apart. You aren't supposed to write files to deployment space. It isn't intented as permanent storage location for the obvious reason that all changes will get lost whenever you redeploy the WAR. You need to write it to a fixed path somewhere outside the deploy space. In the below example I'll assume that the file is moved to /var/webapp/fruits.xml on the server's disk file system.

    So, you can use JAXB to read and write the XML file in a managed bean as follows:

    @Named
    @RequestScoped
    public class Bean {
    
        private File file = new File("/var/webapp/fruits.xml");
        private JAXBContext jaxb; // Can be application scoped. It's thread safe.
        private List<Fruit> fruits;
    
        @PostConstruct
        public void init() throws JAXBException, IOException {
            jaxb = JAXBContext.newInstance(Fruits.class);
            fruits = ((Fruits) jaxb.createUnmarshaller().unmarshal(file)).getList();
        }
    
        public void save() throws JAXBException {
            jaxb.createMarshaller().marshal(new Fruits(fruits), file);
        }
    
        public List<Fruit> getFruits() { 
            return fruits;
        }
    
    }
    

    You can display it for editing in a JSF <h:dataTable> the usual way.

    <h:dataTable value="#{bean.fruits}" var="fruit">
        <h:column><h:inputText value="#{fruit.name}" /></h:column>
        <h:column><h:inputText value="#{fruit.price}" /></h:column>
    </h:dataTable>
    
    0 讨论(0)
提交回复
热议问题