1. 1. winestory中struts2的使用
  2. 2. 什么是Struts
    1. 2.1. Struts的体系结构
    2. 2.2. Struts2的优点
  3. 3. struts2核心配置文件struts.xml详解
    1. 3.1. struts.xml文件示例
    2. 3.2. constant
    3. 3.3. package
    4. 3.4. action
    5. 3.5. result
    6. 3.6. default-action-ref
    7. 3.7. global-results
    8. 3.8. global-exception-mapping
    9. 3.9. include
  4. 4. struts2中action接收参数的三种方法
    1. 4.1. 1.使用action 中的属性接收参数
    2. 4.2. 2.使用DomainModel接收参数:
    3. 4.3. 3使用ModelDriven接收参数
  5. 5. Action获取表单提交数据
    1. 5.1. 获取表单提交数据的三种主要方式
      1. 5.1.1. 1.使用ActionContext
      2. 5.1.2. 2.使用ServletActionContext类
      3. 5.1.3. 3.使用接口注入方式
    2. 5.2. 在action操作域对象
    3. 5.3. struts2提供获取表单数据方式
      1. 5.3.1. 1.原始方式获取表单封装到实体类对象
      2. 5.3.2. 2.属性封装
      3. 5.3.3. 3.模型驱动封装,对于要传入多个model,第二种方式不方便
      4. 5.3.4. 4.可以使用多个module实体对象的封装
    4. 5.4. 封装数据到集合
      1. 5.4.1. 封装数据到list集合
      2. 5.4.2. 封装数据到map集合
  6. 6. struts2结果页面配置
    1. 6.1. action的访问
    2. 6.2. 结果页面配置
      1. 6.2.1. 全局结果页面
      2. 6.2.2. 局部结果页面配置
      3. 6.2.3. result便签的type属性
      4. 6.2.4. 实例
  7. 7. struts2中的重定向问题
    1. 7.1. struts重定向的几种方式
    2. 7.2. struts重定向的实例
    3. 7.3. 我的问题解决
  8. 8. struts2文件上传(以上传头像为例)
    1. 8.1. jsp视图层
    2. 8.2. action层
    3. 8.3. Struts.xml的配置
    4. 8.4. 显示
  9. 9. ssh框架实现分页显示
    1. 9.1. 目的
    2. 9.2. 实现
      1. 9.2.1. 分页类
      2. 9.2.2. 编写action
      3. 9.2.3. 编写service层
      4. 9.2.4. Dao接口层
      5. 9.2.5. Dao层的实现层
      6. 9.2.6. 视图层
      7. 9.2.7. 配置文件

winestory中struts2的使用

使用ssh框架做的一个小论坛是我的第一个项目,ssh框架在现在早已经过时,但是当初学习和解决问题的精神却是最重要的,因此我将相关的博文进行归档,记录并缅怀初学编程时的历程。
这一篇是struts2框架相关内容。

winestory中struts2的使用

什么是Struts

Struts直译过来就是支柱,枝干的意思,它实现了基于javaweb应用的Model-View——Controller设计模式的应用框架

Struts的体系结构

一个请求在Struts2框架中的处理大概会经过以下结构步骤

  1. 客户端发出一个指向Servlet容器(例如Tomcat)的请求
  2. 这个请求会经过结构过滤器Filter(ActionContextCleanUP可选过滤器,其他web过滤器如SiteMesh等),最后到达FilterDispatcher过滤器
  3. 接着FilterDispatcher(过滤调度器)过滤器被调用,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
  4. 如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给Action对象的代理(ActionProxy)
  5. ActionProxy通过配置管理器(Configuration Manager)读取框架的相关的配置文件(Struts.xml以及它包含的*.xml配置文件)找到需要调用的Action类
  6. 找到需要调用的Action类之后,ActionProxy会创建一个ActionInvocation(动作调用)的实例
  7. ActionInvocation在调用Action的过程之前,会先依次调用相关配置拦截器(Intercepter)执行结果返回结果字符串
  8. ActionInvocation负责查找结果字符串对应的Result。然后再执行这个Result,再返回对应的结果视图(如JSP)来呈现界面
  9. 再次调用所用的配置拦截器(调用顺序与第7步相反),然后响应(HttpServletResponse)被返回给浏览器

