Action是用于处理请求操作的,它是由StrutsPrepareAndExceuteFilter分发过来的,
一、Action的创建方式
Action的创建方式有三种。
1、POJO类(PlainOldJavaObjects简单的Java对象),不需要继承任何父类,实现任何接口。
如:创建一个TestAction.java代码如下。
(1) 在项目的JavaResource\src目录中创建一个数据包,包名为“action”。
(2) 在action数据包中创建一个类TestAction.java,如下图所示。
该文件的代码如下:
package action;
publicclass TestAction {
public String execute() {//自定的action必须包含有execute()这个方法
return "success";
}
}
这种方式是Struts2框架通过反射来实现的,步骤:
A、struts2框架通过读取struts.xml配置文件获得完整的Action类名;
B、object =Class.forName("完整类名").newInstance();
C、Methodmethod = Class.forName("完整类名").getMethod("execute");
D、method.invoke(object);
2、实现Action接口
在javaResource\src\action数据包中创建ITestAction.java,。
该文件的代码如下:
packageaction;
importcom.opensymphony.xwork2.Action;
publicclass ITestAction implements Action {
@Override
public String execute() throws Exception{
return "success";
}
}
Action接口中,定义默认五种逻辑视图名称,我们打开类库的Action.java文件就会看到定义的五个常量和一个抽象方法execute()。如下图所示。
其中五个常量的含义如下。
public static final String ERROR ="error"; // 数据处理发送错误 (错误页面)
public static final String INPUT ="input"; // 用户输入数据有误,通常用于表单数据校验 (输入页面)
public static final String LOGIN ="login"; // 主要权限认证 (登陆页面)
public static final String NONE ="none"; // 页面不跳转 return null; 效果一样
public static final String SUCCESS= "success"; // 数据处理成功 (成功页面)
3、继承ActionSupport类(推荐)
其实ActionSupport类本身已经实现了Action接口,而且可以在Action中使用表单校验、错误信息设置、读取国际化信息三个功能,所以推荐使用。
在javaResource\src\action数据包中创建STestAction.java,如下图所示。
该文件的代码如下:
package action;
import com.opensymphony.xwork2.ActionSupport;
publicclassSTestAction extends ActionSupport {
@Override
public String execute() throws Exception {
return"success";
}
}
二、Action的访问
为了讲解该内容我们先做下面的准备工作。需要对login数据表进行增删改查操作。
1、在mysql数据库管理系统中创建一个数据库stsc,并在数据库中创建一个login数据表,表的结构如下:
2、创建持久层的创建(参见第三章的3.6.2.2)
3、数据库类的创建(参见第三章的3.6.2.3)
4、业务层的创建(参见第三章的3.6.2.4)
5、easyui创建用户的界面(参见第三章的3.6.2.5)
6、创建对数据表login进行添加、更新、删除和查询相应的Action.即LoginAction.java,代码如下:
package action;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.opensymphony.xwork2.ActionSupport;
import bussiness.Blogin;
import entity.LoginEntity;
public class LoginAction extends ActionSupport {
private HttpServletResponse response;// 用于获取servlet中的请求对象。便于向客户反馈信息
private HttpServletRequest request;// 用于获取servlet中的请求对象。便于获取表单传送过来的各种数据,如删除或更新时传送过来的关键字id的值
private LoginEntity loginEntity;// 用于获取表单中与loginEntity各属性同名的变量的值或对表单中各变量赋值,注意表单中的name的属性值与对象。属性要一致,如<input id="name" name="loginEntity.name" />这里的name的属性值为loginEntity.name,这样我们在strust2中才能正确接收到数据。
private List<LoginEntity> listlogin;// 获取数据表中所有记录。
public LoginAction(){
response=ServletActionContext.getResponse();//获取Response对象
request=ServletActionContext.getRequest();//获取Request对象
try {
request.setCharacterEncoding("utf-8");//设置接数据的编码为utf-8
response.setContentType("text/html;charset=utf-8");//设置输出编码为utf-8,以防出现乱码
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public LoginEntity getLoginEntity() {
return loginEntity;
}
public void setLoginEntity(LoginEntity loginEntity) {
this.loginEntity = loginEntity;
}
public List<LoginEntity> getListlogin() {
return listlogin;
}
public void setListlogin(List<LoginEntity> listlogin) {
this.listlogin = listlogin;
}
/**
* 该方法用户向login数据表添加一条记录
* @return 这个方法没有返回值,因为我们不需要Action作跳转所以返回的是null
*/
public String insert() {
try {
//调用业务类的insert()方法向数据表添加数据
if (Blogin.insert(loginEntity)) {
response.getWriter().println("添加数据成功");
} else {
response.getWriter().println("添加数据失败");
}
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}
/**
* 该方法用户向login数据表更新一条记录
* @return 这个方法没有返回值,因为我们不需要Action作跳转所以返回的是null
*/
public String update() {
try {
//通过业务类的update()方法,对满足条件的记录进行更新操作
if (Blogin.update(loginEntity)) {
response.getWriter().println("更新数据成功");
} else {
response.getWriter().println("更新数据失败");
}
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}
/**
* 该方法用户向login数据表删除满足条件的记录
* @return 这个方法没有返回值,因为我们不需要Action作跳转所以返回的是null
*/
public String del() {
try {
if (Blogin.del(Long.parseLong(request.getParameter("id")))) {
response.getWriter().println("删除数据成功");// 删除成功向用户输出"删除数据成功"
} else {
response.getWriter().println("删除数据失败");// 删除失败,向用户输出“删除数据失败”
}
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}
/**
* 该方法用于读取login数据表中所有记录
* @return 这个方法没有返回值,因为我们不需要Action作跳转所以返回的是null
*/
public String select(){
try {
//通过业务类的select()方法获取login数据表中所有数据
listlogin=Blogin.select();
//实例化Gson类,它主要用于把数据集中的对象(login数据表实体类的对象)转化为json数据格式
Gson gs=new GsonBuilder().create();
//把数据集list转化为json格式的字符口串
String jsonstr=gs.toJson(listlogin);
//把json数据传给实词端
response.getWriter().print(jsonstr);
return null;
} catch (IOException e) {
return null;
}
}
}
7、struts.xml文件的配置,文件内容如下。
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/login" extends="struts-default">
<action name="insert" class="action.LoginAction" method="insert">
</action>
<action name="update" class="action.LoginAction" method="update">
</action>
<action name="delete" class="action.LoginAction" method="del">
</action>
<action name="search" class="action.LoginAction" method="select">
</action>
</package>
8、界面的创建(easyui创建用户界面)(参见第三章的3.6.2.5)
但需要把添加、更新表单的输入域和删除中的部分代码修改,完整代码如下 :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>管理员信息列表</title>
<link rel="stylesheet" type="text/css"
href="js/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="js/themes/icon.css">
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.easyui.min.js"></script>
<script type="text/javascript" src="js/easyui-lang-zh_CN.js"></script>
<script type="text/javascript">
function update(row) {//该函数用于处理当用户单击工具栏上的更新按钮事件
if ($("#dd") != null) {//判断页面中是滞存在id等于dd元素,若存则删除它
$("#dd").remove();
}
$("body").append("<div id='dd'></div>");//在页面的body元素中添加一个div元素,且它的id="dd"
$('#dd').dialog({ //定义一个弹出一个窗口
title : '更新管理员', //窗口的标题
width : 280, //窗口的宽度
height : 140, //窗口的高度
closed : false, //窗口没有显示关闭按钮
cache : false, //没有设置缓冲
modal : true,//设置窗口模式为真的
buttons : [ { //为窗口设置两个按钮,即登录和重置两个按钮
text : '更新',
handler : function() {//当单击登录按钮时,调用send()方法进行处理表单
$('#ff').form('submit', {
url : "update",//当用于单击提交按钮时,把表单数据提交到后台updatelogin.jsp进行处理
onSubmit : function() {
//在这里可以对用户输入的信息进行验证操作
if ($("#name").val() == "") {//判断用户名输入框是否为空,若为空则提示用户,并返回到登录界面
$.messager.alert('错误', '用户名不能为空');
return false;
}
if ($("#pass").val() == "") {//判断密码输入框是否为空,若为空则提示用户,并返回到登录界面
$.messager.alert('错误', '密码不能为空');
return false;
}
},
success : function(data) { //若提交成功则弹出对话框提示用户
$('#dd').dialog("close");//关闭当前添加窗口
$('#dg').datagrid("reload");//重新装入表格的内容
}
});
}
}, {
text : '关闭',
handler : function() {//当单击重置按钮所要执行的任务
$('#dd').dialog("close");//关闭当前添加窗口
$('#dg').datagrid("reload");//重新装入表格的内容
}
} ]
});
//str变量是构建添加管理员表单
var str = "";
str += '<form id="ff" method="post">';
str += '<table>';
str += '<tr>';
str += '<td>用户名:</td>';
<!-- 注意input中的name的属性值-->
str += '<td><input name="loginEntity.name" id="name" type="text"></input></td>';
str += '</tr>';
str += '<tr>';
str += '<td>密 码:</td>';
str += '<td><input name="loginEntity.pass" id="pass" type="password"></input><input name="loginEntity.id" id="id" type="hidden"></input></td>';
str += '</tr>';
str += '</table>';
str += '</form>';
$("#dd").html(str);//把表单放到id="dd"元素,即把表单放到对话框中
$("#name").val(row[0]["name"]);
$("#pass").val(row[0]["pass"]);
$("#id").val(row[0]["id"]);
}
function insert() {
if ($("#dd") != null) {//判断页面中是滞存在id等于dd元素,若存则删除它
$("#dd").remove();
}
$("body").append("<div id='dd'></div>");//在页面的body元素中添加一个div元素,且它的id="dd"
$('#dd').dialog({ //定义一个弹出一个窗口
title : '添加管理员', //窗口的标题
width : 280, //窗口的宽度
height : 140, //窗口的高度
closed : false, //窗口没有显示关闭按钮
cache : false, //没有设置缓冲
modal : true,//设置窗口模式为真的
buttons : [ { //为窗口设置两个按钮,即登录和重置两个按钮
text : '添加',
handler : function() {//当单击登录按钮时,调用send()方法进行处理表单
$('#ff').form('submit', {
url : "insert",//当用于单击提交按钮时,把表单数据提交到后台insertlogin这个后台服务程序(Servlet)进行处理
onSubmit : function() {
//在这里可以对用户输入的信息进行验证操作
if ($("#name").val() == "") {//判断用户名输入框是否为空,若为空则提示用户,并返回到登录界面
$.messager.alert('错误', '用户名不能为空');
return false;
}
if ($("#pass").val() == "") {//判断密码输入框是否为空,若为空则提示用户,并返回到登录界面
$.messager.alert('错误', '密码不能为空');
return false;
}
},
success : function(data) { //若提交成功则弹出对话框提示用户
$('#dd').dialog("close");//关闭当前添加窗口
$('#dg').datagrid("reload");//重新装入表格的内容
}
});
}
}, {
text : '关闭',
handler : function() {//当单击重置按钮所要执行的任务
$('#dd').dialog("close");//关闭当前添加窗口
$('#dg').datagrid("reload");//重新装入表格的内容
}
} ]
});
//str变量是构建添加管理员表单
var str = "";
str += '<form id="ff" method="post">';
str += '<table>';
str += ' <tr>';
str += ' <td>用户名:</td>';
str += ' <td><input name="loginEntity.name" id="name" type="text"></input></td>';
str += ' </tr>';
str += ' <tr>';
str += ' <td>密 码:</td>';
str += ' <td><input name="loginEntity.pass" id="pass" type="password"></input></td>';
str += ' </tr> ';
str += '</table>';
str += '</form>';
$("#dd").html(str);//把表单放到id="dd"元素,即把表单放到对话框中
};
$(function() {
//利用easyui的datagrid组件以表格方式显示数据表login的内容
$('#dg').datagrid(
{
url : 'select', //这是处理数据的后台程序
columns : [ [ //columns是定义datagrid张爱玲折表格头
{
field : 'id',
title : '编号',
width : 100
}, //表格头部的列标题
{
field : 'name',
title : '用户名',
width : 100
},
{
field : 'pass',
title : '密码',
width : 100
}
] ],
toolbar : [
{//显示工具栏
text : '添加',
iconCls : 'icon-add',
handler : function() {
insert();
}
},
'-',
{
text : '更新',
iconCls : 'icon-edit',
handler : function() {
var row = $('#dg').datagrid("getSelections");//获取用户选择的数据行
if (row) {
if (row.length > 1) {
//选择的数据行大于1,提示用户,一次只能选择一行数据进行更新操作
$.messager.alert("提示","一次只能更新一行数据,不能更新多行数据");
return false;
} else if (row.length == 1) {
update(row);//如选择选择了一行数据,则调用update()方法,弹出更新对话框
} else {
//如果没有选择数据行则提示用户只有选择数据行后才能进行更新操作
$.messager.alert("提示","没有选择要更新的数据行,不能进行更新操作");
return false;
}
}
}
},
'-',
{
text : '删除',
iconCls : 'icon-remove',
handler : function() {
var row = $('#dg').datagrid("getSelections");//获取用户选择的数据行
if (row) {
if (row.length >= 1) {//判断用户是否选择了要删除的数据行
var strid = "";//用于保存用户选择数据行的
//下面是遍历用户所选择的数据行
$(row).each(function(index,item) {
if (strid != "") {
strid += ",";
}
strid += item["id"];//把用户选择的数据行的id保
});
$.messager.confirm(
'确认',
'您确认想要删除记录吗?',
function(r) {
if (r) {
$.ajax({//采用异步通讯方式进请求
type : "post",//采用post方式向后台程序请求
url : "del",//请求的后台处理程序
data : {//在向后台程序请求的同时,给后台程序传递参数,邓
id : strid
},
success : function(data) {//若请示成功时,则返回data
$('#dg').datagrid("reload");//删除成功后要对datarid的表格中的数据进行更新操作
}
});
}
});
} else {
$.messager.alert("提示","你没有选择数据行,所以不能进行删除操作");
return false;
}
}
}
} ]
,
pagination : true,//显示分页工具
pageNumber : 1,//表示显示第几页,第一页
pageSize : 10,//表示每页显示的记录个数
pageList : [ 10, 20, 30, 40, 50 ],//第一页显示记录个数列表
});
})
</script>
</head>
<body>
<div id="dg"></div>
</body>
</html>
10、运行listllogin.html进行测试。到此利用struts2对数据表进行增删改查结束了
其实对Action的访问方式主要有3种
1、基本的访问方式。访问方式如下。
(1)在客户端采用Action的名字直接访问,如我们上面的listlogin.html中在采用AJAX方式进行异步访问是主要通过url指定Action.
$.ajax({//采用异步通讯方式进请求
type : "post",//采用post方式向后台程序请求
url : "del",//请求的后台处理程序,即LoginAction中的del()方法进行thgj
data : {//在向后台程序请求的同时,给后台程序传递参数,邓
id : strid
},
success : function(data) {//若请示成功时,则返回data
$('#dg').datagrid("reload");//删除成功后要对datarid的表格中的数据进行更新操作
}
});
(2) struts.xml的配置如下。
<?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.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="insert" class="action.LoginAction" method="insert">
</action>
<action name="update" class="action.LoginAction" method="update">
</action>
<action name="del" class="action.LoginAction" method="del">
</action>
<action name="select" class="action.LoginAction" method="select">
</action>
</package>
</struts>
2、采用通配符
使用通配符* 可以简化struts.xml配置
(1)页面代码:
$.ajax({//采用异步通讯方式进请求
type : "post",//采用post方式向后台程序请求
url : "LoginAction_del",//请求的后台处理程序,即LoginAction中的del()方法进行thgj
data : {//在向后台程序请求的同时,给后台程序传递参数,邓
id : strid
},
success : function(data) {//若请示成功时,则返回data
$('#dg').datagrid("reload");//删除成功后要对datarid的表格中的数据进行更新操作
}
});
(2)struts.xml配置
<?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.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="*_*" class="action.{1}Action" method="{2}">
</action>
</package>
</struts>
3、采用动态方法调用
当在<action>中不配置method属性同时又不希望执行默认的execute方法时,可以使用动态方法调用,访问的方式为"action名"+"!"+"方法名"
$.ajax({//采用异步通讯方式进请求
type : "post",//采用post方式向后台程序请求
url : "login!del",//请求的后台处理程序,即LoginAction中的del()方法进行thgj
data : {//在向后台程序请求的同时,给后台程序传递参数,邓
id : strid
},
success : function(data) {//若请示成功时,则返回data
$('#dg').datagrid("reload");//删除成功后要对datarid的表格中的数据进行更新操作
}
});
(2)struts.xml配置
<?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="true" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="login" class="action.LoginAction">
</action>
</package>
</struts>
三、package配置中默认值
1、如果没有为package指定namespace,则默认的namespace值为"/";
2、如果action中没有指定class,则默认的class为ActionSupport;
3、如果action中没有指定method,则默认的method为execute;
4、如果result中没有指定name,则默认的name为success。