springmvc + shiro + Jpa 整合(一)登录 退出

一 、底层环境搭建

1、项目结构:



 

2、shrio的maven依赖

<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>  
		    <groupId>org.apache.shiro</groupId>  
		    <artifactId>shiro-web</artifactId>  
		    <version>1.2.2</version>  
		</dependency>  
		<dependency>  
		    <groupId>org.apache.shiro</groupId>  
		    <artifactId>shiro-spring</artifactId>  
		    <version>1.2.2</version>  
		</dependency>  
		<dependency>  
		    <groupId>org.apache.shiro</groupId>  
		    <artifactId>shiro-ehcache</artifactId>  
		    <version>1.2.2</version>  
		</dependency> 

3、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_3_0.xsd" version="3.0">
  <display-name>TestShiro</display-name>
  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
     <!-- 防止发生java.beans.Introspector内存泄露,应将它配置在ContextLoaderListener的前面 -->  
    <!-- 详细描述见http://blog.csdn.net/jadyer/article/details/11991457 -->  
    <listener>  
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
    </listener>  
    
     <!-- 实例化Spring容器 -->  
    <!-- 应用启动时,该监听器被执行,它会读取Spring相关配置文件,其默认会到WEB-INF中查找applicationContext.xml -->  
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- 配置编码过滤器 -->
    <filter>
        <filter-name>characterEncodingFilter</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>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 -->  
    <!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> -->  
    <!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 -->  
    <!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 -->  
    <filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
        <init-param>  
            <!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->  
            <param-name>targetFilterLifecycle</param-name>  
            <param-value>true</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>shiroFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    
    
    
    <!-- SpringMVC核心分发器 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>


    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

2、applicationContext.xml的配置

<?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/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="
                    http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                    http://www.springframework.org/schema/tx 
                    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
                    http://www.springframework.org/schema/aop 
                    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
                    http://www.springframework.org/schema/context      
                    http://www.springframework.org/schema/context/spring-context-3.1.xsd
                    http://www.springframework.org/schema/cache 
                    http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
                    http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd 
                    http://www.springframework.org/schema/data/jpa 
                    http://www.springframework.org/schema/data/jpa/spring-jpa.xsd" 
                    default-lazy-init="true">

    <context:component-scan base-package="com.libm" >
    	 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
	</context:component-scan>        
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- c3p0连接 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass" value="${jdbc.driverClassName}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
	
    <!-- JPA实体管理器工厂 -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
        
        <!-- 加入定制化包路径, 此种写法不需要配置persistence.xml,会自动扫描实体类 -->
        <property name="packagesToScan" value="com.libm.domain" />

        <property name="jpaProperties">
            <props>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop><!-- validate/update/create -->
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
                
                <!-- 建表的命名规则 -->
                <!-- <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop> -->
                
            </props>
        </property>
    </bean>
    
    <!-- 设置JPA实现厂商的特定属性 -->
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
    </bean>
    
    <!-- Jpa 事务配置 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-- Spring Data Jpa配置 -->
    <jpa:repositories base-package="com.libm"  transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
    
    <!-- 使用annotation定义事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
    
    
    
    <!-- /////////////////////////////////////////////////////////////////////////////////// -->
    <!-- shiro -->
    
    <bean id="myShiro" class="com.libm.service.MyShiro"></bean>
     <!-- 配置权限管理器 -->  
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">    
        <!-- ref对应我们写的realm  MyShiro -->  
        <property name="realm" ref="myShiro"/>    
        <!-- 使用下面配置的缓存管理器 -->  
        <property name="cacheManager" ref="cacheManager"/>    
    </bean>  
      
    <!-- 配置shiro的过滤器工厂类,id- shiroFilter要和我们在web.xml中配置的过滤器一致 -->  
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">   
        <!-- 调用我们配置的权限管理器 -->   
        <property name="securityManager" ref="securityManager"/>   
        <!-- 配置我们的登录请求地址 -->   
        <property name="loginUrl" value="/login.do"/>    
        <!-- 配置我们在登录页登录成功后的跳转地址,如果你访问的是非/login地址,则跳到您访问的地址 -->  
        <property name="successUrl" value="/home.do"/>    
        <!-- 如果您请求的资源不再您的权限范围,则跳转到/403请求地址 -->  
        <!-- <property name="unauthorizedUrl" value="/403"/> -->    
        <!-- 权限配置 -->  
        <property name="filterChainDefinitions">    
            <value>    
                <!-- anon表示此地址不需要任何权限即可访问 -->  
                /index.do = anon
                /login.do = authc 
                /home.do = authc 
            </value>    
        </property>    
    </bean>  
    
      
    <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />    
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />   
 
    
</beans>

