项目总结:
1.使用paper.jsp中使用jstl需要引入3个包:jsf-api.jar,jsf-impl.jar,jstl-1.2.jar
使用paper的标签需要引入:pager-taglib.jar
然后如何引入?
<%@taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
第一条在pager-taglib.jar/META-INF/taglib.tld中的shortname和uri即可找到
第二条在jstl-1.2.jar/META-INF/c.tld/中的shortname和uri即可找到
2.log4j.properties中log4j.rootLogger=warn, stdout改为log4j.rootLogger=error, stdout即可忽略warn错误
3:
UserAction
@Controller("userAction")
@Scope("prototype")
public class UserAction extends ActionSupport implements ModelDriven<User>{
private User user;//使用user进行user属性的传输(username,id传到action等)
private IGroupService groupService;
private IUserService userService;
private int gid;
public IUserService getUserService() {
return userService;
}
@Resource
public void setUserService(IUserService userService) {
this.userService = userService;
}
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public IGroupService getGroupService() {
return groupService;
}
@Resource
public void setGroupService(IGroupService groupService) {
this.groupService = groupService;
}
@Override
public User getModel() {
// TODO 自动生成的方法存根
if(user==null) user=new User();
return user;
}
public String addInput() {
ActionContext.getContext().put("gs", groupService.listAllGroup());
return SUCCESS;
}
public void validateAdd() {
if(user.getUsername()==null||"".equals(user.getUsername().trim())) {
this.addFieldError("username", "用户名不能为空");
}
if(user.getNickname()==null||"".equals(user.getNickname().trim())) {
this.addFieldError("nickname", "昵称不能为空");
}
if(user.getPassword()==null||"".equals(user.getPassword().trim())) {
this.addFieldError("password", "密码不能为空");
}
if(this.hasFieldErrors()) {
ActionContext.getContext().put("gs", groupService.listAllGroup());
}//当有错误时,就会返回input界面,此时如果没有重新传入gs,下拉框没有值,就会空指针异常
}
public String add() {
userService.add(user, gid);
ActionContext.getContext().put("url","/user_list.action");
return "redirect";
}
public String list() {
ActionContext.getContext().put("us",userService.findUser());
return SUCCESS;
}
public String delete() {
userService.delete(user.getId());
ActionContext.getContext().put("url","/user_list.action");
return "redirect";
}
public String updateInput() {
ActionContext.getContext().put("gs", groupService.listAllGroup());
User tu=userService.load(user.getId());
user.setNickname(tu.getNickname());//设置user值,在jsp界面即可取到值,所以文本框等就有值
user.setPassword(tu.getPassword());
user.setUsername(tu.getUsername());
this.gid=tu.getGroup().getId();//设置gid,在jsp页面即可实现下拉框选中
return SUCCESS;
}
public String update() {
User tu=userService.load(user.getId());//获取要更新的用户
tu.setNickname(user.getNickname());//获取文本框里的内容(即user属性的内容),然后将要更新的用户进行修改
tu.setPassword(user.getPassword());
tu.setUsername(user.getUsername());
userService.update(tu);
ActionContext.getContext().put("url","/user_list.action");
return "redirect";
}
}
validateAdd中当有错误时,就会返回input界面,此时如果没有重新传入gs,下拉框没有值,就会空指针异常
GroupAction:
@Controller("groupAction")
@Scope("prototype")
public class GroupAction extends ActionSupport implements ModelDriven<Group>{
/**
*
*/
private static final long serialVersionUID = 9035927090402972047L;
private IGroupService groupService;
private Group group;
private int cid;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public IGroupService getGroupService() {
return groupService;
}
@Resource
public void setGroupService(IGroupService groupService) {
this.groupService = groupService;
}
public String list() {
System.out.println("list");
ActionContext.getContext().put("gl", groupService.listAllGroup());
return SUCCESS;
}
public String show() {
System.out.println(cid);
group=groupService.load(cid);
System.out.println(group);
return SUCCESS;
}
public String addInput() {
return SUCCESS;
}
public String add() {
groupService.add(group);
ActionContext.getContext().put("url", "/group_list.action");
return "redirect";
}
public void validateAdd() {
if(group.getName()==null||"".equals(group.getName().trim())) {
this.addFieldError("name", "组名不能为空!");
}
}
public String updateInput() {
Group tg=groupService.load(group.getId());
group.setName(tg.getName());
return SUCCESS;
}
public String update() {
Group tg=groupService.load(group.getId());
tg.setName(group.getName());
groupService.update(tg);
ActionContext.getContext().put("url", "/group_list.action");
return "redirect";
}
public String delete() {
groupService.delete(group.getId());
ActionContext.getContext().put("url", "/group_list.action");
return "redirect";
}
@Override
public Group getModel() {
// TODO 自动生成的方法存根
if(group==null) group=new Group();
return group;
}
}
BaseDao:
package spring.dao;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import spring.model.Pager;
import spring.model.SystemContext;
public class BaseDao<T> extends HibernateDaoSupport implements IBaseDao<T>{
private Class<T> clz;
@SuppressWarnings("unchecked")
public Class<T> getClz() {
if(clz==null) {
clz = ((Class<T>)
(((ParameterizedType)(this.getClass().getGenericSuperclass())).getActualTypeArguments()[0]));
}
return clz;
}
public void setClz(Class<T> clz) {
this.clz = clz;
}
@Resource(name="sessionFactory")
public void setSuperSessionFactory(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
@Override
public void add(T t) {
// TODO 自动生成的方法存根
this.getHibernateTemplate().save(t);
}
@Override
public void delete(int id) {
// TODO 自动生成的方法存根
this.getHibernateTemplate().delete(this.load(id));
}
@Override
public void update(T t) {
// TODO 自动生成的方法存根
this.getHibernateTemplate().update(t);
}
@Override
public T load(int id) {
// TODO 自动生成的方法存根
return this.getHibernateTemplate().load(getClz(), id);
}
@Override
public List<T> list(String sql) {
// TODO 自动生成的方法存根
return list(sql, null);
}
@Override
public List<T> list(String sql, Object[] args) {
// TODO 自动生成的方法存根
@SuppressWarnings("unchecked")
Query<T> q=this.getSessionFactory().getCurrentSession().createQuery(sql);
if(args!=null) {
for(int i=0;i<args.length;i++) {
q.setParameter(i, args[i]);
}
}
List<T> list=q.list();
return list;
}
@Override
public List<T> list(String sql, Object args) {
// TODO 自动生成的方法存根
return list(sql, new Object[] {args});
}
@Override
public Pager<T> find(String sql) {
// TODO 自动生成的方法存根
return find(sql, null);
}
@Override
public Pager<T> find(String sql, Object[] args) {
// TODO 自动生成的方法存根
Pager<T> pager=new Pager<>();
int pageSize=SystemContext.getPageSize();
int pageOffset=SystemContext.getPageOffset();
Query q=this.getSessionFactory().getCurrentSession().createQuery(sql);
Query cq=this.getSessionFactory().getCurrentSession().createQuery(getCountSql(sql));
if(args!=null) {
for(int i=0;i<args.length;i++) {
q.setParameter(i, args[i]);
cq.setParameter(i, args[i]);
}
}
q.setFirstResult(pageOffset);
q.setMaxResults(pageSize);
List<T> datas=q.list();
long totalRecord=(long)cq.uniqueResult();
pager.setDatas(datas);
pager.setPageOffset(pageOffset);
pager.setPageSize(pageSize);
pager.setTotalRecord(totalRecord);
return pager;
}
@Override
public Pager<T> find(String sql, Object args) {
// TODO 自动生成的方法存根
return find(sql,new Object[] {args});
}
public String getCountSql(String sql){
String s=sql.substring(0, sql.indexOf("from"));
System.out.println(s);
if("".equals(s.trim())) {//注意是""而不是使用null
s="select count(*) "+sql;
}else {
s=s.replace(s, "select count(*) ");
}
return s;
}
}
SystemContext:
public class SystemContext {
private static ThreadLocal<Integer> pageSize=new ThreadLocal<Integer>();
private static ThreadLocal<Integer> pageOffset=new ThreadLocal<Integer>();
public static int getPageSize() {
return pageSize.get();
}
public static void setPageSize(int _pageSize) {
pageSize.set(_pageSize);
}
public static int getPageOffset() {
return pageOffset.get();
}
public static void setPageOffset(int _pageOffset) {
pageOffset.set(_pageOffset);
}
public static void removePageOffset() {
pageOffset.remove();
}
public static void removePageSize() {
pageSize.remove();
}
}
通过ThreadLocal实现不同层数据的传送(Action-Dao),实现getter setter remove方法。
SystemContextFilter:
public class SystemContextFilter implements Filter{
private int pageSize=10;
@Override
public void destroy() {
// TODO 自动生成的方法存根
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
// TODO 自动生成的方法存根
try {
int pageOffset=0;
try {
pageOffset=Integer.parseInt(req.getParameter("pager.offset"));
} catch (NumberFormatException e) {
}
SystemContext.setPageOffset(pageOffset);
SystemContext.setPageSize(pageSize);
chain.doFilter(req, resp);//一定要chain.doFilter才可以继续执行
}finally{
SystemContext.removePageOffset();
SystemContext.removePageSize();
}
}
@Override
public void init(FilterConfig cfg) throws ServletException {
// TODO 自动生成的方法存根
try {
pageSize=Integer.parseInt(cfg.getInitParameter("pageSize"));
} catch (NumberFormatException e) {
}
}
}
注意:(1).执行完毕,finally进行removePageSize,removePageOffset
(2).实现给pageSize和pageOffset设置初始值,如果pageSize在配置文件中获取不到(即interger.paseInt(null)),捕获异常,但是不抛出,pageOffset在request中获取不到也是这个思路
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener><!-- 创建监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:beans.xml</param-value>
</context-param>
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping><!-- 创建OpenSessionInViewFilter -->
<!-- OpenSessionInViewFilter允许这个request使用的是一个session,可以在request的任何时期延迟加载数据 -->
<!-- 要想该过滤器起作用,必须设置在struts2过滤器之前 -->
<filter>
<filter-name>SystemContextFilter</filter-name>
<filter-class>spring.filter.SystemContextFilter</filter-class>
<init-param>
<param-name>pageSize</param-name>
<param-value>15</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SystemContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping><!-- 创建struts过滤器 -->
</web-app>
自己写的过滤器一定要在struts过滤器之前!
pager:
public class Pager<T> {
private List<T> datas;
private long totalRecord;
private int pageSize;
private int pageOffset;
public List<T> getDatas() {
return datas;
}
public void setDatas(List<T> datas) {
this.datas = datas;
}
public long getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(long totalRecord) {
this.totalRecord = totalRecord;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPageOffset() {
return pageOffset;
}
public void setPageOffset(int pageOffset) {
this.pageOffset = pageOffset;
}
}
paper最基本4个参数,datas,pageSize,pageOffset,totalRecord
pager.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">
<%@taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<pg:pager items="${us.totalRecord }" export="curPage=pageNumber" url="${param.url }"><!-- 此处的pageNumber是当前页的意思 -->
<pg:first>
<a href="${pageUrl }">首页</a><!-- pageUrl为该标签自动导出的值,直接使用即可 -->
</pg:first>
<pg:prev>
<a href="${pageUrl }">上一页</a>
</pg:prev>
<pg:pages><!-- 每次点一下页面,就会刷新,此时就会循环输出每一个页码,当输出的页码等于当前页码,就不加超链接 -->
<c:if test="${curPage eq pageNumber }">
${pageNumber }
</c:if>
<c:if test="${curPage ne pageNumber }">
<a href="${pageUrl }">${pageNumber }</a>
</c:if>
</pg:pages>
<pg:next>
<a href="${pageUrl }">下一页</a>
</pg:next>
<pg:last>
<a href="${pageUrl }">尾页</a>
</pg:last>
</pg:pager>
pageUrl为该标签自动导出的值,直接使用即可
group/addInput:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<h1>添加组:</h1>
<s:form action="group_add" method="post">
<s:textfield label="组名" name="name"/><!-- 此处不需要再加: -->
<s:submit value="添加组"/>
</s:form>
</body>
</html>
label里面的内容不需要再加冒号
group/list:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<s:iterator value="#gl"><!-- 取ActionContext中的数据需要# -->
${id }----<a href="group_show.action?cid=${id }">${name }</a>
-<a href="group_delete.action?id=${id }">删除</a><!-- 这里的id是设置在group.id中,所以在action中要通过group.getid获取 -->
-<a href="group_updateInput.action?id=${id }">更新</a>
<br>
</s:iterator>
</body>
</html>
group/show:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!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>组信息</title>
</head>
<body>
<h1>组名称:${group.name }</h1><!-- 在action中有group中的name已经设置了值,此处自动获取 -->
</body>
</html>
group/updateInput
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<h1>更新组:</h1>
<s:form action="group_update" method="post">
<s:hidden name="id"/><!-- 把id传到update中处理,要不然只传修改后的name而没有id是无法进行修改的 -->
<s:textfield label="组名" name="name"/>
<s:submit value="更新组"/>
</s:form>
</body>
</html>
注意:(1).要通过hidden把id传到update
user/addInput:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<h1>用户添加:</h1>
<s:form action="user_add" method="post">
<s:textfield label="用户名称" name="username"/>
<s:password label="用户密码" name="password"/>
<s:textfield label="用户昵称" name="nickname"/>
<s:select list="#gs" label="选择组" listKey="id" listValue="name" name="gid"/>
<s:submit value="添加"/>
</s:form>
</body>
</html>
user/list:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<s:iterator value="#us.datas"><!--获取pager中的datas -->
${id }----<a href="user_show.action?id=${id }">${username }</a>
----${password }----${nickname }----${group.name }
<a href="user_delete.action?id=${id }">删除</a>
<a href="user_updateInput.action?id=${id }">更新</a>
<br>
</s:iterator>
<jsp:include page="/inc/pager.jsp"><!--引入paper -->
<jsp:param value="user_list.action" name="url"/><!-- 传进去url -->
<jsp:param value="${us.totalRecord }" name="items"/><!-- 传进去总记录数 -->
</jsp:include>
</body>
</html>
user/update:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!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>Insert title here</title>
</head>
<body>
<h1>用户更新:</h1>
<s:form action="user_update" method="post">
<s:hidden name="id"/>
<s:textfield label="用户名称" name="username"/>
<s:textfield label="用户密码" name="password"/>
<s:textfield label="用户昵称" name="nickname"/>
<s:select list="#gs" label="选择组" listKey="id" listValue="name" name="gid"/>
<s:submit value="更新"/>
</s:form>
</body>
</html>