商务综合管理-day2~5 分页实现,shiro(验证授权,MD5Hash加密),struts2全局异常处理


 

Oracle创建表空间,用户及授权

--创建表空间
create tablespace jk
datafile 'E:\Develop_Index\oraclePlace\jkP\jkP.dbf'
size 50M
autoextend on
next 10M

--创建用户
create user heima
identified by heima
default tablespace jk

--授权
grant dba to heima
--或者授权
grant connect,resource to heima


 

分页实现说明

 



 

代码


/**
 * 分页辅助类:对分页的基本数据进行一个简单的封装 用来传递分页参数和查询参数params
 */
public class Page<T> {
	private int pageNo = 1; // 页码,默认是第一页
	private int pageSize = SysConstant.PAGE_SIZE; // 每页显示的记录数,默认是10
	private int totalRecord; // 总记录数
	private int totalPage; // 总页数
	private List<T> results; // 对应的当前页记录
	private Map<String, Object> params = new HashMap<String, Object>(); // 其他的参数我们把它分装成一个Map对象

	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getTotalRecord() {
		return totalRecord;
	}

	public void setTotalRecord(int totalRecord) {
		this.totalRecord = totalRecord;
		// 在设置总页数的时候计算出对应的总页数,在下面的三目运算中加法拥有更高的优先级,所以最后可以不加括号。
		int totalPage = totalRecord % pageSize == 0 ? totalRecord / pageSize : totalRecord / pageSize + 1;
		this.setTotalPage(totalPage);
	}

	public int getTotalPage() {
		return totalPage;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}

	public List<T> getResults() {
		return results;
	}

	public void setResults(List<T> results) {
		this.results = results;
	}

	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}

	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Page [pageNo=").append(pageNo).append(", pageSize=").append(pageSize).append(", results=")
				.append(results).append(", totalPage=").append(totalPage).append(", totalRecord=").append(totalRecord)
				.append("]");
		return builder.toString();
	}

	/* 页面链接 */
	public String url; // 分页按钮中的转向链接

	public void setUrl(String url) {
		this.url = url;
	}

	public String links;

	public String getLinks() {
		StringBuffer sBuf = new StringBuffer();
		int curPageNo = this.pageNo; // 当前页

		sBuf.append("<span class=\"noprint\" style=\"padding:5px;\">");

		// 利用js动态设置分页页码
		sBuf.append("<script language=\"javascript\">");
		sBuf.append("	function setPageNo( value ){");
		sBuf.append("		document.getElementById(\"page.pageNo\").value = value;");
		// sBuf.append(" alert(document.getElementById(\"pageNo\").value);");
		sBuf.append("	}");
		sBuf.append("</script>");
		sBuf.append("<input type=\"hidden\" id=\"page.pageNo\" name=\"page.pageNo\" value=\"").append(curPageNo)
				.append("\">"); // 分页参数:当前页隐藏域

		sBuf.append(" 第").append(curPageNo).append("页 / 共").append(this.totalPage).append("页 ");
		sBuf.append(" 总共").append(this.totalRecord).append("条记录 每页").append(this.pageSize).append("条记录 ");

		sBuf.append("<a href=\"#").append("\" οnclick=\"setPageNo(1);formSubmit('").append(url).append("','_self')");
		sBuf.append("\">[首页]");
		sBuf.append("</a> ");

		if (this.pageNo <= 1) {
			curPageNo = 1;
		} else {
			curPageNo = this.pageNo - 1;
		}
		sBuf.append("<a href=\"#").append("\" οnclick=\"setPageNo(").append(curPageNo).append(");formSubmit('")
				.append(url).append("','_self')");
		sBuf.append("\">[上一页]");
		sBuf.append("</a> ");

		if (this.pageNo >= this.totalPage) {
			curPageNo = this.totalPage;
		} else {
			curPageNo = this.pageNo + 1;
		}
		sBuf.append("<a href=\"#").append("\" οnclick=\"setPageNo(").append(curPageNo).append(");formSubmit('")
				.append(url).append("','_self')");
		sBuf.append("\">[下一页]");
		sBuf.append("</a> ");

		sBuf.append("<a href=\"#").append("\" οnclick=\"setPageNo(").append(this.totalPage).append(");formSubmit('")
				.append(url).append("','_self')");
		sBuf.append("\">[末页]");
		sBuf.append("</a> ");

		sBuf.append("</span>");

		return sBuf.toString();
	}

}


 

 

Shiro框架的应用 登陆验证授权及权限控制

 

权限相关7张表


 

pom jar包引用

	    <!-- shiro -->
	     <!-- apache shiro dependencies -->
	     <dependency>
	    	<groupId>org.apache.shiro</groupId>
	    	<artifactId>shiro-all</artifactId>
	    	<version>${shiro.version}</version>
	     </dependency>


 

web.xml

   <!-- Shiro Security filter  filter-name这个名字的值将来还会在spring中用到  -->
   <!-- 注意:shiro的filter必须在struts2的filter之前,否则action无法创建 -->

    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <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>