3、spring-mvc.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation=" 
                http://www.springframework.org/schema/beans 
                http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
                http://www.springframework.org/schema/context 
                http://www.springframework.org/schema/context/spring-context-3.1.xsd 
                http://www.springframework.org/schema/mvc 
                http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
                http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd" >
    
    <!-- 启动springMVC注解 -->
    <mvc:annotation-driven/>
    <context:component-scan base-package="com.libm">
      	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />   
    	<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> 
    </context:component-scan>
   
    
    <!-- 自定义tiles -->
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer"> 
    	<property name="definitions"> 
    		<list> 
    			<value>classpath:titles.xml</value> 
    		</list> 
    	</property> 
    </bean> 
    <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
    	<property name="viewClass"> 
    		<value> org.springframework.web.servlet.view.tiles3.TilesView </value> 
    	</property> 
    </bean>
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!-- <mvc:interceptors>
    	<mvc:interceptor>
    		<mvc:mapping path="/*.do"/>
    		<mvc:exclude-mapping path="/index.do"/>
    		<mvc:exclude-mapping path="/login.do"/>
    		<bean class="com.libm.interceptor.LoginInterceptor" />
    	</mvc:interceptor>
    </mvc:interceptors> -->
    
    <!-- 静态资源加载 -->
    <mvc:resources location="/css/" mapping="/css/**" />
    <mvc:resources location="/js/" mapping="/js/**"/>
    <mvc:resources location="/images/" mapping="/images/**" />
    
</beans>

一 、实现

1、实体类

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;


@Entity
public class User {
	private Integer id;  
    private String username;  
    private String password;  
    
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
	
    
}

2、 自定义MyShiro 身份验证

import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import com.libm.domain.User;

@Service
public class MyShiro extends AuthorizingRealm {
	
	@Autowired
	private UserService userService;
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		// UsernamePasswordToken对象用来存放提交的登录信息
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String username = token.getUsername();
		
		String password = String.valueOf(token.getPassword());
		// 查出是否有此用户 ,此处查询数据库
		User user = userService.chekLogin(username,password);
		if (user != null) {
			// 若存在,将此用户存放到登录认证info中
			return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
		}
		return null;
	}

}

3、index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>

</head>
<body>
<form action="login.do" method="post">
	<div align="center">
		<table>
			<tr>
				<td>username</td>
				<td><input type="text" name="username"/> </td>
			</tr>
			<tr>
				<td>password</td>
				<td><input type="password" name="password"/> </td>
			</tr>
		</table>
		<button type="submit" id="loginBtn">login</button>
	</div>
	
</form>
</body>
</html>

4、LoginController

package com.libm.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.libm.domain.User;

@Controller
public class LoginController {
	
	@RequestMapping(value="login")
	public String login(User user){
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword());
		try{
			token.setRememberMe(true);
			subject.login(token); 
			return "redirect:/home.do";
		}catch(Exception e){
			return "redirect:/index.do";
		}
		
	}
	
	@RequestMapping(value="home")
	public ModelAndView home(){
		ModelAndView mv = new ModelAndView("home");
		
		return mv;
	}
	@RequestMapping(value="index")
	public ModelAndView index(){
		ModelAndView mv = new ModelAndView("index");
		
		return mv;
	}
	@RequestMapping(value="logout")
	public String logout(){
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return "redirect:/index.do";
	}
	
	
	
	
}

猜你喜欢

转载自1960370817.iteye.com/blog/2371339
今日推荐