Spring+Hibernate+JSF+Ajax4jsf+Acegi+jCaptcha 做登录模块

带 图片验证码的用户登录是一个系统中很常见的模块,在Java EE中有很多不同的实现,而开源世界中又给我们提供了很多优秀的框架,从而减少了我们的编码量,下面给大家简单介绍一下用Spring+ Hibernate+JSF+Ajax4jsf+Acegi+jCaptcha 如何构建一个登录模块:    我使用这些框架的版本如下:
    Spring 2.0.1
    Hibernate 3.2
    JSF 1.2
    Acegi 1.0.5
    jCaptcha 1.0-RC6
    首先建表USERTEST,和ROLETEST,作为用户表和角色表
CREATE TABLE USERTEST
(
  USERID    NUMBER                              NOT NULL,
  USERNAME  VARCHAR2(20 CHAR)                   NOT NULL,
  PASSWORD  VARCHAR2(100 CHAR)                  NOT NULL,
  STATUS    NUMBER                              DEFAULT 1                     NOT NULL,
  ROLEID    NUMBER                              NOT NULL
)

CREATE TABLE ROLETEST
(
  ROLEID    NUMBER                              NOT NULL,
  ROLENAME  VARCHAR2(50 CHAR)                   NOT NULL,
  ROLEDESC  VARCHAR2(50 CHAR)
)

    同时给ROLETEST表添加一条记录:1    ROLE_USER    普通用户
    再给USERTEST表添加一条记录:1    admin    123    1    1
    对应的hbm.xml文件就相信大家都会写,如果用eclipse开发的话,可以使用HibernateSynchronizer插件,我使用的版本是 3.1.9
    接下来就要给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"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd "
id="WebApp_ID" version="2.5">
<display-name>Demo</display-name>
<welcome-file-list>
  <welcome-file>index.html</welcome-file>
  <welcome-file>index.htm</welcome-file>
  <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   /WEB-INF/classes/applicationContext.xml
  </param-value>
</context-param>
<context-param>
  <param-name>javax.faces.CONFIG_FILES</param-name>
  <param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
<listener>
  <listener-class>
   org.springframework.web.context.ContextLoaderListener
  </listener-class>
</listener>
<listener>
  <listener-class>
   org.acegisecurity.ui.session.HttpSessionEventPublisher
  </listener-class>
</listener>
<listener>
  <listener-class>
   com.sun.faces.config.ConfigureListener
  </listener-class>
</listener>
<filter>
  <filter-name>OpenSessionInView</filter-name>
  <filter-class>
   org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
  </filter-class>
  <init-param>
   <param-name>singleSession</param-name>
   <param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>OpenSessionInView</filter-name>
  <url-pattern>*.jsf</url-pattern>
</filter-mapping>
<filter>
  <filter-name>Acegi Filter Chain Proxy</filter-name>
  <filter-class>
   org.acegisecurity.util.FilterToBeanProxy
  </filter-class>
  <init-param>
   <param-name>targetClass</param-name>
   <param-value>
    org.acegisecurity.util.FilterChainProxy
   </param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>Acegi Filter Chain Proxy</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter>
  <display-name>Ajax4jsf Filter</display-name>
  <filter-name>ajax4jsf</filter-name>
  <filter-class>org.ajax4jsf.Filter</filter-class>
  </filter>
  
  <filter-mapping>
  <filter-name>ajax4jsf</filter-name>
  <servlet-name>Faces Servlet</servlet-name>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
  </filter-mapping>


<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>*.jsf</url-pattern>
</servlet-mapping>
</web-app>

    然后Spring的applicationContext.xml,在这里面你需要配置数据库连接、hibernate的各种策略、Acegi安全设置、 jCaptcha设置等等:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/

Spring+Hibernate+JSF+Ajax4jsf+Acegi+jCaptcha 做登录模块

www.firnow.com    时间 : 2008-02-03  作者:佚名   编辑:本站 点击:  2469 [ 评论 ]

