【问题标题】:Parsing a simple XML document with JAXP(JEE6)使用 JAXP(JEE6) 解析简单的 XML 文档
【发布时间】:2011-08-05 12:51:11
【问题描述】:

我想为我的网络应用创建一个授权过滤器(以便能够限制对某些页面的访问)。

我创建了一个简单的 .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>

然后我需要进行解析以提取页面的值,以便能够创建允许或重定向的条件(取决于)。我只需要有人告诉我如何从 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
    }
}

在 doFilter 方法内的 cmets 中解释了我需要做什么。有人可以给我一个提示,告诉我我应该如何遍历文件以查找每种用户类型的页面名称?我尝试从互联网上学习 JAXP 示例,但它们比我需要的要复杂。

更新 xml 存储在 WEB-INF/classes 中

【问题讨论】:

    标签: java xml parsing jakarta-ee


    【解决方案1】:

    使用NodeList nodes = document.getElementsByTagName(tagname);标签名应该是买家或卖家等,因为你需要它。遍历节点列表并读取数据。

    【讨论】:

      【解决方案2】:

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

      请阅读this article

      基本上,归结为写在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>
      

      以上示例适用于买方角色。

      【讨论】:

      • 这里如何控制重定向?
      • 没错。我发现基于过滤器的身份验证仅适用于非常复杂的目的。例如,您希望有能力,在一段时间内向某些用户授予某些权限。并且您想在 db 中记住所有这些“授权”。对于普通情况,基于容器的安全性就足够了。
      【解决方案3】:

      宁可使用 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;
              }
      
          }
      
      }
      

      然后执行下面的代码来映​​射它(假设allowedpages.xml被放置在classpath的根目录下)。

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

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

      最后你可以访问所有买家页面如下:

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

      不用说,家庭种植的安全性并不总是最佳做法。 Java EE 6 附带了容器管理的安全性。

      【讨论】:

      • 我很想使用容器管理的安全性,因为我知道更好,只是我很难在我的场景中实现它。我想在我学到更多东西之前,我会坚持这种方法。 P.S 我需要在 web.xml 文件中添加一些东西吗?
      • 什么都没有。以上就是阅读 XML 所需要做的一切。 JAXB 已经与 Java EE 6 容器捆绑在一起(我知道您使用的是 Glassfish)。在 Tomcat 上,您必须单独安装和配置它。
      • 我刚写完Filter,我去试试。感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 2017-12-07
      • 2011-05-14
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      • 2010-10-07
      相关资源
      最近更新 更多