EhCache和Spring的结合使用

这里我使用的View层是SpringMvc,之所以没有因为Struts2,是因为SpringMvc更为方便一点,SpringMvc确实是一个非常之方便的前端框架,但是我不是太喜欢用,就像一个东西你用习惯了之后很难去改变一样。如果叫你不用ecplise去开发,你说你会不会哭一样。但是新技术更新不止,逼着我们硬着头皮去学。这也是没有办法的事情

上篇写了之后,隔了这么长的时间去写是因为我上个星期比较忙,加上通宵上线了一夜,好几天都没有恢复过来 。好了废话不多说了,看下代码 

首先看下web.xml

<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <listener>
  		<listener-class>
  			org.springframework.web.context.request.RequestContextListener
  		</listener-class>
  </listener>
  
  <servlet>
  	<servlet-name>dispatcher</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
 	<servlet-name>dispatcher</servlet-name>
 	<url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <filter>
		<filter-name>encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encoding</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>
</span>
注意这里的dispatcher如果名字是这个,且没有初始化的话,SpringMvc框架会默认去读/WEB-INF/dispatcher-servlet.xml

也可以自己去初始化

<span style="font-size:14px;"> <servlet>
<span style="white-space:pre">		</span><servlet-name>dispatcher</servlet-name>
<span style="white-space:pre">		</span><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<span style="white-space:pre">		</span> <span style="white-space:pre">	</span><init-param>
    <span style="white-space:pre">			</span><param-name>contextConfigLocation</param-name>
  <span style="white-space:pre">				</span><param-value>/WEB-INF/conf/*-servlet.xml</param-value>
   <span style="white-space:pre">			</span></init-param>
<span style="white-space:pre">		</span><load-on-startup>1</load-on-startup>
<span style="white-space:pre">	</span></servlet>
<span style="white-space:pre">	</span><servlet-mapping>
<span style="white-space:pre">		</span><servlet-name>dispatcher</servlet-name>
<span style="white-space:pre">		</span><url-pattern>/</url-pattern>
<span style="white-space:pre">	</span></servlet-mapping></span>
它会读到/WEB-INF/config/*-servlet.xml文件

我们来看下dispatcher-servlet.xml

<span style="font-size:14px;"><?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:p="http://www.springframework.org/schema/p"  
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"  
	xmlns:mvc="http://www.springframework.org/schema/mvc"  
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
	http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
	
    <context:component-scan base-package="com.tgb.web.controller"/>
    
    <context:component-scan base-package="com.huawei.action"/>
    <mvc:annotation-driven/>
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    	<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
    	<property name="prefix" value="/WEB-INF/jsp/"></property>
    	<property name="suffix" value=".jsp"></property>
    	
    </bean>
    <!-- 设置multipartResolver才能完成文件上传 -->
   	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  		<property name="maxUploadSize" value="5000000" /> 
  	</bean>
   	
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    	<property name="exceptionMappings">
    		<props>
    			<prop key="com.tgb.web.controller.UserException">error</prop>
    			<prop key="java.lang.NullPointException">exception</prop>
    		</props>
    	</property>
    </bean>
    
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="/WEB-INF/conf/ehcache.xml"/>
	</bean> 
	
	<bean id="demoCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
		<property name="cacheManager" ref="cacheManager"/>
		<property name="cacheName" value="demoCache"/>
		
	</bean>
	
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/person/*"/><!-- 如果不配置或/*,将拦截所有的controller -->
			<bean class="com.huawei.interceptor.OrgMgtInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors> 
</beans> 
</span>

<context:component-scan base-package="com.tgb.web.controller"/>

在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean

注意:如果配置了<context:component-scan>那么<context:annotation-config/>标签就可以不用再xml中配置了,因为前者包含了后者

<mvc:annotation-driven/>这个springmvc的组件,这里就不细说了,因为说了感觉没有太大的意义,把这个说清了,我这篇Ehcache就不用写下去了,因为去搞SpringMvc去了,就是可以使用注入,方便操作在spring3.0以后才有的

重点看下这个

<span style="font-size:14px;"><bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation" value="/WEB-INF/conf/ehcache.xml"/>
	</bean> 
	
	<bean id="demoCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
		<property name="cacheManager" ref="cacheManager"/>
		<property name="cacheName" value="demoCache"/>
		
	</bean>
	
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/person/*"/><!-- 如果不配置或/*,将拦截所有的controller -->
			<bean class="com.huawei.interceptor.OrgMgtInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors> </span>

看下EhCacheManagerFactroyBean的SpringApi


这个就不翻译了。简单的英语

我们把所有的配置文件都放到/WEB-INF/conf下。这样方便管理

在看下EhCacheFactoryBean,我们首先把EhCacheManagerFactroyBean,然后设置下cacheName设置为我们自己设定的名字,下面是ehcache.xml配置文件

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="ehcache.xsd">
  <diskStore path="java.io.tmpdir"/>
  <defaultCache
    maxElementsInMemory="10000"
    maxElementsOnDisk="0"
    eternal="true"
    overflowToDisk="true"
    diskPersistent="false"
    timeToIdleSeconds="0"
    timeToLiveSeconds="0"
    diskSpoolBufferSizeMB="50"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LFU"
    />
  <cache name="demoCache"
    maxElementsInMemory="100"
    maxElementsOnDisk="0"
    eternal="true"
    overflowToDisk="true"
    diskPersistent="false"
    timeToIdleSeconds="119"
    timeToLiveSeconds="119"
    diskSpoolBufferSizeMB="50"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LFU"
    />
    <!-- 
    name:Cache的名称,必须是唯一的(ehcache会把这个cache放到hashmap里)
    maxElementsInMemory:内存中保持的对象数量
    maxElementsOnDisk:DiskStore中保持的对象数量,默认为0,表示不限制
    eternal:是否是永恒的数据,如果是,则它的超过设置会被忽略
    overflowToDisk:如果内存中数量超过maxElementsInMermory限制,是否要缓存到磁盘上
    diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效,默认为false
    timeToIdleSeconds:对象空闲时间,指对象在多长时间没有被访问就会失效。只对eternal为false时有效,默认为0,表示一直可以访问
    timeToLiveSeconds:对象存活时间,指对象从创建到失效所需要的时间,只对eternal为false时有效,默认值为0,表示一直可以访问
    diskSpoolBufferSizeMB:DiskStore使用的磁盘大小,默认值为30m。每个cache使用各自的DiskStore
    memoryStoreEvictionPolicy:如果内存中数据超过内存限制,向磁盘缓存时的策略。默认值为LRU,可选 FIFO,LFU
     -->
</ehcache>
上面关于一些字段的定义我也写得很清楚了

下面是

<span style="font-size:14px;"><mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/person/*"/><!-- 如果不配置或/*,将拦截所有的controller -->
			<bean class="com.huawei.interceptor.OrgMgtInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors> </span>
上面也写得比较清楚了,这些写的目的是为了拦截URL /person/*下的所有controller

要记得清楚这里是先写OrgMgtInterceptor之后才进/person/*下的方法,所以以登录页面来说,初始化页面肯定不能去拦截,我在写的时候就写错了,所以在方法里补救了下

来看下OrgMgtInterceptor

package com.huawei.interceptor;

import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.InetAddress;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.huawei.dao.Person;

public class OrgMgtInterceptor implements HandlerInterceptor{
	@Resource(name="demoCache")
	private Cache cache;
	
	public Cache getCache() {
		return cache;
	}

	public void setCache(Cache cache) {
		this.cache = cache;
	}

	public void afterCompletion(HttpServletRequest arg0,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		//执行顺序:3、afterCompletion
	}

	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2, ModelAndView arg3) throws Exception {
		//执行顺序: 2、
	}

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object arg2) throws Exception { 
		String url = request.getRequestURL().toString();
		url = url.substring(url.lastIndexOf("/")+1, url.length());
		if("login".equals(url)||"login1".equals(url)||"main2".equals(url)){
			return true;
		}
		Person person = (Person) request.getSession().getAttribute("name");
		if("boss".equals(person.getName())&&"123456".equals(person.getPassword()))
		{	
			 response.sendRedirect(request.getContextPath() + "/person/main2");   
			return false;
		}
		else
		{
			Element elementPerson = cache.get(person.getName());
			if(elementPerson!=null)
			{
				if(person.getPassword().equals(((Person) elementPerson.getValue()).getPassword()))
				{
					return true;
				}
				response.sendRedirect(request.getContextPath() + "/person/login");
				return false;
			}
			else
			{
				response.sendRedirect(request.getContextPath() + "/person/login");
				return false;
			}
			
		}	
	}
}

这里我们首先要继承HandlerInterceptor

其次我们要实现的是

public boolean preHandle这个方法就行了

我写这个的目的是个简单的应用,就是登录之后我把用户存放在ehcache中,如果是boss用户的话先验证,然后去到main2 Action中

如果是普通的用户,会先在ehcache中校验用户名和密码是否正确,然后去到main1 Action中。

package com.huawei.action;


import java.io.Serializable;


import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


import com.huawei.dao.Person;
import com.huawei.interceptor.OrgMgtInterceptor;




@Controller
@RequestMapping("/person")
public class PersonLoginAction {
<span style="white-space:pre">	</span>@Resource(name="demoCache")
<span style="white-space:pre">	</span>private Cache cache;
<span style="white-space:pre">	</span>public Cache getCache() 
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>return cache;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>public void setCache(Cache cache) 
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>this.cache = cache;
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@RequestMapping(value="/login",method=RequestMethod.GET)
<span style="white-space:pre">	</span>public String login()
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>Person person = new Person();
<span style="white-space:pre">		</span>person.setName("chenzj");
<span style="white-space:pre">		</span>person.setPassword("123456");
<span style="white-space:pre">		</span>Person person1 = new Person();
<span style="white-space:pre">		</span>person1.setName("zhaoshuo");
<span style="white-space:pre">		</span>person1.setPassword("123456");
<span style="white-space:pre">		</span>Person person2 = new Person();
<span style="white-space:pre">		</span>person2.setName("zhengdaheng");
<span style="white-space:pre">		</span>person2.setPassword("123456");
<span style="white-space:pre">		</span>Element elementPerson = new Element(person.getName(),person);
<span style="white-space:pre">		</span>cache.put(elementPerson);
<span style="white-space:pre">		</span>elementPerson = new Element(person1.getName(),person1);
<span style="white-space:pre">		</span>cache.put(elementPerson);
<span style="white-space:pre">		</span>elementPerson = new Element(person2.getName(),person2);
<span style="white-space:pre">		</span>cache.put(elementPerson);
<span style="white-space:pre">		</span>return "person/login";
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>@RequestMapping(value="/login1",method=RequestMethod.POST)
<span style="white-space:pre">	</span>public String login(String name,String password,HttpSession session){
<span style="white-space:pre">		</span>Person person = new Person();
<span style="white-space:pre">		</span>person.setName(name);
<span style="white-space:pre">		</span>person.setPassword(password);
<span style="white-space:pre">		</span>session.setAttribute("name", person);
<span style="white-space:pre">		</span>return "redirect:/person/main1";
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>@RequestMapping(value="/main1",method=RequestMethod.GET)
<span style="white-space:pre">	</span>public String login1(){
<span style="white-space:pre">		</span>return "person/main1";
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>@RequestMapping(value="/main2",method=RequestMethod.GET)
<span style="white-space:pre">	</span>public String login2(){
<span style="white-space:pre">		</span>return "person/main2";
<span style="white-space:pre">	</span>}
}<span style="font-family: Arial;"></span>

在去login的时候我先手动把用户塞到ehcache中,这是测试随便写写,怎么方便怎么写嘛

看到login,login1,main2是不拦截的,这也是我设计的不好,但是本人比较懒,所以就懒得改了

login1提交时读取name和password放到session中

在往main1重定向时会进到interceptor中,关于重定向和转发的根本,会在下一篇中讲到

这时候可以去看看OrgMgtInterceptor中写得非常清楚。这里也就不多说了



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值