使用JSF的Servlet过滤器

时间:2014-11-06 12:27:34

标签: ajax jsf redirect jsf-2.2 servlet-filters

我尝试使用JSF配置Servlet过滤器。我在这里遇到很多问题我也在使用PrimeFaces。

这是我的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>JsfEaxmples</display-name>
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>1</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.SEPARATOR_CHAR</param-name>
    <param-value>-</param-value>
  </context-param>
  <context-param>
    <param-name>org.richfaces.skin</param-name>
    <param-value>classic</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.BUILD_BEFORE_RESTORE</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.RECREATE_VALUE_EXPRESSION_ON_BUILD_BEFORE_RESTORE</param-name>
    <param-value>true</param-value>
  </context-param>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>

  </servlet-mapping>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
  </context-param>
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>
  <filter>
  <filter-name>sessionfilter</filter-name>
  <filter-class>com.invoice.sessionfilter</filter-class>

  </filter>
  <filter-mapping>
  <filter-name>sessionfilter</filter-name>
  <url-pattern>/*</url-pattern>

  </filter-mapping>
</web-app>

首先我使用了像<url-pattern>jsf invoice system/*</url-pattern>这样的过滤器,这完全不起作用,所以我改为<url-pattern>/*</url-pattern>这个响应,但在我的过滤中给了很多问题 我用过滤器

检查以下过程
  1. 如果会话不存在,则应将用户重定向到登录页面
  2. 如果会话存在且用户进入登录页面,则不应重定向
  3. 添加过滤器PrimeFaces组件外观更改后更多。添加过滤器后,它无法正确导航。

    这是我的过滤器代码。

    package com.invoice;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class sessionfilter implements Filter {
    
        String uname;
    
        /**
         * Default constructor.
         */
        public sessionfilter() {
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see Filter#destroy()
         */
        public void destroy() {
            // TODO Auto-generated method stub
        }
    
        /**
         * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
         */
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            // place your code here
    
            // pass the request along the filter chain
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse resp = (HttpServletResponse) response;
            String pagerequested = req.getRequestURL().toString();
            HttpSession ses = req.getSession(true);
            //uname=(String)ses.getAttribute("uname");//null pointer exception
            if (pagerequested.contains("Login.xhtml") && uname == null)// if user logs in to this for first time
            {
    
                chain.doFilter(request, response);
    
            } else if (uname != null && pagerequested.contains("Login.xhtml")) { // if session exists and user tries to go to login page he should be redirected
    
                resp.sendRedirect("invoiceinfo.xhtml");
    
            } else if (uname == null && !pagerequested.contains("Login.xhtml")) {
    
                try {
                    uname = (String) ses.getAttribute("uname");
                    chain.doFilter(request, response);
    
                } catch (Exception e) {
                    resp.sendRedirect("Login.xhtml");
                }
            }
        }
    
        /**
         * @see Filter#init(FilterConfig)
         */
        public void init(FilterConfig fConfig) throws ServletException {
            // TODO Auto-generated method stub
        }
    
    }
    

    这是我的登录bean,其中包含sessionn作用域,我不在这里使用注释

    package com.invoice;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    import javax.faces.bean.SessionScoped;
    import javax.faces.context.FacesContext;
    import javax.servlet.http.HttpSession;
    
    @SessionScoped
    public class login {
    
        String username, userpassword, errormess, navipg;
    
        public String getNavipg() {
            return navipg;
        }
    
        public void setNavipg(String navipg) {
            this.navipg = navipg;
        }
    
        public String getErrormess() {
            return errormess;
        }
    
        public void setErrormess(String errormess) {
            this.errormess = errormess;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getUserpassword() {
            return userpassword;
        }
    
        public void setUserpassword(String userpassword) {
            this.userpassword = userpassword;
        }
    
        public String navigate() {
            try {
                Class.forName("oracle.jdbc.driver.OracleDriver");
                Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "invoice", "google");
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery("select username,password from usertable where username='" + username + "' and password='" + userpassword + "' ");
                if (rs.next()) {
                    setErrormess("");
                    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("uname", this.username);
                    navipg = "invoiceinfo";
                } else {
                    setErrormess("Invalid Login credentials");
                    username = "";
                    navipg = "Login";
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return navipg;
        }
    
        public String logout() {
            FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
            return "Login";
        }
    }
    

    我的登录页面是

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:p="http://primefaces.org/ui">
    
        <h:head>
            <style type="text/css">
                .ui-panelgrid tr,
                .ui-panelgrid td {
                    border: none;
                }
            </style>
        </h:head>
    
        <h:body>
            <h:form>
                <p:panelGrid columns="3" id="pnl" border= "0">
                    <f:facet name="header"><p:graphicImage value="login.jpg"/></f:facet>
                    <h:outputText value="Username"/>
    
                    <p:inputText id="uname" value="#{login.username}" required="true" label="username"/>
                    <p:message for="uname"/>
    
                    <h:outputText value="Password"/>
                    <p:password id="pass" value="#{login.userpassword}" required="true" label="password"/>
                    <p:message for="pass"/>
    
                    <p:commandButton value="Login" action="#{login.navigate}" ajax="false"/>
                    <p:button value="Reset" />
                </p:panelGrid>
    
                <h1><h:outputText value="#{login.errormess}"/></h1>
            </h:form>
        </h:body>
    </html>
    

    我完全被困在这里而不知道如何继续进行过滤。

1 个答案:

答案 0 :(得分:1)

使用CDI,我使用它。似乎工作正常。重定向ajax请求。

所有页面都在/ secure /中,但root.xhtml除外。

<filter>         
    <filter-name>LoginFilter</filter-name>         
    <filter-class>...LoginFilter</filter-class>     
</filter>      
<filter-mapping>         
    <filter-name>LoginFilter</filter-name>         
    <url-pattern>/secure/*</url-pattern>     
</filter-mapping>  

过滤器:

@Inject
private LoginBean loginBean;

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

    // Set response headers to no-cache
    HttpServletResponse res = (HttpServletResponse) response;
    HttpServletRequest req = (HttpServletRequest) request;
    res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
    res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
    res.setDateHeader("Expires", 0); // Proxies.

    // Check if user logged in, if not redirect to login.xhtml
    if (loginBean == null || !((LoginBean) loginBean).isLoggedIn()) {
        boolean isAjax = "XMLHttpRequest".equals(req.getHeader("X-Requested-With"));

        if (!isAjax) {
            res.sendRedirect(req.getContextPath() + "/login.xhtml"); 
        } else {
            // Redirecting an ajax request has to be done in the following way:
            // http://javaevangelist.blogspot.dk/2013/01/jsf-2x-tip-of-day-ajax-redirection-from.html
            String redirectURL = res.encodeRedirectURL(req.getContextPath() + "/login.xhtml");
            StringBuilder sb = new StringBuilder();
            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><partial-response><redirect url=\"").append(redirectURL).append("\"></redirect></partial-response>");
            res.setCharacterEncoding("UTF-8");
            res.setContentType("text/xml");
            PrintWriter pw = response.getWriter();
            pw.println(sb.toString());
            pw.flush();
        }
    } else {
        // Let chain of filters continue;
        chain.doFilter(request, response);
    }
}

login.xhtml:

<h:body onload="PF('dlg').show()">
    <p:growl id="growl" life="5000" autoUpdate="true" showDetail="true" escape="false"/>

    <h:form>    
        <p:dialog id="dialog" header="Login" footer="..." width="400" widgetVar="dlg" closable="false" showEffect="clip" draggable="false" resizable="false" style="box-shadow: 7px 10px 5px #303030;"> 

            <p:panelGrid columns="2">
                <p:outputLabel value="Username"/>            
                <p:inputText value="#{loginBean.username}" id="username"/>            
                <p:outputLabel value="Password"/>            
                <p:password value="#{loginBean.password}" id="password"/>            
            </p:panelGrid>
            <p:commandButton  id="button" value="Login" action="#{loginBean.doLogin}" style="float:right"/> 
.... close tags

LoginBean是一个简单的SessionScoped CDI bean。