Struts2的优点

  • Struts2是非侵入式设计,即不依赖与Servlet API和StrutsAPI
  • Strtus2提供了强大的拦截器,利用拦截器可进行AOP编程(面向切面的编程),实现权限的拦截等功能
  • Strtus2提供了类型转换器,可以很方便地进行类型转换,例如将特殊的的请求参数转换成需要的类型
  • Struts2支持多种表现层技术,如JSP、FreeMarker、Vectocity
  • Struts2的输入验证可以对指定的方法进行验证
    笔记来源:实验楼

struts2核心配置文件struts.xml详解

struts.xml文件示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="index" />
<global-results>
<result name="error">/WEB-INF/jsp/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"/>
</global-exception-mappings>
<action name="index">
<result type="redirectAction">
<param name="actionName">HelloWorld</param>
<param name="namespace">/example</param>
</result>
</action>
</package>
<include file="example.xml"/>
</struts>

constant

包含一些属性设置,他可以改变struts框架的一些行为。例如示例中的 struts.enable.DynamicMethodInvocation 设为true,表示设置动态方法调用为真,而 struts.devMode 表示是否启用开发者模式。

package

在struts中,package用来管理action、result、interceptor、interceptor-stack等配置信息

  • name:必须唯一,这样其他package如果引用本package的话,才能找得到。
  • extends:当本package继承其他package的时候,会继承父package的所有配置属性(例如action、result等等);由于package的信息获取是按照struts.xml文件中的先后顺序进行的,因此父package必须在子package之前先定义。通常情况下,继承一个“struts-default.xml”的package,这是 Struts2 默认的package。
    namespace:namespace的配置会改变项目的url访问地址,主要是针对比较大型的项目以方便管理action,因为不同namespace中的action可以同名,从而解决action重名的问题。如果没有指定namespace,则默认为“”。

action

  • name:action的名称
  • class:action对应的java类
  • method:在该class中对应执行Action的函数方法,默认是execute()。
  • converter:类型转换器

result

  • name:具体来说,就是根据某个返回结果,指定响应逻辑,默认是success。
  • type:返回结果的类型,默认为dispatcher。

default-action-ref

如果找不到项目请求的action,就会报出404错误,而且这种错误不可避免,所以我们可以使用 default-action-ref 来指定一个默认的action,如果系统出现找不到action的情况,就会来调用这个默认的action。

global-results

设置package范围内的全局响应结果。在多个action都返回同一个逻辑视图(通常为某个jsp页面)的情况下,可以通过该标签来统一配置。

global-exception-mapping

配置发生异常时的视图信息。exception-mapping是控制action范围内的,而global-exception-mapp是控制package范围内的。两个都配置时,exception-mapping的优先级更高。

include

使用include引入外部配置文件,直接给出url即可

1
<include file="**/**/***.xml" />

使用 include 的好处在于,例如当我们开发一个比较大型的项目的时候,配置文件肯定会写一大堆。如果写在一个配置文件里就不好查看和修改,不便于维护;所以使用 include 后可以根据模块、也可以根据功能来划分,这样就比较清晰,方便管理和维护。
其他较为常用的还有 拦截器等等。
来源:实验楼 https://www.shiyanlou.com/courses/32/labs/920/document

struts2中action接收参数的三种方法

struts2中action接收参数的方法主要有一下三种

1.使用action 中的属性接收参数

  • 定义:在action类中定义属性,创建get和set方法
  • 接收:通过属性接收参数,如userId;
  • 发送:通过属性名传递参数,如:user_usershow?userId=1;

2.使用DomainModel接收参数:

  • 定义:定义Model类,在action中定义Model类的对象(不需要new),创建该对象的get和set方法
  • 接收:通过对象的属性接收参数,如user.getUserName();
  • 发送:使用对象的属相传递参数,如user_usershow?user.user.userName=xxx;

3使用ModelDriven接收参数

  • 定义:action实现ModelDriven泛型接口,定义Model类的对象(必须new),通过getModel方法返回该对象;
  • 接收:通过对象的属性接收参数,如:user.getUserName();
  • 发送:直接使用属性名传递参数,如:user_usershow?userName=xxx

    Action获取表单提交数据

获取表单提交数据的三种主要方式

