Parsing a simple XML document with JAXP(JEE6)

10,812

Solution 1

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.

Solution 2

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.

Share:
10,812
javing
Author by

javing

Enthusiastic java developer based in London, I love stackoverflow, I use it regularly for many years and is a great way of helping and ask for help. Also i love blogging about software. Please visit my Blogs: Javing (Medium) Javing (Blogger)

Updated on June 25, 2022

Comments

  • javing
    javing almost 2 years

    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

  • javing
    javing about 13 years
    How do you control redirection in here?
  • javing
    javing about 13 years
    I would love to use container managed security, because i know is better, it is just that i am having difficulties to implement it in my scenario. I think until i learn a bit more i will stick to this approach. P.S Do i need to add something to the web.xml file?
  • BalusC
    BalusC about 13 years
    Nothing. The above is really all you need to do to read the XML. JAXB is already bundled with Java EE 6 containers (I know you're using Glassfish). On Tomcat you'd have to install and configure it separately.
  • javing
    javing about 13 years
    I just finished writing the Filter, i go to try it. Thanks for your help.
  • Zbyszek
    Zbyszek almost 11 years
    That's right. I found filter based authentication fit only to very sophisticated purpposes. For example, you want to have ablility, to grant some rights for some time to some users. And you want to remember in db all these "grants". For ordinary case, container based security is enough and effective.