<script src="http://dev.firnow.com/ad/2010/article/ad4.js"></script><script type="text/javascript">&lt;!-- google_ad_client = &quot;pub-2974889429954990&quot;; /* 468x15, 创建于 10-4-24 */ google_ad_slot = &quot;8838741374&quot;; google_ad_width = 468; google_ad_height = 15; //--&gt; </script><script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script><script src="http://pagead2.googlesyndication.com/pagead/expansion_embed.js"></script><script src="http://googleads.g.doubleclick.net/pagead/test_domain.js"></script><script>google_protectAndRun(&quot;ads_core.google_render_ad&quot;, google_handleError, google_render_ad);</script>
<script src="http://dev.firnow.com/ad/2010/article/ad5.js"></script><script type="text/javascript"> cpro_client='diybl_cpr'; cpro_at='text_image'; cpro_161=3; cpro_flush=2; cpro_w=300; cpro_h=250; cpro_template='text_default_300_250'; cpro_cbd='#FFFFFF'; cpro_cbg='#FFFFFF'; cpro_ctitle='#215670'; cpro_cdesc='#444444'; cpro_curl='#808080'; cpro_cflush='#e10900'; cpro_uap=1; cpro_cad=1; cpro_channel=4; </script><script src="http://cpro.baidu.com/cpro/ui/cp.js" type="text/javascript"></script>
-
<script src="http://dev.firnow.com/ad/2010/article/ad6.js"></script><script type="text/javascript"> cpro_client='diybl_cpr'; cpro_at='text_image'; cpro_161=3; cpro_flush=2; cpro_w=300; cpro_h=250; cpro_template='text_default_300_250'; cpro_cbd='#FFFFFF'; cpro_cbg='#FFFFFF'; cpro_ctitle='#215670'; cpro_cdesc='#444444'; cpro_curl='#808080'; cpro_cflush='#e10900'; cpro_uap=1; cpro_cad=1; cpro_channel=4; </script><script src="http://cpro.baidu.com/cpro/ui/cp.js" type="text/javascript"></script>
-

aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.1.xsd ">
<bean id="dataSource"
  class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName">
   <value>oracle.jdbc.driver.OracleDriver</value>
  </property>
  <property name="url">
   <value>jdbc:oracle:thin:@10.10.10.10:1521:demo</value>
  </property>
  <property name="username">
   <value>demo</value>
  </property>
  <property name="password">
   <value>demo</value>
  </property>
</bean>
<bean id="sessionFactory"
  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
  <property name="dataSource">
   <ref bean="dataSource" />
  </property>
  <property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.OracleDialect
    </prop>
    <prop key="hibernate.connection.pool_size">5</prop>
    <prop key="hibernate.show_sql">true</prop>
    <prop key="cache.provider_class">
     org.hibernate.cache.OSCacheProvider
    </prop>
    <prop key="cache.use_query_cache">true</prop>
    <prop key="cglib.use_reflection_optimizer">false</prop>
   </props>
  </property>
  <property name="mappingDirectoryLocations">
   <list><!-- 这里指定了hibernate的映射目录 -->
    <value>classpath:/com/fifthlab/demo/pojo</value>
   </list>
  </property>
</bean>

<bean id="transactionManager"
  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>

<!-- Transaction template for Managers -->
<bean id="txProxyTemplate" abstract="true"
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
  <property name="transactionManager" ref="transactionManager" />
  <property name="transactionAttributes">
   <props>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="add*">PROPAGATION_REQUIRED</prop>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
    <prop key="relation*">PROPAGATION_REQUIRED</prop>
    <prop key="disconnect*">PROPAGATION_REQUIRED</prop>
    <prop key="assign*">PROPAGATION_REQUIRED</prop>
    <prop key="unassign*">PROPAGATION_REQUIRED</prop>
    <prop key="*">PROPAGATION_SUPPORTS</prop>
   </props>
  </property>
</bean>

<!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX acegi part begin XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
<!-- ======================== FILTER CHAIN ======================= -->
<!--  if you wish to use channel security, add "channelProcessingFilter," in front
  of "httpSessionContextIntegrationFilter" in the list below -->
<bean id="filterChainProxy"
  class="org.acegisecurity.util.FilterChainProxy">
  <property name="filterInvocationDefinitionSource">
   <value>
    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    PATTERN_TYPE_APACHE_ANT
    /**/*.jsf=httpSessionContextIntegrationFilter,captchaValidationProcessingFilter ,authenticationProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
   </value>
  </property>
</bean>

<bean id="httpSessionContextIntegrationFilter"
  class="org.acegisecurity.context.HttpSessionContextIntegrationFilter">
  <property name="context">
   <value><!-- 此处修复了Acegi和jCaptcha不能兼容的一个bug,在后面的版本中应该修复了 -->
    com.fifthlab.demo.dao.authentication.FixedCaptchaSecurityContextImpl
   </value>
  </property>
</bean>

<bean id="authenticationManager"
  class="org.acegisecurity.providers.ProviderManager">
  <property name="providers">
   <list>
    <ref local="daoAuthenticationProvider" />
   </list>
  </property>
</bean>