1.使用ActionContext

Map<String,Object>getParameters() 返回一个包含所有HttpServletRequest参数信息

  1. 因为方法不是静态的方法,需要创建ActionContext类的对象
  2. ActionContext对象不是new出来的 static ActionContext getContext() 获取当前线程的ActionContext对象
  3. 实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public String execute() throws Exception {
//第一种方式:使用ActionContext类获取
//获取ActionContext对象
ActionContext context=ActionContext.getContext();
//调用方法得到表单数据
Map<String, Object> map = context.getParameters();
Set<String> keys=map.keySet();
//根据key得到vaule,使用数组形式是因为输入项可能有复选框
for(String key:keys){
Object[] obj=(Object[]) map.get(key);
System.out.println(Arrays.toString(obj));
}
return NONE;
}

2.使用ServletActionContext类

1
2
3
4
5
6
7
8
9
10
public String execute() throws Exception {
//使用ServletActionContext获取request对象
HttpServletRequest request=ServletActionContext.getRequest();
//调用request里面的方法得到结果
String username=request.getParameter("username");
String password=request.getParameter("password");
String address=request.getParameter("address");
System.out.println(username+" "+password+" "+address);
return NONE;
}

3.使用接口注入方式

在action操作域对象

1
2
3
4
5
6
7
8
9
10
//操作三个域对象
//1.request域
HttpServletRequest request=ServletActionContext.getRequest();
request.setAttribute("req","reqvalue" );
//2.session域
HttpSession session=request.getSession();
session.setAttribute("sess", "sessValue");
//3ServletContext域
ServletContext context=ServletActionContext.getServletContext();
context.setAttribute("contextname", "contextValue");

struts2提供获取表单数据方式

1.原始方式获取表单封装到实体类对象

1
2
3
4
5
6
7
8
9
10
11
12
13
public String execute() throws Exception {
HttpServletRequest request=ServletActionContext.getRequest();
String username=request.getParameter("username");
String password=request.getParameter("password");
String address=request.getParameter("address");
//封装到实体类
User user=new User();
user.setUsername(username);
user.setPassword(password);
user.setAddress(address);
System.out.println(user);
return NONE;
}

2.属性封装

  1. 直接把表单提交属性封装到action属性中
  2. 实现步骤
    1. 在action成员变量位置定义变量,变量名称和表单输入项的name属性值一样
    2. 生成变量的get和set方法
  3. 使用属性封装获取表单数据到属性里面,不能直接把数据封装到实体类对象里面
  4. 实例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class sysAction extends ActionSupport{    
    private String username;

    public String login() throws Exception {
    System.out.println(username);
    return SUCCESS;
    }

    public String getUsername() {
    return username;
    }
    public void setUsername(String username) {
    this.username= username;
    }
    }

3.模型驱动封装,对于要传入多个model,第二种方式不方便

  1. 可以直接把表单数据封装到实体类对象
  2. 实现步骤
    1. action实现接口ModelDriven
    2. 实现接口里面的方法getModel方法
    3. 在action里面创建实体类对象
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      public class DataDemo2Action extends ActionSupport implements ModelDriven<User>{
      //创建对象
      private User user=new User();
      public User getModel() {
      // 返回创建的对象
      return user;
      }
      public String execute() throws Exception {

      return NONE;
      }
      }

4.可以使用多个module实体对象的封装

此种封装方法,变量名称和表单输入项的name属性值不一样,变单输入项样式为

