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
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>