applicationContext.xml

	<!--Shiro安全框架产生代理子类的方式: 使用cglib方式-->
	<aop:aspectj-autoproxy proxy-target-class="true" />



ehcache-shiro.xml 

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="shiroCache">

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            />
</ehcache>


 

applicationContext-shiro.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:p="http://www.springframework.org/schema/p"  
	xmlns:context="http://www.springframework.org/schema/context"   
	xmlns:tx="http://www.springframework.org/schema/tx"  
	xmlns:aop="http://www.springframework.org/schema/aop"  
	xsi:schemaLocation="http://www.springframework.org/schema/beans    
	http://www.springframework.org/schema/beans/spring-beans.xsd    
	http://www.springframework.org/schema/aop    
	http://www.springframework.org/schema/aop/spring-aop.xsd    
	http://www.springframework.org/schema/tx    
	http://www.springframework.org/schema/tx/spring-tx.xsd    
	http://www.springframework.org/schema/context    
	http://www.springframework.org/schema/context/spring-context.xsd">
	
	<description>Shiro配置文件</description>
	<!-- SecurityManager配置 -->
	<!-- 配置Realm域 -->
	<!-- 密码比较器 -->
	<!-- 代理如何生成? 用工厂来生成Shiro的相关过滤器-->
	<!-- 配置缓存:ehcache缓存 -->
	<!-- 安全管理 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
        <property name="realm" ref="authRealm"/><!-- 引用自定义的realm -->
        <!-- 缓存 -->
        <property name="cacheManager" ref="shiroEhcacheManager"/>
    </bean>

    <!-- 自定义权限认证 -->
    <bean id="authRealm" class="cn.itcast.jk.shiro.AuthRealm">
		<property name="userService" ref="userService"/>
		<!-- 自定义密码加密算法  -->
		<property name="credentialsMatcher" ref="passwordMatcher"/>
	</bean>
	
	<!-- 设置密码加密策略 md5hash -->
	<bean id="passwordMatcher" class="cn.itcast.jk.shiro.CustomCredentialsMatcher"/>

    <!-- filter-name这个名字的值来自于web.xml中filter的名字 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!--登录页面  -->
        <property name="loginUrl" value="/index.jsp"></property>
        <!-- 登录成功后 -->      
        <property name="successUrl" value="/home.action"></property>
        <property name="filterChainDefinitions">
            <!-- /**代表下面的多级目录也过滤 -->
            <value>
				/index.jsp* = anon
				/home* = anon
				/sysadmin/login/login.jsp* = anon
				/sysadmin/login/logout.jsp* = anon
				/login* = anon
				/logout* = anon
				/components/** = anon
				/css/** = anon
				/images/** = anon
				/js/** = anon
				/make/** = anon
				/skin/** = anon
				/stat/** = anon
				/ufiles/** = anon
				/validator/** = anon
				/resource/** = anon
				/** = authc
				/*.* = authc
            </value>
        </property>
    </bean>

    <!-- 用户授权/认证信息Cache, 采用EhCache  缓存 -->
    <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
    </bean>

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!-- 生成代理,通过代理进行控制 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
          depends-on="lifecycleBeanPostProcessor">
        <property name="proxyTargetClass" value="true"/>
    </bean>
    
    <!-- 安全管理器 -->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager"/>
    </bean>
	
</beans>








MD5Hash散列加密及shiro自定义密码比较器

 

加密工具类

org.apache.shiro.crypto.hash.Md5Hash.Md5Hash(Object source,Object salt, int hashIterations)

 

public class Encrypt {
	/*
	 * 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,
	 * 常见的散列算法如MD5、SHA等。一般进行散列时最好提供一个salt(盐),比如加密密码“admin”,
	 * 产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,
	 * 可以到一些md5解密网站很容易的通过散列值得到密码“admin”,
	 * 即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,
	 * 如用户名和ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。
	 */
	
	//高强度加密算法,不可逆
	public static String md5(String password, String salt){
		return new Md5Hash(password,salt,2).toString();
	}
	
	public static void main(String[] args) {
		System.out.println(new Md5Hash("123456","zhangsan"+"cgx",5).toString());
	}
}

 

自定义密码比较器

public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {

	//密码比较的方法   token代表用户在界面输入的用户名和密码     info代表从数据库中得到加密数据
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
		//1.向下转型 
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		
		//2.将用户在界面输入的原始密码加密
		Object pwd = Encrypt.md5(new String(upToken.getPassword()), upToken.getUsername());
		
		//3.取出数据库中加密的密码
		Object dbPwd = info.getCredentials();
		
		return this.equals(pwd, dbPwd);
	}
}


 

实现shiro登陆校验及授权

 




 