1
2
3
4
5
<form action="sys/login.action" method="post">    
<input type="text" name="user.username">
<input type="text" name="teacher.level">
<input type="submit" value="submit">
</form>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class sysAction extends ActionSupport{    
private User user;
private Teacher teacher;

public String login() throws Exception {
System.out.println(user.getUsername());
System.out.println(teacher.getLevel());
return SUCCESS;
}

public void setUser(User user) {
this.user = user;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
}

封装数据到集合

封装数据到list集合

  1. 在action声明List
  2. 生成list变量的get和set方法
  3. 在表单输入项写表达式

封装数据到map集合

  1. 在action声明map集合
  2. 生成list变量的get和set方法
  3. 在表单输入项写表达式

struts2结果页面配置

action的访问

  • 使用method方法
  • 使用通配符实现

    在action标签里面name属性,name属性值写符号 * ,表示匹配任何内容
  • 动态访问

结果页面配置

全局结果页面

  1. 如果多个action,方法里面返回相同值的时候,可以使用全局结果界面配置

局部结果页面配置

  1. 当存在全局结果页面配置时,依旧以局部结果页面配置为准

result便签的type属性

  1. type属性:如何到路径里
  2. type属性值:
    • 默认值:转发操作,值是dispatcher
    • 重定向:redirect
    • chain:转发到action
    • redirectAction:重定向到action

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="demo1" extends="struts-default" namespace="/">
<action name="user_*" class="userAction" method="{1}">
<!-- <result name="loginsuccess">/index.jsp</result> -->
<result name="loginsuccess" type="redirectAction">story_indexlist</result>
<result name="login">/login.jsp</result>
<result name="logout" type="redirectAction">story_indexlist</result>
<result name="registersuccess">/login.jsp</result>
<result name="usershow">/myinfo.jsp</result>
<result name="showUserinfo">/myinfoedit.jsp</result>
<result name="update" type="redirectAction">story_indexlist</result>
</action>
<action name="story_*" class="storyAction" method="{1}">
<result name="toAddPage">/newstory.jsp</result>
<result name="add" type="redirectAction">story_indexlist</result>
<result name="indexlist">/index.jsp</result>
<result name="storyshow">/storyshow.jsp</result>
<result name="getAllStory">/showbypage.jsp</result>
<result name="addComment">/showbypage.jsp</result>
</action>
<action name="comment_*" class="commentAction" method="{1}">
<result name="add" type="redirectAction">story_show?story_id=${comment.story.story_id}</result>
</action>
</package>
</struts>

struts2中的重定向问题

在处理ssh框架的小论坛项目的时候,遇到一个问题,在一个帖子下需要进行评论,但是在点击评论按钮的时候,后台做出这几个动作:

  1. 存储评论信息到数据库,也就是comment实体;
  2. 重新加载帖子详情和评论详情

    要实现以上需求,可以通过struts的重定向功能来实现

struts重定向的几种方式

  • dispatcher —— 请求转发到一个页面 (默认),不可以用这种方式转发到一个action
  • chain —— 一个action请求转发至另一个 action
  • redirect —— 响应重定向到一个页面,也可以实现响应重定向到action
  • redirectAction —— 一个action响应重定向至另一个 action

struts重定向的实例

  • redirectAction —— 一个action响应重定向至另一个 action,这种是不带参数的

    1
    <result name="loginsuccess" type="redirectAction">story_indexlist</result>
  • 带参数的redirectAction

    1
    <result type="redirect">successAction?name=${name}</result>

我的问题解决

我的项目的重定向就需要参数,在重现加载帖子和评论的时候需要知道帖子的id,具体的解决方案如下

1
<result name="add" type="redirectAction">story_show?story_id=${comment.story.story_id}</result>

在comment的action中,重定向,并获取参数,这里可能有问题的就是参数的获取,这个参数的获取和action方法中的属性获取有关系,可能有以下的集中情况

  • 根据你的action获取表单数据方式的不同,${}里面的参数书写方式也不同,如果是属性,并有getter和setter方法,那么可以直接写属性值,如果是其他的方式获取,则要根据你的情况来设置
  • 如果这个参数是实体内的实体对象,比如我需要的storyId,则是comment实体内的一个story对象,在这个story对象里具有storyId这个值,那么就需要使用上面的方式${comment.story.story_id}如果使用${comment.story_id}是会报错

    我的comment Action如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package cn.haigeek.action;
import cn.haigeek.entity.Comment;
import cn.haigeek.service.CommentService;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;
/**
* Created by haigeek on 2017/7/22.
*/
public class CommentAction extends ActionSupport {
Date date = new Date();
private Comment comment;
private CommentService commentService;
//private Integer storyId;
public void setCommentService(CommentService commentService) {
this.commentService = commentService;
}
public Comment getComment() {
return comment;
}
public void setComment(Comment comment) {
this.comment = comment;
}
public String add(){
comment.setCommentDate(date);
commentService.add(comment);
return "add";
}
}

struts2文件上传(以上传头像为例)

在java的ssh项目中,需要为注册的用户设置一个头像,具体解决方案如下

jsp视图层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<form action="${pageContext.request.contextPath }/user_updateavatar.action?user.usid=${user.uid}"
method=post enctype="multipart/form-data">
<input type="hidden" name="user.uid" value="${user.uid }"/>
<div class="panel panel-default">
<div class="panel-body">
<br>
<div class="mdui-card-header-title">头像上传</div>
<div class="mdui-container">
<input type="file" name="avatar">
<button class="mdui-btn mdui-btn-dense mdui-color-blue mdui-float-right mdui-m-a-2">
保存
</button>
</div>
</div>
</div>
</form>

input类型要设置为type为File类型,name需要对应action中的命名

action层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
private File avatar;//上传文件域
private String avatatFileType;//上传文件类型
private String avatarFileName;//上传文件名字
private String savePathAvatar;//文件存储位置,在struts2中配置
//对应的get和set方法
public String updateavatar(){
//文件在本地的具体存储位置
String path=ServletActionContext.getServletContext().getRealPath("/")+getSavePathAvatar()+"\\"+getAvatarFileName();
//文件存储到数据库的路径(根据实际情况来设置)
String path2=getSavePathAvatar()+"/"+getAvatarFileName();
try{
FileOutputStream fos=new FileOutputStream(path);
FileInputStream fis=new FileInputStream(getAvatar());
byte[]buffer=new byte[1024];
int len=0;
try {
while ((len=fis.read(buffer))>0){
fos.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//接受页面传过来的用户id
int uid=user.getUid();
User user4=userService.findOne(uid);
user4.setAvatar(path2);
//调用service进行路径的存储
userService.update(user4);
return "update";
}

Struts.xml的配置

1
2
3
4
<action name="user_*" class="userAction" method="{1}">
<!-- 动态设置存储位置的值 -->
<param name="savePathAvatar">/upload/avatar</param>
</action>

显示

1
<img src="${story.user.avatar}"/></div>

我的项目是显示这个story对应的用户的头像

ssh框架实现分页显示

目的

最近在写的一个java小论坛的首页想要实现首页帖子列表的分页显示

实现

分页类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package cn.haigeek.entity;

/**
* Created by haigeek on 2017/7/16.
*/
public class pageShow {
//此类用于分页
private int pageNow;//当前页
private int totalSize;//总条数
private int totalPage;//总页数
private int pageSize = 10;//每页显示条数
private boolean hasPre;//是否有上一页
private boolean hasNext;//是否有下一页
private boolean hasFirst;//是否有首页
private boolean hasLast;//是否有尾页

public pageShow(int pageNow, int totalSize) {
//构造方法
this.setPageNow(pageNow);
this.setTotalSize(totalSize);
}

public pageShow(int pageNow, int totalSize, int pageSize) {//可动态改变每页条数
//构造方法
this.setPageNow(pageNow);
this.setTotalSize(totalSize);
this.pageSize = pageSize;
}

public void setPageNow(int pageNow) {
this.pageNow = pageNow;
}

public int getPageNow() {
return pageNow;
}

public void setTotalSize(int totalSize) {
this.totalSize = totalSize;
}

public int getTotalSize() {
return totalSize;
}

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

public int getPageSize() {
return pageSize;
}

public int getTotalPage() {//总页数 = 总条数/每页显示条数
totalPage = this.getTotalSize() / this.getPageSize();
if (this.getTotalSize() % this.getPageSize() != 0) {
totalPage++; //若余数为不0 则要多加一页
}
return totalPage;
}

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

public boolean isHasPre() {//是否有上一页 除第一页以外都有上一页 说明有首页的就有上一页
if (this.isHasFirst()) {
return true;
} else return false;
}

public void setHasPre(boolean hasPre) {
this.hasPre = hasPre;
}

public boolean isHasNext() {//是否有下一页 除最后一页以外都有下一页 说明有尾页的就有下一页
if (this.isHasLast()) {
return true;
} else return false;
}

public void setHasNext(boolean hasNext) {
this.hasNext = hasNext;
}

public boolean isHasFirst() {//是否有首页 除第一页以外都有首页
if (this.pageNow == 1)//是第一页就没有首页
return false;
else
return true;
}

public void setHasFirst(boolean hasFirst) {
this.hasFirst = hasFirst;
}

public boolean isHasLast() {//是否有尾页 除最后一页以外都有尾页
if (pageNow == this.getTotalPage()) {//最后一页
return false;
} else return true;
}

public void setHasLast(boolean hasLast) {
this.hasLast = hasLast;
}
}

编写action

1
2
3
4
5
6
7
8
9
10
public String getAllStory(){
List <Story>StoryList=storyService.getAllStory(pageNow,pageSize);
//放进域对象
ServletActionContext.getRequest().setAttribute("StoryList", StoryList);
//放入request对象
Map request= (Map) ActionContext.getContext().get("request");
pageShow page=new pageShow(pageNow,storyService.findStorySize(),pageSize);
request.put("page",page);
return "getAllStory";
}

编写service层

1
2
3
4
5
6
7
8
	//service层
public List <Story>getAllStory(int page,int pageSize){
return storyDao.getAllStory(page,pageSize);
}
//获取帖子数目
public int findStorySize(){
return storyDao.findStorySize();
}

Dao接口层

1
2
3
int findStorySize();

List <Story>getAllStory(int page, int pageSize);

Dao层的实现层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class StoryDaoImpl extends HibernateDaoSupport implements StoryDao {
public int findStorySize() {
Session session=getSessionFactory().openSession();
String hql = "from Story ";
int size = session.createQuery(hql).list().size();
session.close();
return size;
}
public List<Story> getAllStory(int pageNow, int pageSize) {
//获取session的方式很重要,这里的dao层是继承了HibernateDaoSupport来实现dao接口
Session session=this.getHibernateTemplate().getSessionFactory().getCurrentSession();
String hql="from Story order by story_id desc ";
Query query = session.createQuery(hql);//执行查询操作
query.setFirstResult((pageNow - 1) * pageSize);
query.setMaxResults(pageSize);
List <Story> StoryList = query.list();
return StoryList;

}
}

视图层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<div class="panel-body">
<c:forEach items="${StoryList }" var="story">
<ul class="mdui-list">
<a href="${pageContext.request.contextPath }/story_show.action?story_id=${story.story_id}">
<li class="mdui-list-item mdui-ripple">
<div class="mdui-list-item-avatar"><img src="avatar1.jpg"/></div>
<div class="mdui-list-item-content">
<div class="mdui-list-item-title mdui-list-item-two-line">${story.story_title}</div>
<div class="mdui-list-item-text mdui-list-item-one-line"> ${story.user.username}发表在说天谈地
最后回复:haigeek 2017.06.07
</div>
</div>
</li>
</a>
</ul>
</c:forEach>
<s:set name="page" value="#request.page"></s:set>
<nav aria-label="Page navigation">
<ul class="pagination center-block">
<s:if test="#page.hasPre">
<li>
<a href=story_getAllStory?pageNow=<s:property value="#page.pageNow-1"/>
aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
</s:if>
<s:if test="#page.hasFirst">
<li>
<a href="story_getAllStory?pageNow=1"
aria-label="Previous">
<span aria-hidden="true">首页</span>
</a>
</li>
</s:if>

<li><a href="story_getAllStory?pageNow=1">1</a></li>
<li><a href="story_getAllStory?pageNow=2">2</a></li>
<li><a href="story_getAllStory?pageNow=3">3</a></li>
<li><a href="story_getAllStory?pageNow=4">4</a></li>
<li><a href="story_getAllStory?pageNow=5">5</a></li>
<s:if test="#page.hasLast">
<li>
<a href=story_getAllStory?pageNow=<s:property value="#page.totalPage"/>
aria-label="Previous">
<span aria-hidden="true">尾页</span>
</a>
</li>
</s:if>
<s:if test="#page.hasNext">
<li>
<a href="story_getAllStory?pageNow=<s:property value="#page.pageNow+1" /> "
aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</s:if>
</ul>

</nav>
</div>

视图使用了一些样式(bootstrap等),主要是标签的使用,需要加入

1
2
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib uri="/struts-tags" prefix="s" %>

配置文件

配置struts.xml和spring配置文件即可,我的项目主要是添加功能,配置文件已经配置好,只贴了核心的代码,最后在struts.xml添加一项配置即可