<bean id="daoAuthenticationProvider"
  class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
  <property name="userDetailsService">
   <ref local="hibernate3Authentication" />
  </property>
</bean>

<bean id="loggerListener"
  class="org.acegisecurity.event.authentication.LoggerListener" />

<bean id="authenticationProcessingFilter"
  class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
  <property name="authenticationManager">
   <ref bean="authenticationManager" />
  </property>
  <property name="authenticationFailureUrl">
   <value>/login.jsf </value>
  </property>
  <property name="defaultTargetUrl">
   <value>/login.jsf </value>
</property>
  <property name="filterProcessesUrl">
   <value>/j_acegi_security_check</value>
  </property>
</bean>
<bean id="exceptionTranslationFilter"
  class="org.acegisecurity.ui.ExceptionTranslationFilter">
  <property name="authenticationEntryPoint">
   <ref local="authenticationProcessingFilterEntryPoint" />
  </property>
</bean>

<bean id="authenticationProcessingFilterEntryPoint"
  class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
  <property name="loginFormUrl">
   <value>/login.jsf </value>
  </property>
  <property name="forceHttps">
   <value>false</value>
  </property>
</bean>

<bean id="filterInvocationInterceptor"
  class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
  <property name="authenticationManager">
   <ref bean="authenticationManager" />
  </property>
  <property name="accessDecisionManager">
   <ref local="httpRequestAccessDecisionManager" />
  </property>
  <property name="observeOncePerRequest">
   <value>true</value>
  </property>
  <property name="objectDefinitionSource">
   <value>
    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    PATTERN_TYPE_APACHE_ANT
    /login.jsp =ROLE_ANONYMOUS
    /success.jsp =ROLE_USER
   </value>
  </property>
</bean>

<!-- 用来验证用户名密码是否相符,并赋予相应的角色 -->
<bean id="hibernate3Authentication"
  class="com.fifthlab.demo.dao.authentication.Hibernate3Authentication ">
  <property name="sessionFactory">
   <ref local="sessionFactory" />
  </property>
</bean>

<bean id="anonymousProcessingFilter"
  class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
  <property name="key">
   <value>foobar</value>
  </property>
  <property name="userAttribute">
   <value>anonymousUser,ROLE_ANONYMOUS</value>
  </property>
</bean>

<bean id="httpRequestAccessDecisionManager"
  class="org.acegisecurity.vote.AffirmativeBased">
  <property name="allowIfAllAbstainDecisions">
   <value>false</value>
  </property>
  <property name="decisionVoters">
   <list>
    <ref bean="roleVoter" />
   </list>
  </property>
</bean>

<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter" />
<!-- 下面开始添加 jcaptcha  -->
<bean id="captchaValidationProcessingFilter"
  class="org.acegisecurity.captcha.CaptchaValidationProcessingFilter">
  <property name="captchaService">
   <ref bean="captchaService" />
  </property>
  <property name="captchaValidationParameter">
   <value>j_captcha_response</value>
  </property>
</bean>

<!-- 用来验证图片验证码是否输入正确 --> <bean id="captchaService"
  class="com.fifthlab.demo.dao.authentication.JCaptchaServiceProxyImpl ">
  <property name="jcaptchaService" ref="jcaptchaService" />
</bean>
<bean id="jcaptchaService"
  class="com.octo.captcha.service.image.DefaultManageableImageCaptchaService" />
<!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX acegi part end XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->

</beans>
    先解释一下上面applicationContext.xml中红色的部分是jCaptcha的一个filter,必须放在第二个位置,后面的是 acegi的filter,也就是说,要先验证图片验证码是否正确,再让acegi来验证用户名和密码。蓝色的部分是需要写的几个代码,其中有一个修复 bug的地方,如果不添加那个bean,在运行的时候就会报Cast转型的错误。下面列一下蓝色部分的代码:
