Parsing a simple XML document with JAXP(JEE6)

2019-02-13 21:36发布

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

3条回答
聊天终结者
2楼-- · 2019-02-13 22:19

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.

查看更多
3楼-- · 2019-02-13 22:31

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.

查看更多
姐就是有狂的资本
4楼-- · 2019-02-13 22:37

use NodeList nodes = document.getElementsByTagName(tagname); the tagname should be buyer or seller etc as you need it. Iterate over the node list and read the data.

查看更多
登录 后发表回答