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。