FixedCaptchaSecurityContextImpl:
import org.acegisecurity.captcha.CaptchaSecurityContextImpl;
public class FixedCaptchaSecurityContextImpl extends CaptchaSecurityContextImpl {
public int hashCode() {

  if (getAuthentication() == null) {
   return (int) System.currentTimeMillis();
  } else {
   return this.getAuthentication().hashCode();
  }
}

}
Hibernate3Authentication:
import java.util.ArrayList;
import java.util.List;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.hibernate.Criteria;
import org.hibernate.criterion.Expression;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.fifthlab.demo.pojo.Roletest;
import com.fifthlab.demo.pojo.Usertest;
public class Hibernate3Authentication extends HibernateDaoSupport implements UserDetailsService {
public UserDetails loadUserByUsername(final String username)
{
  Criteria criteria = getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(Usertest.class);
  criteria.add(Expression.eq(Usertest.PROP_USERNAME, username));
  List users = criteria.list();
  if (users.size() == 0)
  {
   throw new UsernameNotFoundException("User not found");
  }
  Usertest user = (Usertest) users.get(0);
  // get User roles of this user
  List<Roletest> userRoles = new ArrayList<Roletest>();
  userRoles.add(user.getRoletest());
  GrantedAuthority[] dbAuths = new GrantedAuthority[userRoles.size()];
  if (userRoles.size() == 0)
  {
   throw new U
sernameNotFoundException("User has no GrantedAuthority");
  }
  // grant authority to user
  String roleName = null;
  Roletest role = null;
  for (int i = 0; i < userRoles.size(); i++)
  {
   role = (Roletest) userRoles.get(i);
   if (null != role)
   {
    roleName = role.getRolename();
    dbAuths = new GrantedAuthorityImpl(roleName);   
   }
  }
  
  user.setAuthorities(dbAuths);
  
  return user;
}
}
JCaptchaServiceProxyImpl:
import org.acegisecurity.captcha.CaptchaServiceProxy;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.octo.captcha.service.CaptchaServiceException;
public class JCaptchaServiceProxyImpl implements CaptchaServiceProxy {
   
    private ImageCaptchaService jcaptchaService;
  
    public boolean validateReponseForId(String id, Object response) {
  
      try {
       boolean result = jcaptchaService.validateResponseForID(id, response);
       //System.out.println("id:"+id+"\nresponse:"+response+"\nresult:"+result);
       return result;
  
      } catch (CaptchaServiceException cse) {
        //fixes known bug in JCaptcha
       cse.printStackTrace();
        return false;
      }
    }
  
    public void setJcaptchaService(ImageCaptchaService jcaptchaService) {
      this.jcaptchaService = jcaptchaService;
    }
  }
    接下来是简单的登录页面login.jsp和登录成功后的跳转页面success.jsp:
login.jsp:
<%@ page language="Java" c%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="https://ajax4jsf.dev.java.net/ajax" prefix="a4j"%>
<f:view>
<html>
<head>
<title>hello</title>
</head>
<META HTTP-EQUIV="PRAGMA" C>
<META HTTP-EQUIV="Pragma" C>
<META HTTP-EQUIV="Expires" C>
<body>

<h:form id="form1">
  <h:panelGrid columns="1">
   <h:panelGroup>
    <h:outputLabel value="username:" for="username" />
    <h:inputText id="username" value="#{loginBean.userName}" />
   </h:panelGroup>
   <h:panelGroup>
    <h:outputLabel value="password:" for="password" />
    <h:inputSecret id="password" value="#{loginBean.password}" />
   </h:panelGroup>
   <h:panelGroup>
    <h:outputLabel value="verifying code:" for="verifyingCode" />
    <h:inputText id="verifyingCode" value="#{loginBean.verifyingCode}" />
    <a4j:mediaOutput element="img" cacheable="false" session="false"
        createC id="showPic"
        mimeType="image/jpeg" />
    <a4j:commandLink reRender="showPic" requestDelay="40" >
     <h:outputText value="refresh" />
    </a4j:commandLink>
   </h:panelGroup>
   <h:panelGroup>
    <h:commandButton id="commandButton1" value="Submit"
     action="#{loginBean.authenticate}" />
   </h:panelGroup>
  </h:panelGrid>
</h:form>

</body>
</html>
</f:view>

    其中红色部分是应用了Ajax4jsf这个框架的两个标签,<a4j:mediaOutput> 是表示输出一个媒体,这里我选择的是输出图片,它会异步的产生图片,而不必 和页面载入时同步取图片。而<a4j:commandLink reRender="showPic"> 则是在看不清图片的情况下通过异步的方式刷新上面那个<a4j:mediaOutput> 的图片。
    success.jsp的页面很简单,就是显示一个“Welcome here”的字样,因此不列出来了。
    然后我们看一下页面中用到的backing bean的代码:
