1. 首先在在web.xml文件中,加入SiteMesh和shiro的过滤器,保证SiteMesh的过滤器配置放在shiro的过滤器后面,不然的话,shiro的标签不能正确处理。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  5. version="2.5">
  6. <display-name>ems</display-name>
  7.  
  8. <servlet>
  9. <servlet-name>dispatcherServlet</servlet-name>
  10. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  11. <init-param>
  12. <param-name>contextConfigLocation</param-name>
  13. <param-value>classpath:config/spring-mvc.xml</param-value>
  14. </init-param>
  15. <load-on-startup>1</load-on-startup>
  16. </servlet>
  17. <servlet-mapping>
  18. <servlet-name>dispatcherServlet</servlet-name>
  19. <url-pattern>/</url-pattern>
  20. </servlet-mapping>
  21.  
  22. <listener>
  23. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  24. </listener>
  25. <context-param>
  26. <param-name>contextConfigLocation</param-name>
  27. <param-value>classpath:config/applicationContext.xml</param-value>
  28. </context-param>
  29.  
  30. <filter>
  31. <filter-name>characterEncodingFilter</filter-name>
  32. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  33. <init-param>
  34. <param-name>encoding</param-name>
  35. <param-value>UTF-8</param-value>
  36. </init-param>
  37. <init-param>
  38. <param-name>forceEncoding</param-name>
  39. <param-value>true</param-value>
  40. </init-param>
  41. </filter>
  42. <filter-mapping>
  43. <filter-name>characterEncodingFilter</filter-name>
  44. <url-pattern>/*</url-pattern>
  45. </filter-mapping>
  46.  
  47. <!-- shiro 安全过滤器 -->
  48. <filter>
  49. <filter-name>shiroFilter</filter-name>
  50. <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  51. <async-supported>true</async-supported>
  52. <init-param>
  53. <param-name>targetFilterLifecycle</param-name>
  54. <param-value>true</param-value>
  55. </init-param>
  56. </filter>
  57. <filter-mapping>
  58. <filter-name>shiroFilter</filter-name>
  59. <url-pattern>/*</url-pattern>
  60. </filter-mapping>
  61.  
  62. <filter>
  63. <filter-name>sitemesh</filter-name>
  64. <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
  65. </filter>
  66. <filter-mapping>
  67. <filter-name>sitemesh</filter-name>
  68. <url-pattern>/*</url-pattern>
  69. </filter-mapping>
  70.  
  71. <session-config>
  72. <session-timeout>30</session-timeout> <!-- 单位:分钟 -->
  73. </session-config>
  74. </web-app>

2. pom.xml中引入sitemesh的依赖

  1. <dependency>
  2. <groupId>org.sitemesh</groupId>
  3. <artifactId>sitemesh</artifactId>
  4. <version>3.0.1</version>
  5. </dependency>

3. 在WEB-INF下加入sitemesh的配置文件(sitemesh3.xml):

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <sitemesh>
  3. <!-- Map default decorator. This shall be applied to all paths if no other paths match. -->
  4. <mapping path="/*" decorator="/main.jsp" exclude="false" />
  5.  
  6. <!-- Exclude path from decoration. -->
  7. <mapping path="/js/*" exclude="true" />
  8. <mapping path="/img/*" exclude="true" />
  9. <mapping path="/images/*" exclude="true" />
  10. <mapping path="/css/*" exclude="true" />
  11. <mapping path="/font-awesome/*" exclude="true" />
  12. <mapping path="/login" exclude="true" />
  13. <mapping path="/login.jsp" exclude="true" />
  14. </sitemesh>

main.jsp 为模板页面,<mapping exlude /> 表示不经过sitemesh处理的资源和页面。

4. 模板页面的书写

在模板页面中可以使用下面的标签作为占位符:

<sitemesh:write property='title' />

<sitemesh:write property='head' />

<sitemesh:write property='body' />

被装饰的页面,可以使用自己页面中的对应部分(title, head, body),填充在这些标签的位置。

下面看一个模板页面的例子:

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
  4. <%@ taglib prefix="s" uri="http://www.springframework.org/tags" %>
  5. <!DOCTYPE html>
  6. <html>
  7. <head>
  8. <title><sitemesh:write property='title' /></title>
  9. <meta charset="UTF-8" />
  10. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  11. <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css" />
  12. <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap-responsive.min.css" />
  13. <link rel="stylesheet" href="${pageContext.request.contextPath}/css/fullcalendar.css" />
  14. <link rel="stylesheet" href="${pageContext.request.contextPath}/css/matrix-login.css" />
  15. <link rel="stylesheet" href="${pageContext.request.contextPath}/css/matrix-style.css" />
  16. <link rel="stylesheet" href="${pageContext.request.contextPath}/css/matrix-media.css" />
  17. <link rel="stylesheet" href="${pageContext.request.contextPath}/font-awesome/css/font-awesome.css" />
  18. <link rel="stylesheet" href="${pageContext.request.contextPath}/css/jquery.gritter.css" />
  19. <link rel='stylesheet' href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,800' />
  20. <style type="text/css">
  21. #top_header{
  22. margin-left:80px;
  23. margin-right:80px;
  24. padding-top:9px;
  25. font-size:30px;
  26. display:block;
  27. width:500px;
  28. }
  29. #top_logout{
  30. margin-right:2px;
  31. }
  32. #cur_user{
  33. margin-top:9px;
  34. display:block;
  35. }
  36. .tc{ background-color:#e6e6e6; border:#016574 2px solid; display:none;
  37. position:fixed; top:39%; left:40%; -moz-border-radius: 5px; -khtml-border-radius: 5px;
  38. -webkit-border-radius: 5px; border-radius: 5px; padding:19px 35px; font-size:14px;
  39. }
  40. </style>
  41. <sitemesh:write property='head' />
  42. </head>
  43. <body>
  44.  
  45. <!--Header-part-->
  46. <div id="header">
  47. <h1><a href="javascript:;">Admin</a></h1>
  48. </div>
  49. <!--close-Header-part-->
  50.  
  51. <!--top-Header-menu-->
  52. <div id="user-nav" class="navbar navbar-inverse">
  53. <ul class="nav">
  54. <li class=""><span id="top_header">XXX系统</span></li>
  55. <li><span id="cur_user">当前登陆用户:${user.username}</span></li>
  56. <li id="top_logout" style="float:right;"><a title="" href="/ems/logout"><i class="icon icon-share-alt"></i> <span class="text">Logout</span></a></li>
  57. </ul>
  58. </div>
  59. <!--close-top-Header-menu-->
  60.  
  61. <!--sidebar-menu-->
  62. <div id="sidebar"><a href="javascript:;" class="visible-phone"><i class="icon icon-home"></i> Dashboard</a>
  63. <ul>
  64. <shiro:hasAnyRoles name="student,teacher">
  65. <li id="li_queryScore"><a href="/ems/user/queryScore"><i class="icon icon-home"></i><span>查询成绩</span></a></li>
  66. </shiro:hasAnyRoles>
  67. <shiro:hasAnyRoles name="teacher,admin">
  68. <li id="li_showStudentInfo"><a href="/ems/student/showStudentInfo"><i class="icon icon-home"></i><span>查询学生信息</span></a></li>
  69. </shiro:hasAnyRoles>
  70. <shiro:hasAnyRoles name="admin">
  71. <li id="li_showTeacherInfo"><a href="/ems/teacher/showTeacherInfo"><i class="icon icon-home"></i><span>查询教师信息</span></a></li>
  72. </shiro:hasAnyRoles>
  73. <shiro:hasAnyRoles name="teacher,admin">
  74. <li><a href="/ems/html/tables.html"><i class="icon icon-th"></i><span>统计</span></a></li>
  75. </shiro:hasAnyRoles>
  76. <shiro:hasAnyRoles name="student,teacher,admin">
  77. <li><a href="/ems/html/grid.html"><i class="icon icon-fullscreen"></i><span>打印</span></a></li>
  78. <li id="li_password"><a href="/ems/user/password"><i class="icon icon-inbox"></i><span>密码修改</span></a> </li>
  79. </shiro:hasAnyRoles>
  80. <shiro:hasRole name="admin">
  81. <li id="li_showPrivilege"><a href="/ems/priv/showPrivilege"><i class="icon icon-fullscreen"></i><span>权限设置</span></a></li>
  82. </shiro:hasRole>
  83. <shiro:hasAnyRoles name="teacher,admin">
  84. <li id="li_setting"><a href="/ems/set/setting"><i class="icon icon-tint"></i><span>成绩比例和录入设置</span></a></li>
  85. </shiro:hasAnyRoles>
  86. <shiro:hasAnyRoles name="student,teacher">
  87. <li id="li_queryReExam"><a href="/ems/user/queryReExam"><i class="icon icon-pencil"></i><span>补考名单</span></a></li>
  88. <li id="li_queryReLearn"><a href="/ems/user/queryReLearn"><i class="icon icon-pencil"></i><span>重修名单</span></a></li>
  89. </shiro:hasAnyRoles>
  90. </ul>
  91. </div>
  92. <!--sidebar-menu-->
  93.  
  94. <!--main-container-part-->
  95. <sitemesh:write property='body' />
  96.  
  97. <!-- end-Footer-part -->
  98. </body>
  99. </html>

上面的模板页面使用了:<sitemesh:write property='title' />, <sitemesh:write property='head' />,<sitemesh:write property='body' />

然后我们看下被装饰的页面:

  1. <%@ page contentType="text/html; charset=UTF-8" %>
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <title>index</title>
  7. </head>
  8. <body>
  9.  
  10. <!--main-container-part-->
  11. <div id="content">
  12.  
  13. <!--breadcrumbs-->
  14. <div id="content-header">
  15. <div id="breadcrumb"> <a href="tables.html" title="Go to Home" class="tip-bottom"><i class="icon-home"></i> Home</a></div>
  16. </div>
  17. <!--End-breadcrumbs-->
  18.  
  19. <!--Action boxes-->
  20. <div class="container-fluid">
  21. <shiro:hasAnyRoles name="student,teacher">
  22. <input type="hidden" name="user_type" id="user_type" value="${user.userType}" />
  23. 学年:<select id="learn_time" name="learn_time">
  24. <option value="2014">2014</option>
  25. <option value="2015" selected = "selected">2015</option>
  26. <option value="2016">2016</option>
  27. <option value="2017">2017</option>
  28. </select>
  29. 学期:<input type="radio" name="which_term" value="1" />上学期
  30. <input type="radio" name="which_term" value="2" />下学期
  31. </shiro:hasAnyRoles>
  32. <c:if test="${user.userType == '1'}">
  33. <input type="button" value="查询" id="queryScoreForStudent"/>
  34. </c:if>
  35. <c:if test="${user.userType == '2'}">
  36. <br/>
  37. 班级:<input type="text" name="className" id="class_name" />
  38. 课程:
  39. <select id="course_type_select" name="courseId">
  40. <c:forEach items="${courseList }" var="course" varStatus="status">
  41. <c:if test="${status.index == 0}">
  42. <option selected="selected" value="${course.id}"><c:out value="${course.name}"/></option>
  43. </c:if>
  44. <c:if test="${status.index > 0}">
  45. <option value="${course.id}"><c:out value="${course.name}"/></option>
  46. </c:if>
  47. </c:forEach>
  48. </select>
  49. <input type="button" value="查询课程成绩" id="queryScoreForTeacher"/>
  50. </c:if>
  51.  
  52. <div class="row-fluid">
  53. <div class="span12">
  54. <div class="widget-box">
  55. <div class="widget-content nopadding">
  56. <table class="table table-bordered table-striped" id="score_table">
  57. </table>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. </div>
  63. <!--End-Action boxes-->
  64.  
  65. </div>
  66. <!--end-main-container-part-->
  67.  
  68. <!--Footer-part-->
  69. <div class="row-fluid">
  70. <div id="footer" class="span12"> 2013 © Matrix Admin. Brought to you by <a href="http://themedesigner.in/">Themedesigner.in</a> </div>
  71. </div>
  72. <!-- end-Footer-part -->
  73.  
  74. <script src="${pageContext.request.contextPath}/js/jquery.min.js"></script>
  75. <script src="${pageContext.request.contextPath}/js/highLight.js"></script>
  76. <script type="text/javascript">
  77. $.namespace("ems.index");
  78. ems.index = function(){
  79. var divShow = $("#DivShow");
  80. return {
  81. queryScoreForStudent : function(){
  82. var time = $.trim($("#learn_time").val());
  83. var term = $.trim($("input[name='which_term']:checked").val());
  84. var indata = {time:time, term:term};
  85. $.post("/ems/user/queryScoreForStudent",indata, function(data){
  86. $("#score_table").empty();
  87. if(data != null && data.result == 'ok'){
  88. var d = data.data;
  89. console.log(d);
  90. if(data.data != null){
  91. var score_html = '<thead><tr><th>课程</th><th>分数</th><th>老师</th><th>时间</th></tr></thead><tbody>';
  92. for(var i=0; i<d.length; i++){
  93. score_html += '<tr class="odd gradeX"><td>' + d[i].courseName + '</td>';
  94. score_html += '<td>' + d[i].score + '</td>';
  95. score_html += '<td>' + d[i].teacherName + '</td>';
  96. score_html += '<td>' + new Date(d[i].learnTime).format("yyyy-MM-dd"); + '</td>';
  97. }
  98. score_html += '</tbody>';
  99. $("#score_table").empty().append(score_html);
  100. }
  101. }
  102. },'json');
  103. },
  104. queryScoreForTeacher : function(){
  105. var courseId = $.trim($("#course_type_select").val());
  106. if(courseId == null || courseId == '')
  107. return;
  108. var className = $.trim($("#class_name").val());
  109. var time = $.trim($("#learn_time").val());
  110. var term = $.trim($("input[name='which_term']:checked").val());
  111. var indata = {courseId:courseId, time:time, term:term, className:className};
  112. $.post("/ems/user/queryScoreForTeacher", indata, function(data){
  113. $("#score_table").empty();
  114. if(data != null && data.result == 'ok'){
  115. var d = data.data;
  116. console.log(d);
  117. if(data.data != null){
  118. var score_html = '<thead><tr><th>学号</th><th>姓名</th><th>专业</th><th>课程</th>'
  119. + '<th>分数</th><th>时间</th><th>录入成绩</th></tr></thead><tbody>';
  120. for(var i=0; i<d.length; i++){
  121. score_html += '<tr class="odd gradeX"><td>' + d[i].no + '</td>';
  122. score_html += '<td>' + d[i].studentName + '</td>';
  123. score_html += '<td>' + d[i].major + '</td>';
  124. score_html += '<td>' + d[i].courseName + '</td>';
  125. score_html += '<td>' + d[i].score + '</td>';
  126. score_html += '<td>' + new Date(d[i].learnTime).format("yyyy-MM-dd"); + '</td>';
  127. score_html += '<td><input type="button" id="'+ d[i].id + '" name="'+ d[i].flag
  128. + '" value="录入成绩" onclick="ems.index.showDiv(this)"/></td>';
  129. }
  130. score_html += '</tbody>';
  131. $("#score_table").empty().append(score_html);
  132. }
  133. }
  134. },'json');
  135. },
  136. showDiv : function(myThis){
  137. divShow.find("#student_course_id").val(myThis.id);
  138. divShow.find("#student_course_flag").val(myThis.name);
  139. divShow.show();
  140. },
  141. closeDiv : function(){
  142. divShow.find("#student_course_id").val("");
  143. divShow.find("#student_course_flag").val("");
  144. divShow.hide();
  145. },
  146. updateStudentScore : function(){
  147. var value1 = divShow.find("#value1").val();
  148. var value2 = divShow.find("#value2").val();
  149. var value3 = divShow.find("#value3").val();
  150. var id = divShow.find("#student_course_id").val();
  151. var flag = divShow.find("#student_course_flag").val();
  152. var indata = {id:id,flag:flag,score1:value1,score2:value2,score3:value3};
  153. $.post("/ems/user/updateStudentScore", indata, function(data){
  154. if(data != null && data.result == 'ok'){
  155. console.log(data.msg);
  156. ems.index.queryScoreForTeacher();
  157. }else{
  158. alert(data.msg);
  159. }
  160. }, 'json');
  161. ems.index.closeDiv();
  162. },
  163. createLearnTimeSelect : function(){
  164. var begin = 2008;
  165. var current_year = new Date().format("yyyy");
  166. var sel_html = '';
  167. for(var i=0; i<20; i++){
  168. if(begin+i == current_year)
  169. sel_html +='<option value="' + (begin+i) +'" selected = "selected">'+ (begin+i) +"</option>";
  170. sel_html += '<option value="' + (begin+i) +'">'+ (begin+i) +"</option>";
  171. }
  172. $("#learn_time").empty().append(sel_html);
  173. }
  174. };
  175. }();
  176.  
  177. $(document).ready(function(){
  178. ems.index.createLearnTimeSelect(); // 生成学年下拉框
  179. $(document).on('click', '#queryScoreForTeacher', ems.index.queryScoreForTeacher);
  180. $(document).on('click', '#queryScoreForStudent', ems.index.queryScoreForStudent);
  181. $(document).on('click', '#btnCancel', ems.index.closeDiv);
  182. $(document).on('click', '#btnOK', ems.index.updateStudentScore);
  183. });
  184. </script>
  185. </body>
  186. </html>

我们看到被装饰页面的整个 body 部分,会填充到装饰页面中的 <sitemesh:write property='body' /> 处。

正好是注释: <!--main-container-part--> 和 <!-- end-Footer-part --> 相匹配和对应。

注意:模板页面的 <sitemesh:write property='head' /> 最好放置head标签的最后面,因为被装饰页面中的head部分由可能存在依赖于模板页面中的js库。

我们看到sitemesh的使用还是十分简单的。

SiteMesh, SpringMVC, Shiro 配置的更多相关文章

  1. SpringMVC+Shiro权限管理【转】

    1.权限的简单描述 2.实例表结构及内容及POJO 3.Shiro-pom.xml 4.Shiro-web.xml 5.Shiro-MyShiro-权限认证,登录认证层 6.Shiro-applica ...

  2. SpringMVC+Shiro权限管理

    什么是权限呢?举个简单的例子: 我有一个论坛,注册的用户分为normal用户,manager用户.对论坛的帖子的操作有这些:添加,删除,更新,查看,回复我们规定:normal用户只能:添加,查看,回复 ...

  3. SpringMVC+Apache Shiro+JPA(hibernate)案例教学(二)基于SpringMVC+Shiro的用户登录权限验证

    序: 在上一篇中,咱们已经对于项目已经做了基本的配置,这一篇文章开始学习Shiro如何对登录进行验证. 教学: 一.Shiro配置的简要说明. 有心人可能注意到了,在上一章的applicationCo ...

  4. springmvc shiro UnauthorizedException 异常解决方案

    springMVC 整合 shiro 时,配置了当访问某个URL没有权限时的配置处理: <!-- 通过unauthorizedUrl指定没有权限操作时跳转页面 --><propert ...

  5. springmvc shiro整合cas单点登入

    shiro cas分为登入跟登出 maven依赖: <dependency> <groupId>org.apache.shiro</groupId> <art ...

  6. (转)Springboot+shiro配置笔记+错误小结

    springboot不像springmvc,它没有xml配置文件,那该如何配置shiro呢,其实也不难,用java代码+注解来解决这个问题.仅以此篇记录我对shiro的学习,如有对过客造成不便,实在抱 ...

  7. Springboot+shiro配置笔记+错误小结

    软件152 尹以操 springboot不像springmvc,它没有xml配置文件,那该如何配置shiro呢,其实也不难,用java代码+注解来解决这个问题.仅以此篇记录我对shiro的学习,如有对 ...

  8. SpringMVC+Shiro权限管理(转载)

    源码 http://pan.baidu.com/s/1pJzG4t1 SpringMVC+Shiro权限管理 博文目录 权限的简单描述 实例表结构及内容及POJO Shiro-pom.xml Shir ...

  9. springmvc+shiro+freemarker实现的安全及权限管理

    本文讲述了基于springmvc+shiro实现安全管理,shiro+freemarker实现权限验证. 首先我们从web.xml开始: <?xml version="1.0" ...

随机推荐

  1. SQL Server里强制参数化的痛苦

    几天前,我写了篇SQL Server里简单参数化的痛苦.今天我想继续这个话题,谈下SQL Server里强制参数化(Forced Parameterization). 强制参数化(Forced Par ...

  2. IOS开发UI基础storyboard相关概念的认识

    本文主要介绍一些基本的概念 为后面的学习做个准备 需要了解的知识点有以下几个方面: storyboard文件的认识 IBAction 和IBOutlet UIViewController控制器的认识 ...

  3. Android的init过程(二):初始化语言(init.rc)解析

    Android的init过程(一) 本文使用的软件版本 Android:4.2.2 Linux内核:3.1.10 在上一篇文章中介绍了init的初始化第一阶段,也就是处理各种属性.在本文将会详细分析i ...

  4. Chrome弹窗的简单应用(选择结构与循环结构)

    ★选择结构★ ★JS实现弹窗显示随机数 示例代码效果图   ★ 弹窗实现对随机数的进一步判断 示例代码效果图 ★综合应用   比较大小 ★ 判断成绩等级 ): : : : : alert(" ...

  5. 用SQL语句修复SQL Server数据库

    使用数据库的过程中,由于断电或其他原因,有可能导致数据库出现一些小错误,比如检索某些表特别慢,查询不到符合条件的数据等. 出现这些情况的原因,往往是因为数据库有些损坏,或索引不完整. 在ACCESS中 ...

  6. c#重点[集合类型]异常,数组,集合ArrayList,List<>,hashTable,hashtable泛型(Dictionary)

    1.foreach[对一些数组或集合进行遍历] foreach(类型 变量名 in 集合对象){语句体} //定义一个数组 ,,,,, }; foreach(var i in sNum1) { Con ...

  7. C#中 导入和导出Excel的方法

    using System.Data; using System.Data.OleDb; /// <summary> /// Excel转为DataTable /// </summar ...

  8. 35 Gallery – Ajax Slide

    http://html5up.net/overflow (PC,Mobile,Table) http://bridge.net/ https://github.com/bridgedotnet/Bri ...

  9. Verilog学习笔记简单功能实现(一)...............D触发器

    module D_flop(data,clk,clr,q,qb); input data,clk,clr; output q,qb; wire a,b,c,d,e,f,ndata,nclk; nand ...

  10. [WP8] Binding时,依照DataType选择DataTemplate

    [WP8] Binding时,依照DataType选择DataTemplate 范例下载 范例程序代码:点此下载 问题情景 在开发WPF.WP8...这类应用程序的时候,透过Binding机制搭配Da ...