ajax - 使用 JSF 的 Servlet 过滤器

标签 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. 如果 session 不存在,用户应该被重定向到登录页面
  2. 如果 session 存在,并且如果用户进入登录页面,则他不应被重定向

添加过滤器后 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
    }

}

这是我的 sessionn 范围的登录 bean 我不在这里使用注释

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>

我完全被困在这里,不知道如何继续使用过滤器。

最佳答案

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

除根目录中的 login.xhtml 外,所有页面都在/secure/中。

<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);
    }
}

登录.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。

关于ajax - 使用 JSF 的 Servlet 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26779489/

相关文章:

java - 通过 LDAP 服务器进行身份验证

java - 在 JSF 中获取请求参数值

java - Spring MVC 重定向是在 url 中添加一些参数

powershell - '<' 运算符保留供将来使用

php - 如何从动态加载的 ajax 文件重定向整个页面

javascript - 希望我的表在新内容添加到数据库时刷新

jquery - 为什么 Ajax 脚本无法在 IIS 7.5 Win 2008 R2 服务器上运行?

java - 在数据表过滤器上添加 onkeyup 事件

python - 有没有一种简单的方法可以在 python 中请求 URL 而不是遵循重定向?

html - 用于替换 div 内容的 jQuery html() 仅适用于第一次