LoginBean:
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.fifthlab.demo.dao.authentication.JCaptchaServiceProxyImpl;
public class LoginBean extends HibernateDaoSupport {
private static final long serialVersionUID = 1L;
private String userName;
private String password;
private String verifyingCode;
private AuthenticationManager authenticationManager;
private JCaptchaServiceProxyImpl captchaService;
/**
  * @return 返回用户输入的验证码
  */
public String getVerifyingCode()
{
  return this.verifyingCode;
}

/**
  * @param verifyingCode 设置图片验证码
  */
public void setVerifyingCode(String verifyingCode)
{
  this.verifyingCode = verifyingCode;
}

/**
  * @return 返回captchaService来验证图片验证码
  */
public JCaptchaServiceProxyImpl getCaptchaService()
{
  return this.captchaService;
}

/**
  * @param captchaService 设置图片验证码服务
  */
public void setCaptchaService(JCaptchaServiceProxyImpl captchaService)
{
  this.captchaService = captchaService;
}

/**
  * @return 返回密码
  */
public String getPassword()
{
  return password;
}
/**
  * @param password 设置密码
  *            
  */
public void setPassword(String password)
{
  this.password = password;
}
/**
  * @return 返回用户名
  */
public String getUserName()
{
  return userName;
}
/**
  * @pa
ram userName 设置用户名
  *            
  */
public void setUserName(String userName)
{
  this.userName = userName;
}
/**
  * @return 返回验证管理器
  */
public AuthenticationManager getAuthenticationManager()
{
  return authenticationManager;
}
/**
  * @param authenticationManager 设置验证管理器
  *            
  */
public void setAuthenticationManager(AuthenticationManager authenticationManager)
{
  this.authenticationManager = authenticationManager;
}

public String authenticate()
{
  try
  {
   String sessionid = ((HttpSession)FacesContext.getCurrentInstance()
           .getExternalContext()
           .getSession(false)).getId();
   boolean captchaResult = getCaptchaService().validateReponseForId(sessionid, getVerifyingCode());//验证图片验证码
     UsernamePasswordAuthenticationToken authReq = new UsernamePasswordAuthenticationToken(
     getUserName(), getPassword());
   //验证用户名和密码
   Authentication auth = getAuthenticationManager().authenticate(authReq);
   String result = "failure";
   if(auth.isAuthenticated() == true && captchaResult)
   {//如果图片验证码和帐户全部验证通过
    result = "succeed";
    //把验证信息保存的上下文中
    SecurityContext secCtx = SecurityContextHolder.getContext();
    secCtx.setAuthentication(auth);
   }
      
   return result;
  }
  catch(AuthenticationException e)
  {
   e.printStackTrace();
   return "failure";
  }
}
}

CaptchaImageBean:
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.octo.captcha.service.image.ImageCaptchaService;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class CaptchaImageBean {
static final long serialVersionUID = 1L;
private ImageCaptchaService jcaptchaService;

public void setJcaptchaService(ImageCaptchaService jcaptchaService) {
  this.jcaptchaService = jcaptchaService;
}

public void paint(OutputStream out, Object data) throws IOException
{
  byte[] captchaChallengeAsJpeg = null;
  ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
  
  HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance()
        .getExternalContext().getRequest();
  
  String captchaId = ((HttpSession)FacesContext.getCurrentInstance()
    .getExternalContext()
    .getSession(false)).getId();
  
  BufferedImage challenge = jcaptchaService.getImageChallengeForID(
    captchaId, request.getLocale());
  JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream);
  jpegEncoder.encode(challenge);
  captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
  
  jpegOutputStream.close();
  out.write(captchaChallengeAsJpeg);
  out.flush();
  out.close();
}
}
    最后当然是配置faces-config.xml了,里面配置了和Spring的整合、导航、managed bean等等:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>
<application>
  <variable-resolver>
   org.springframework.web.jsf.DelegatingVariableResolver
  </variable-resolver>
</application>
<managed-bean>
  <managed-bean-name>loginBean</managed-bean-name>
  <managed-bean-class>com.fifthlab.demo.backingbean.LoginBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
   <property-name>authenticationManager</property-name>
   <value>#{authenticationManager}</value>
  </managed-property>
  <managed-property>
   <property-name>captchaService</property-name>
   <value>#{captchaService}</value>
  </managed-property>
</managed-bean>

<managed-bean>
  <managed-bean-name>captchaImageBean</managed-bean-name>
  <managed-bean-class>com.fifthlab.demo.backingbean.CaptchaImageBean</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
   <property-name>jcaptchaService</property-name>
   <value>#{jcaptchaService}</value>
  </managed-property>
</managed-bean>

<navigation-rule>
  <from-view-id>/login.jsp</from-view-id>
  <navigation-case>
   <from-outcome>succeed</from-outcome>
   <to-view-id>/success.jsp</to-view-id>
  </navigation-case>
  <navigation-case>
   <from-outcome>failure</from-outcome>
   <to-view-id>/login.jsp</to-view-id>
  </navigation-case>
</navigation-rule>
</faces-config>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值