java 使用 JAXP(JEE6) 解析一个简单的 XML 文档

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5663581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 12:10:05  来源:igfitidea点击:

Parsing a simple XML document with JAXP(JEE6)

javaxmlparsingjakarta-ee

提问by sfrj

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:

我创建了一个简单的 .xml 文件,其中包含允许每个用户访问的页面:

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

然后我需要进行解析以提取页面的值,以便能够创建允许或重定向的条件(取决于)。我只需要有人告诉我如何从 xml 中提取这些页面的值。这就是我到目前为止所做的:

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.

在 doFilter 方法中的注释中解释了我需要做什么。有人能给我一个关于我应该如何遍历文件以找到每个用户类型的页面名称的提示吗?我尝试遵循互联网上的 JAXP 示例,但它们比我需要的更复杂。

UpdateThe xml is stored in WEB-INF/classes

更新xml 存储在 WEB-INF/classes

回答by BalusC

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

而是使用 JAXB。JAXP 是一个古老而冗长的 API。JAXB 依赖于 Javabeans,因此干净且相对容易。首先创建一个 Javabean,它使用javax.xml.bind注解1:1 映射到 XML 文件。

@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.xmlis placed in root of the classpath).

然后执行下面的部分来映射它(假设它allowedpages.xml放在类路径的根目录中)。

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.

请注意,您不应该new File()为此使用。另见getResourceAsStream()vsFileInputStream

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.

毋庸置疑,家庭种植安全并不总是最佳实践。Java EE 6 附带容器管理的安全性。

回答by darioo

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?

请问你为什么要重新发明轮子?如果您使用的是 Java EE 6,为什么不使用与您所做的类似但本质上是声明性的内置安全机制?

Please read this article.

请阅读这篇文章

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

从本质上讲,它将归结为将其写入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.

上面的例子是买方角色。

回答by Manoj

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.

根据需要使用NodeList nodes = document.getElementsByTagName(tagname);标记名应该是买方或卖方等。遍历节点列表并读取数据。