Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing a simple XML document with JAXP(JEE6)

I want to create an authorization filter for my web app(To be able to restrict access to certain pages).

I created a simple .xml file with the pages that each user is allowed to visit:

  <access>
    <buyer>
        <page>buyoffer.xhtml</page>
        <page>faq.xhtml</page>
        <page>index.jsp</page>
        <page>login.xhtml</page>
        <page>main.xhtml</page>
        <page>registrationSucceded.xhtml</page>     
    </buyer>
    <seller>
        <page>sellerpanel.xhtml</page>
        <page>faq.xhtml</page>
        <page>index.jsp</page>
        <page>login.xhtml</page>
        <page>main.xhtml</page>
        <page>registrationSucceded.xhtml</page>     
    </seller>
    <administrator>
        <page>sellerpanel.xhtml</page>
        <page>faq.xhtml</page>
        <page>index.jsp</page>
        <page>login.xhtml</page>
        <page>main.xhtml</page>
        <page>registrationSucceded.xhtml</page>     
    </administrator>
</access>

Then i need to do parsing to extract the value of the pages, to be able to create conditions to allow or redirect(Depending). I just need somebody to tell be how to extract the values of those pages from the xml. This is what i did till now:

public class RestrictPageFilter implements Filter {

    private FilterConfig fc;
    private DocumentBuilder builder;
    private Document document;

    public void init(FilterConfig filterConfig) throws ServletException {
        // The easiest way to initialize the filter
        fc = filterConfig;
        // Get the file that contains the allowed pages
        File f = new File("/allowedpages.xml");
        // Prepare the file parsing
        try {
            builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            document = builder.parse(f);
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpSession session = req.getSession(true);
        String pageRequested = req.getRequestURL().toString();

        // Get the value of the current logged user
        Role currentUser = (Role) session.getAttribute("userRole");
        if (currentUser != null) {
            if(currentUser.getType().equals("BUYER")) {
                //Loop BUYER Element of the .xml
                //if pageRequested.contains(value of the page at buyer element)             
                // chain.doFilter(request, response);
                // Else
                // Redirect the user to the main page
            }
            else if(currentUser.getType().equals("SELLER")) {
                //Same as above just for seller element
            }
            else if(currentUser.getType().equals("ADMINISTRATOR")) {
                //Same as above just for administrator element
            }           
        }
    }

    public void destroy() {
        // Not needed
    }
}

In the comments inside the doFilter method is explained what i need to do. Could someone give me a tip on how i should iterate through the file to find the page names for each of the user types? I try to follow JAXP examples from the internet, but they are more complex than what i need.

Update The xml is stored in WEB-INF/classes

like image 529
javing Avatar asked Apr 14 '11 12:04

javing


People also ask

What is the best way to parse XML in Java?

DOM Parser is the easiest java xml parser to learn. DOM parser loads the XML file into memory and we can traverse it node by node to parse the XML. DOM Parser is good for small files but when file size increases it performs slow and consumes more memory.

What is Jaxp and JAXB?

JAXP is Java API for XML Processing, which provides a platform for us to Parse the XML Files with the DOM Or SAX Parsers. Where as JAXB is Java Architecture for XML Binding, it will make it easier to access XML documents from applications written in the Java programming language.

How Dom parses the XML file?

DOM parser parses the entire XML file and creates a DOM object in the memory. It models an XML file in a tree structure for easy traversal and manipulation. In DOM everything in an XML file is a node. The node represents a component of an XML file.


2 Answers

Rather use JAXB. JAXP is an old and very verbose API. JAXB leans on Javabeans and is therefore clean and relatively easy. First create a Javabean which maps 1:1 to the XML file using javax.xml.bind annotations.

@XmlRootElement
public class Access {

    @XmlElement
    private User buyer;

    @XmlElement
    private User seller;

    @XmlElement
    private User administrator;

    public User getBuyer() {
        return buyer;
    }

    public User getSeller() {
        return seller;
    }

    public User getAdministrator() {
        return administrator;
    }

    public static class User {

        @XmlElement(name="page")
        private List<String> pages;

        public List<String> getPages() {
            return pages;
        }

    }

}

Then execute the following piece to map it (assuming that allowedpages.xml is placed in root of the classpath).

InputStream input = Thread.currentThread().getContextClassLoader().getResourceAsStream("allowedpages.xml");
Access access = (Access) JAXBContext.newInstance(Access.class).createUnmarshaller().unmarshal(input);

Note that you should NOT use new File() for this. See also getResourceAsStream() vs FileInputStream.

Finally you can access all buyer pages as follows:

List<String> buyerPages = access.getBuyer().getPages();
// ...

Needless to say that homegrowing security isn't always the best practice. Java EE 6 ships with container managed security.

like image 55
BalusC Avatar answered Sep 23 '22 22:09

BalusC


May I ask why are you reinventing the wheel? If you're using Java EE 6, why not use the built in security mechanism which is similar to what you do, but declarative in nature?

Please read this article.

Essentially, it will boil down to writing this in web.xml:

<security-constraint>
   <display-name>For users in buyer role</display-name>
   <web-resource-collection>
      <web-resource-name>Restricted Access - Buyers Only</web-resource-name>
      <url-pattern>buyoffer.xhtml</url-pattern>
      <url-pattern>faq.xhtml</url-pattern>
      <url-pattern>index.jsp</url-pattern>
      <url-pattern>login.xhtml</url-pattern>
      <url-pattern>main.xhtml</url-pattern>
      <url-pattern>registrationSucceded.xhtml</url-pattern> 
      <http-method>GET</http-method>
   </web-resource-collection>
   <auth-constraint>
      <role-name>Buyer</role-name>
   </auth-constraint>
   <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
   </user-data-constraint>
</security-constraint>

Above example is for buyer role.

like image 32
darioo Avatar answered Sep 23 '22 22:09

darioo