登陆方法

	public String login() throws Exception {
		
		if(UtilFuns.isEmpty(username)){
			return "login";
		}
		
		try {
			//1.得到Subject
			Subject subject = SecurityUtils.getSubject();
			//2.调用登录方法
			UsernamePasswordToken token = new UsernamePasswordToken(username, password);
			subject.login(token);//当这一代码执行时,就会自动跳入到AuthRealm中认证方法
			
			//3.登录成功时,就从Shiro中取出用户的登录信息
			User user = (User) subject.getPrincipal();
			
			//4.将用户放入session域中
			session.put(SysConstant.CURRENT_USER_INFO, user);
			
		} catch (Exception e) {
			e.printStackTrace();
			request.put("errorInfo", "对不起,用户名或密码错误!");
			return "login";
		}
		return SUCCESS;
	}



Realm自定义安全数据桥() 

public class AuthRealm extends AuthorizingRealm {

	private UserService userService;
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	//授权   当jsp页面出现Shiro标签时,就会执行授权方法
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
		System.out.println("授权");
		User user = (User) pc.fromRealm(this.getName()).iterator().next();//根据realm的名字去找对应的realm
		
		Set<Role > roles = user.getRoles();//对象导航
		List<String> permissions = new ArrayList<String>();
		for(Role role :roles){
			//遍历每个角色 
			Set<Module> modules = role.getModules();//得到每个角色下的模块列表
			for(Module m :modules){
				permissions.add(m.getName());
			}
		}
		
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermissions(permissions);//添加用户的模块(权限)
		return info;
	}
	//认证   token 代表用户在界面输入的用户名和密码
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("认证");
		
		//1.向下转型
		UsernamePasswordToken upToken  = (UsernamePasswordToken) token;
		
		//2.调用业务方法,实现根据用户名查询
		String hql = "from User where userName=?";
		List<User> list = userService.find(hql, User.class, new String[]{upToken.getUsername()});
		if(list!=null && list.size()>0){
			User user = list.get(0);
			AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
			return info;   //此处如果返回,就会立即进入到密码比较器
		}
		
		return null;//就会出现异常
	}
	
}





shiro标签使用 

	 <!-- 当jsp页面碰到shiro标签时就执行AuthRealm中授权方法 -->
	 <shiro:hasPermission name="系统首页">
	<span id="topmenu" οnclick="toModule('home');">系统首页</span><span id="tm_separator"></span>
	</shiro:hasPermission>
	<shiro:hasPermission name="货运管理">
		<span id="topmenu" οnclick="toModule('cargo');">货运管理</span><span id="tm_separator"></span>
	</shiro:hasPermission>
	<shiro:hasPermission name="统计分析">
	<span id="topmenu" οnclick="toModule('stat');">统计分析</span><span id="tm_separator"></span>
	</shiro:hasPermission>
	<shiro:hasPermission name="基础信息">
	<span id="topmenu" οnclick="toModule('baseinfo');">基础信息</span><span id="tm_separator"></span>
	</shiro:hasPermission>
	<shiro:hasPermission name="系统管理">
	<span id="topmenu" οnclick="toModule('sysadmin');">系统管理</span>
	</shiro:hasPermission>
	<shiro:hasPermission name="流程管理">
	<span id="topmenu" οnclick="toModule('activiti');">流程管理</span>
	</shiro:hasPermission> 





struts2全局异常处理 

 

1.自定义异常处理类

 

public class SysException extends Exception {

private String message;

public String getMessage() {

return message;

}

public SysException(String message) {

this.message = message;

}

}

 

2.struts.xml中进行全局异常的配置

<!-- 配置全局异常 sysExceptionerror -->

<global-results>

<result name="sysException">/WEB-INF/pages/error.jsp</result>

<result name="error">/WEB-INF/pages/error.jsp</result>

</global-results>

<global-exception-mappings>

<exception-mapping result="sysException" exception="cn.itcast.jk.exceptioin.SysException"/>

<exception-mapping result="error" exception="java.lang.Exception"/>

</global-exception-mappings>

 

3.pages/error.jsp页面的加入

<%@ page contentType="text/html;charset=UTF-8" isErrorPage="true" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Error Page</title>
    <script language="javascript">
        function showDetail()
        {
            var elm = document.getElementById('detail_system_error_msg');
            if(elm.style.display == '') {
                elm.style.display = 'none';
            }else {
                elm.style.display = '';
            }
        }
    </script>
</head>

<body style="font-family:微软雅黑;">

<div id="content" style="text-align:left;">

<table>
<tr>
	<td><img alt="system internal error" src="${pageContext.request.contextPath }/images/error01.jpg"/></td>

	
	
	<br>  
	<b>错误信息:</b>
 	
 	<div style="color:blue;padding:15px;">
 		<s:property value="exception.message"/>
 	</div>
    <button οnclick="history.back();">返回</button>


    <p><a href="#" οnclick="showDetail();">点击这里查看具体错误消息</a>,
	<br/>
	报告以下错误消息给系统管理员,可以更加快速的解决问题;
	<br/>联系电话:120
	</p>

	</td>
</tr>
</table>

	<div id="detail_system_error_msg" style="display:none;text-align:left;padding-bottom:100px;">  
		<pre><s:property value="exceptionStack"/></pre>  
	</div>
</div>
</body>
</html>


   两个图片加入WebRoot/images目录下

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值