This commit is contained in:
Calvin
2012-02-26 00:56:01 +08:00
parent a6abb9fe6c
commit 99d759dcf6
12 changed files with 11 additions and 888 deletions
+8 -7
View File
@@ -11,10 +11,10 @@ TODO部分:
2.次要改动
* 整理CSS(整理项目BBS, 整理BluePrint CSS,将JQuery Validation中的milk css替换为message.css,jquery validate input框的.error替换为将替换为hightlight)
* 修正Selenium Test case
* 晦气,再把Velocity回退成Freemarker
3.其他非代码改动
* 发布前打包Maven-Archetype的项目生成模板
* Makesure all bat work
---------------------------------------------------------------------------------
已完成部分:
@@ -23,7 +23,7 @@ TODO部分:
* DAO框架增加MyBatis的使用,与Hibernate在不同的场景各展所长
* 安全框架从SpringSecurity转为Apache Shiro.
* SpringSide Modules的重构
* 使用SiteMesh3实现Layout
* 使用SiteMesh3实现Layout Decoration
* CSS框架从YUI转为Blueprint
* 演示Hibernate Validator
* 升級Jackson1.9 演示,包括可擴展的對象, 對象循環引用,局部更新,自定义类型的持久化,自定义Naming策略,已存在對象等新特性.
@@ -51,7 +51,6 @@ TODO部分:
* 使用Maven FailSafe插件分开单元测试和集成测试
* cxf wsdl2java从ant改为用maven plugin
* hibernate代码生成从ant改为用Eclipse插件
* 发布包中不再包含所有依赖jar,只包含源码,maven和ant命令.
-----------------------------------------------------------------------------------
4.0 正式版
@@ -66,12 +65,14 @@ TODO部分:
* 包括Guava的Cache Builder做的简单缓存
* Review HttpClient的使用
* Review perf4j的使用
* 依赖包次要版本升级:JSW 3.5.7(需自行打包)
* 依赖包次要版本升级:JSW 3.5.7, Log4jdbc,Spymemcached(需自行打包)
* Jersey的Jackson JSON绑定看有没有简化
* 用JUnit自带的Catetory的演示
* 升级Selenium到最新版, 使用自带的Wait类
* 用JUnit自带的Catetory的演示,Harmset演示
* Selenium使用自带的Wait类, 检查新版API变化
* 更深入演示PowerMock
* 升级Jquery-validation用法
* 安全部分加入salt
* Hash与加密要加入salt
* 取消GBK编码的bat
-----------------------------------------------------------------------------------
@@ -1,144 +0,0 @@
package org.springside.examples.miniweb.web;
import java.util.Collection;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springside.examples.miniweb.entity.IdEntity;
import org.springside.modules.utils.AssertUtils;
import org.springside.modules.utils.ReflectionUtils;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
/**
* Struts2中典型CRUD Action的抽象基类.
*
* 主要定义了对Preparable,ModelDriven接口的使用,以及CRUD函数和返回值的命名.
*
* @param <T> CRUDAction所管理的对象类型.
*
* @author calvin
*/
public abstract class CrudActionSupport<T> extends ActionSupport implements ModelDriven<T>, Preparable {
private static final long serialVersionUID = -1653204626115064950L;
/** 进行增删改操作后,以redirect方式重新打开action默认页的result名.*/
public static final String RELOAD = "reload";
protected Logger logger = LoggerFactory.getLogger(getClass());
/**
* Action函数, 默认的action函数, 默认调用list()函数.
*/
@Override
public String execute() throws Exception {
return list();
}
//-- CRUD Action函数 --//
/**
* Action函数,显示Entity列表界面.
* 建议return SUCCESS.
*/
public abstract String list() throws Exception;
/**
* Action函数,显示新增或修改Entity界面.
* 建议return INPUT.
*/
@Override
public abstract String input() throws Exception;
/**
* Action函数,新增或修改Entity.
* 建议return RELOAD.
*/
public abstract String save() throws Exception;
/**
* Action函数,删除Entity.
* 建议return RELOAD.
*/
public abstract String delete() throws Exception;
//-- Preparable函数 --//
/**
* 实现空的prepare()函数,屏蔽了所有Action函数都会执行的公共的二次绑定.
*/
@Override
public void prepare() throws Exception {
}
/**
* 定义在input()前执行二次绑定.
*/
public void prepareInput() throws Exception {
prepareModel();
}
/**
* 定义在save()前执行二次绑定.
*/
public void prepareSave() throws Exception {
prepareModel();
}
/**
* 等同于prepare()的内部函数,供prepardMethodName()函数调用.
*/
protected abstract void prepareModel() throws Exception;
/**
* 根据对象ID集合, 整理合并集合.
*
* 页面发送变更后的子对象id列表时,采用如此的整合算法:在源集合中删除id不在目标集合中的对象,根据目标集合中的id创建对象并添加到源集合中.
* 因为新建对象只有ID被赋值, 因此本函数不适合于cascade-save-or-update自动持久化子对象的设置.
*
* @param srcObjects 源集合,元素为对象.
* @param checkedIds 目标集合,元素为ID.
* @param clazz 集合中对象的类型,必须为IdEntity子类
*/
public static <T extends IdEntity> void mergeByIds(final Collection<T> srcObjects,
final Collection<Long> checkedIds, final Class<T> clazz) {
//参数校验
AssertUtils.notNull(srcObjects, "scrObjects不能为空");
AssertUtils.notNull(clazz, "clazz不能为空");
//目标集合为空, 删除源集合中所有对象后直接返回.
if (checkedIds == null) {
srcObjects.clear();
return;
}
//遍历源对象集合,如果其id不在目标ID集合中的对象删除.
//同时,在目标集合中删除已在源集合中的id,使得目标集合中剩下的id均为源集合中没有的id.
Iterator<T> srcIterator = srcObjects.iterator();
try {
while (srcIterator.hasNext()) {
T element = srcIterator.next();
Long id = element.getId();
if (!checkedIds.contains(id)) {
srcIterator.remove();
} else {
checkedIds.remove(id);
}
}
//ID集合目前剩余的id均不在源集合中,创建对象,为id属性赋值并添加到源集合中.
for (Long id : checkedIds) {
T element = clazz.newInstance();
element.setId(id);
srcObjects.add(element);
}
} catch (Exception e) {
throw ReflectionUtils.convertReflectionExceptionToUnchecked(e);
}
}
}
@@ -1,112 +0,0 @@
package org.springside.examples.miniweb.web.account;
import java.util.List;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springside.examples.miniweb.entity.account.Group;
import org.springside.examples.miniweb.entity.account.Permission;
import org.springside.examples.miniweb.service.account.AccountManager;
import org.springside.examples.miniweb.web.CrudActionSupport;
/**
* 权限组管理Action.
*
* 演示不分页的简单管理界面.
*
* @author calvin
*/
@Namespace("/account")
@Results({ @Result(name = CrudActionSupport.RELOAD, location = "group.action", type = "redirect") })
public class GroupAction extends CrudActionSupport<Group> {
private static final long serialVersionUID = -4052047494894591406L;
private AccountManager accountManager;
//-- 页面属性 --//
private Long id;
private Group entity;
private List<Group> allGroupList;//权限组列表
private List<String> checkedPermissions;//页面中钩选的权限列表
//-- ModelDriven 与 Preparable函数 --//
@Override
public Group getModel() {
return entity;
}
public void setId(Long id) {
this.id = id;
}
@Override
protected void prepareModel() throws Exception {
if (id != null) {
entity = accountManager.getGroup(id);
} else {
entity = new Group();
}
}
//-- CRUD Action 函数 --//
@Override
public String list() throws Exception {
allGroupList = accountManager.getAllGroup();
return SUCCESS;
}
@Override
public String input() throws Exception {
checkedPermissions = entity.getPermissionList();
return INPUT;
}
@Override
public String save() throws Exception {
entity.setPermissionList(checkedPermissions);
accountManager.saveGroup(entity);
addActionMessage("保存权限组成功");
return RELOAD;
}
@Override
public String delete() throws Exception {
accountManager.deleteGroup(id);
addActionMessage("删除权限组成功");
return RELOAD;
}
//-- 页面属性访问函数 --//
/**
* list页面显示所有权限组列表.
*/
public List<Group> getAllGroupList() {
return allGroupList;
}
public Permission[] getAllPermissionList() {
return Permission.values();
}
/**
* input页面显示权限组拥有的权限.
*/
public List<String> getCheckedPermissions() {
return checkedPermissions;
}
/**
* input页面提交权限组拥有的权限.
*/
public void setCheckedPermissions(List<String> checkedPermissions) {
this.checkedPermissions = checkedPermissions;
}
@Autowired
public void setAccountManager(AccountManager accountManager) {
this.accountManager = accountManager;
}
}
@@ -1,159 +0,0 @@
package org.springside.examples.miniweb.web.account;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;
import org.springside.examples.miniweb.entity.account.Group;
import org.springside.examples.miniweb.entity.account.User;
import org.springside.examples.miniweb.service.ServiceException;
import org.springside.examples.miniweb.service.account.AccountManager;
import org.springside.examples.miniweb.web.CrudActionSupport;
import org.springside.modules.orm.Page;
import org.springside.modules.orm.PageRequest;
import org.springside.modules.orm.PropertyFilter;
/**
* 用户管理Action.
*
* 使用Struts2 convention-plugin annotation定义Action参数.
* 演示带分页的管理界面.
*
* @author calvin
*/
//定义URL映射对应/account/user.action
@Namespace("/account")
//定义名为reload的result重定向到user.action, 其他result则按照convention默认.
@Results({ @Result(name = CrudActionSupport.RELOAD, location = "user.action", type = "redirect") })
public class UserAction extends CrudActionSupport<User> {
private static final long serialVersionUID = 8683878162525847072L;
private AccountManager accountManager;
//-- 页面属性 --//
private Long id;
private User entity;
private Page<User> page = new Page<User>();
private List<Long> checkedGroupIds; //页面中钩选的权限组id列表
//-- ModelDriven 与 Preparable函数 --//
public void setId(Long id) {
this.id = id;
}
@Override
public User getModel() {
return entity;
}
@Override
protected void prepareModel() throws Exception {
if (id != null) {
entity = accountManager.getUser(id);
} else {
entity = new User();
}
}
//-- CRUD Action 函数 --//
@Override
public String list() throws Exception {
List<PropertyFilter> filters = null;//PropertyFilter.buildFromHttpRequest(Struts2Utils.getRequest());
page.setPageSize(5);
//设置默认排序方式
if (!page.isOrderBySetted()) {
page.setOrderBy("id");
page.setOrderDir(PageRequest.Sort.ASC);
}
page = accountManager.searchUser(page, filters);
return SUCCESS;
}
@Override
public String input() throws Exception {
checkedGroupIds = entity.getGroupIds();
return INPUT;
}
@Override
public String save() throws Exception {
//根据页面上的checkbox选择 整合User的Groups Set
CrudActionSupport.mergeByIds(entity.getGroupList(), checkedGroupIds, Group.class);
accountManager.saveUser(entity);
addActionMessage("保存用户成功");
return RELOAD;
}
@Override
public String delete() throws Exception {
try {
accountManager.deleteUser(id);
addActionMessage("删除用户成功");
} catch (ServiceException e) {
logger.error(e.getMessage(), e);
addActionMessage("删除用户失败");
}
return RELOAD;
}
//-- 其他Action函数 --//
/**
* 支持使用Jquery.validate Ajax检验用户名是否重复.
*/
public String checkLoginName() {
HttpServletRequest request = ServletActionContext.getRequest();
String newLoginName = request.getParameter("loginName");
String oldLoginName = request.getParameter("oldLoginName");
/*
if (accountManager.isLoginNameUnique(newLoginName, oldLoginName)) {
Struts2Utils.renderText("true");
} else {
Struts2Utils.renderText("false");
}
*/
//因为直接输出内容而不经过jsp,因此返回null.
return null;
}
//-- 页面属性访问函数 --//
/**
* list页面显示用户分页列表.
*/
public Page<User> getPage() {
return page;
}
/**
* input页面显示所有权限组列表.
*/
public List<Group> getAllGroupList() {
return accountManager.getAllGroup();
}
/**
* input页面显示用户拥有的权限组.
*/
public List<Long> getCheckedGroupIds() {
return checkedGroupIds;
}
/**
* input页面提交用户拥有的权限组.
*/
public void setCheckedGroupIds(List<Long> checkedGroupIds) {
this.checkedGroupIds = checkedGroupIds;
}
@Autowired
public void setAccountManager(AccountManager accountManager) {
this.accountManager = accountManager;
}
}
@@ -1,67 +0,0 @@
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="/common/taglibs.jsp" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Mini-Web 权限组管理</title>
<%@ include file="/common/meta.jsp" %>
<link href="${ctx}/css/style.css" type="text/css" rel="stylesheet"/>
<link href="${ctx}/js/validate/jquery.validate.css" type="text/css" rel="stylesheet"/>
<link href="${ctx}/css/blueprint/screen.css" type="text/css" rel="stylesheet" media="screen, projection"/>
<link href="${ctx}/css/blueprint/print.css" type="text/css" rel="stylesheet" media="print"/>
<!--[if lt IE 8]><link href="${ctx}/css/blueprint/blueprint/ie.css" type="text/css" rel="stylesheet" media="screen, projection"><![endif]-->
<script src="${ctx}/js/jquery-min.js" type="text/javascript"></script>
<script src="${ctx}/js/validate/jquery.validate.js" type="text/javascript"></script>
<script src="${ctx}/js/validate/messages_cn.js" type="text/javascript"></script>
<script>
$(document).ready(function() {
//聚焦第一个输入框
$("#name").focus();
//为inputForm注册validate函数
$("#inputForm").validate();
});
</script>
</head>
<body>
<div class="container">
<%@ include file="/common/header.jsp" %>
<div id="content">
<div class="span-24 last">
<h3><s:if test="id == null">创建</s:if><s:else>修改</s:else>权限组</h3>
<form action="group!save.action" method="post">
<input type="hidden" name="id" value="${id}"/>
<table class="noborder">
<tr>
<td>权限组:</td>
<td><input type="text" id="name" name="name" size="40" value="${name}" class="required"/></td>
</tr>
<tr>
<td>授权:</td>
<td>
<s:checkboxlist name="checkedPermissions" list="allPermissionList" listKey="value"
listValue="displayName" theme="custom"/>
</td>
</tr>
<tr>
<td colspan="2">
<shiro:hasPermission name="group:edit">
<input class="button" type="submit" value="提交"/>&nbsp;
</shiro:hasPermission>
<input class="button" type="button" value="返回" onclick="history.back()"/>
</td>
</tr>
</table>
</form>
</div>
</div>
<%@ include file="/common/footer.jsp" %>
</div>
</body>
</html>
@@ -1,63 +0,0 @@
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="org.apache.shiro.SecurityUtils" %>
<%@ include file="/common/taglibs.jsp" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Mini-Web权限组管理</title>
<%@ include file="/common/meta.jsp" %>
<link href="${ctx}/css/style.css" type="text/css" rel="stylesheet"/>
<link href="${ctx}/css/blueprint/screen.css" type="text/css" rel="stylesheet" media="screen, projection"/>
<link href="${ctx}/css/blueprint/print.css" type="text/css" rel="stylesheet" media="print"/>
<!--[if lt IE 8]><link href="${ctx}/css/blueprint/blueprint/ie.css" type="text/css" rel="stylesheet" media="screen, projection"><![endif]-->
</head>
<body>
<div class="container">
<%@ include file="/common/header.jsp" %>
<div id="content" class="span-24 last prepend-top">
<div id="message"><s:actionmessage theme="custom" cssClass="success"/></div>
<div>你好, <shiro:principal/>.</div>
<div>
<table id="contentTable">
<tr>
<th>名称</th>
<th>授权</th>
<th>操作</th>
</tr>
<s:iterator value="allGroupList">
<tr>
<td>${name}</td>
<td>${permissionNames}</td>
<td>&nbsp;
<shiro:hasPermission name="group:view">
<shiro:lacksPermission name="group:edit">
<a href="group!input.action?id=${id}">查看</a>&nbsp;
</shiro:lacksPermission>
</shiro:hasPermission>
<shiro:hasPermission name="group:edit">
<a href="group!input.action?id=${id}" id="editLink-${name}">修改</a>&nbsp;
<a href="group!delete.action?id=${id}" id="deleteLink-${name}">删除</a>
</shiro:hasPermission>
</td>
</tr>
</s:iterator>
</table>
</div>
<div>
<shiro:hasPermission name="group:edit">
<a href="group!input.action">增加新权限组</a>
</shiro:hasPermission>
</div>
</div>
<%@ include file="/common/footer.jsp" %>
</div>
</body>
</html>
@@ -1,107 +0,0 @@
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="/common/taglibs.jsp" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Mini-Web 帐号管理</title>
<%@ include file="/common/meta.jsp" %>
<link href="${ctx}/css/style.css" type="text/css" rel="stylesheet"/>
<link href="${ctx}/js/validate/jquery.validate.css" type="text/css" rel="stylesheet"/>
<link href="${ctx}/css/blueprint/screen.css" type="text/css" rel="stylesheet" media="screen, projection"/>
<link href="${ctx}/css/blueprint/print.css" type="text/css" rel="stylesheet" media="print"/>
<!--[if lt IE 8]><link href="${ctx}/css/blueprint/blueprint/ie.css" type="text/css" rel="stylesheet" media="screen, projection"><![endif]-->
<script src="${ctx}/js/jquery-min.js" type="text/javascript"></script>
<script src="${ctx}/js/validate/jquery.validate.js" type="text/javascript"></script>
<script src="${ctx}/js/validate/messages_cn.js" type="text/javascript"></script>
<script>
$(document).ready(function() {
//聚焦第一个输入框
$("#loginName").focus();
//为inputForm注册validate函数
$("#inputForm").validate({
rules: {
loginName: {
required: true,
remote: "user!checkLoginName.action?oldLoginName=" + encodeURIComponent('${loginName}')
},
name: "required",
password: {
required: true,
minlength:3
},
passwordConfirm: {
equalTo:"#password"
},
email:"email",
checkedGroupIds:"required"
},
messages: {
loginName: {
remote: "用户登录名已存在"
},
passwordConfirm: {
equalTo: "输入与上面相同的密码"
}
}
});
});
</script>
</head>
<body>
<div class="container">
<%@ include file="/common/header.jsp" %>
<div id="content">
<div class="span-24 last">
<h3><s:if test="id == null">创建</s:if><s:else>修改</s:else>用户</h3>
<form id="inputForm" action="user!save.action" method="post">
<input type="hidden" name="id" value="${id}"/>
<table class="noborder">
<tr>
<td>登录名:</td>
<td><input type="text" name="loginName" size="40" id="loginName" value="${loginName}"/></td>
</tr>
<tr>
<td>用户名:</td>
<td><input type="text" id="name" name="name" size="40" value="${name}"/></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" id="password" name="password" size="40" value="${password}"/></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" id="passwordConfirm" name="passwordConfirm" size="40" value="${password}"/>
</td>
</tr>
<tr>
<td>邮箱:</td>
<td><input type="text" id="email" name="email" size="40" value="${email}"/></td>
</tr>
<tr>
<td>权限组:</td>
<td>
<s:checkboxlist name="checkedGroupIds" list="allGroupList" listKey="id" listValue="name" theme="custom"/>
</td>
</tr>
<tr>
<td colspan="2">
<shiro:hasPermission name="user:edit">
<input class="button" type="submit" value="提交"/>&nbsp;
</shiro:hasPermission>
<input class="button" type="button" value="返回" onclick="history.back()"/>
</td>
</tr>
</table>
</form>
</div>
</div>
<%@ include file="/common/footer.jsp" %>
</div>
</body>
</html>
@@ -1,85 +0,0 @@
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ page import="org.apache.shiro.SecurityUtils" %>
<%@ include file="/common/taglibs.jsp" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Mini-Web 帐号管理</title>
<%@ include file="/common/meta.jsp" %>
<link href="${ctx}/css/style.css" type="text/css" rel="stylesheet"/>
<link href="${ctx}/css/blueprint/screen.css" type="text/css" rel="stylesheet" media="screen, projection"/>
<link href="${ctx}/css/blueprint/print.css" type="text/css" rel="stylesheet" media="print"/>
<!--[if lt IE 8]><link href="${ctx}/css/blueprint/blueprint/ie.css" type="text/css" rel="stylesheet" media="screen, projection"><![endif]-->
<script src="${ctx}/js/jquery-min.js" type="text/javascript"></script>
<script src="${ctx}/js/table.js" type="text/javascript"></script>
</head>
<body>
<div class="container">
<%@ include file="/common/header.jsp" %>
<div id="content" class="span-24 last prepend-top">
<div id="message"><s:actionmessage theme="custom" cssClass="success"/></div>
<div id="filter">
<form id="mainForm" action="user.action" method="get">
<input type="hidden" name="page.pageNo" id="pageNo" value="${page.pageNo}"/>
<input type="hidden" name="page.orderBy" id="orderBy" value="${page.orderBy}"/>
<input type="hidden" name="page.orderDir" id="orderDir" value="${page.orderDir}"/>
你好, <shiro:principal/>.&nbsp;&nbsp;
登录名: <input type="text" name="filter_EQS_loginName" value="${param['filter_EQS_loginName']}" size="9"/>
姓名或Email: <input type="text" name="filter_LIKES_name_OR_email" value="${param['filter_LIKES_name_OR_email']}" size="9"/>
<input type="button" value="搜索" onclick="search();"/>
</form>
</div>
<div>
<table id="contentTable">
<tr>
<th><a href="javascript:sort('loginName','asc')">登录名</a></th>
<th><a href="javascript:sort('name','asc')">姓名</a></th>
<th><a href="javascript:sort('email','asc')">电邮</a></th>
<th>权限组</th>
<th>操作</th>
</tr>
<s:iterator value="page.result">
<tr>
<td>${loginName}&nbsp;</td>
<td>${name}&nbsp;</td>
<td>${email}&nbsp;</td>
<td>${groupNames}&nbsp;</td>
<td>&nbsp;
<shiro:hasPermission name="user:view">
<shiro:lacksPermission name="user:edit">
<a href="user!input.action?id=${id}">查看</a>&nbsp;
</shiro:lacksPermission>
</shiro:hasPermission>
<shiro:hasPermission name="user:edit">
<a href="user!input.action?id=${id}">修改</a>&nbsp;
<a href="user!delete.action?id=${id}">删除</a>
</shiro:hasPermission>
</td>
</tr>
</s:iterator>
</table>
</div>
<div>
第${page.pageNo}页, 共${page.totalPages}页
<a href="javascript:jumpPage(1)">首页</a>
<s:if test="page.paginator.hasPrePage"><a href="javascript:jumpPage(${page.prePage})">上一页</a></s:if>
<s:if test="page.paginator.hasNextPage"><a href="javascript:jumpPage(${page.nextPage})">下一页</a></s:if>
<a href="javascript:jumpPage(${page.totalPages})">末页</a>
<shiro:hasPermission name="user:edit">
<a href="user!input.action">增加新用户</a>
</shiro:hasPermission>
</div>
</div>
<%@ include file="/common/footer.jsp" %>
</div>
</body>
</html>
@@ -1,77 +0,0 @@
<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/common/taglibs.jsp"%>
<%@ page import="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Mini-Web 登录页</title>
<%@ include file="/common/meta.jsp"%>
<link href="${ctx}/css/style.css" type="text/css" rel="stylesheet" />
<link href="${ctx}/js/validate/jquery.validate.css" type="text/css"
rel="stylesheet" />
<link href="${ctx}/css/blueprint/screen.css" type="text/css"
rel="stylesheet" media="screen, projection" />
<link href="${ctx}/css/blueprint/print.css" type="text/css"
rel="stylesheet" media="print" />
<!--[if lt IE 8]><link href="${ctx}/css/blueprint/blueprint/ie.css" type="text/css" rel="stylesheet" media="screen, projection"><![endif]-->
<script src="${ctx}/js/jquery-min.js" type="text/javascript"></script>
<script src="${ctx}/js/validate/jquery.validate.js"
type="text/javascript"></script>
<script src="${ctx}/js/validate/messages_cn.js" type="text/javascript"></script>
<script>
$(document).ready(function() {
$("#loginForm").validate();
});
</script>
</head>
<body>
<div class="container">
<%@ include file="/common/header.jsp"%>
<div id="content">
<div class="span-24 last">
<%
if (request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME) != null) {
%>
<div class="error">登录失败,请重试.</div>
<%
}
%>
<form id="loginForm" action="login.action" method="post"
style="margin-top: 1em">
<table class="noborder">
<tr>
<td><label for="username">用户名:</label>
</td>
<td><input type='text' id='username' name='username' class="required" value="${username}"
<s:if test="not empty param.error">value=''</s:if> />
</td>
</tr>
<tr>
<td><label for="password">密码:</label>
</td>
<td><input type='password' id='password' name='password'
class="required" value="${password}" />
</td>
</tr>
<tr>
<td colspan="2" align="right">
<input type="checkbox" id="rememberMe" name="rememberMe" value="${rememberMe}" />
<label for="rememberMe">记住我</label> <input value="登录" type="submit" class="button" />
</td>
</tr>
</table>
</form>
<div>
(管理员<b>admin/admin</b>, 普通用户<b>user/user</b>)
</div>
</div>
</div>
<%@ include file="/common/footer.jsp"%>
</div>
</body>
</html>
@@ -1,32 +0,0 @@
function jumpPage(pageNo) {
$("#pageNo").val(pageNo);
$("#mainForm").submit();
}
function sort(orderBy, defaultOrder) {
if ($("#orderBy").val() == orderBy) {
if ($("#orderDir").val() == "") {
$("#orderDir").val(defaultOrder);
}
else if ($("#orderDir").val() == "desc") {
$("#orderDir").val("asc");
}
else if ($("#orderDir").val() == "asc") {
$("#orderDir").val("desc");
}
}
else {
$("#orderBy").val(orderBy);
$("#orderDir").val(defaultOrder);
}
$("#mainForm").submit();
}
function search() {
$("#orderDir").val("");
$("#orderBy").val("");
$("#pageNo").val("1");
$("#mainForm").submit();
}
@@ -1,32 +0,0 @@
/*
* $HeadURL: $
* $Id: $
* Copyright (c) 2011 by Ericsson, all rights reserved.
*/
package org.springside.examples.miniweb.web.security;
import org.apache.shiro.SecurityUtils;
import org.apache.struts2.convention.annotation.Namespace;
import com.opensymphony.xwork2.ActionSupport;
/**
*
* @author neway
*/
@Namespace("/")
public class LoginAction extends ActionSupport {
private static final long serialVersionUID = 7392913081177740732L;
@Override
public String execute() throws Exception {
return SUCCESS;
}
public String logout() throws Exception {
SecurityUtils.getSubject().logout();
return SUCCESS;
}
}
@@ -7,9 +7,9 @@
<!-- 定期执行的业务类 -->
<bean id="jdkExecutorJob" class="org.springside.examples.showcase.schedule.JdkExecutorJob" lazy-init="false">
<!-- 每次执行间隔60秒 -->
<property name="period" value="60" />
<!-- 首次执行延期2秒 -->
<!-- 每次执行间隔120秒 -->
<property name="period" value="120" />
<!-- 首次执行延期1秒 -->
<property name="initialDelay" value="1" />
<!-- shutdown时等待任务完成, 最多等待20秒 -->
<property name="shutdownTimeout" value="20" />