Struts2学习---基本配置,action,动态方法调用,action接收参数

首先我们先来直接配置,然后再来讲原理: 
第一步:jar包的引入: 
我们可以到struts2的官网上下载: 
http://struts.apache.org/download.cgi#struts2513

然后解压将里面的app文件夹下的示例war文件解压,将里面的struts.xml复制到我们新创建的src目录下(特别说一下,struts2最新的Struts 2.5.13版本压缩包里面没有示例的blank示例文件,我是在2.3.34里面获得的)

配置文件大概是这样的:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts><constant name="struts.enable.DynamicMethodInvocation" value="false" /><constant name="struts.devMode" value="true" /><package name="default" namespace="/" extends="struts-default"><action name="hello"><result>/Hello.jsp</result></action></package>
</struts>    

 以上的配置文件是经过我的修改的,所以比较简洁,因为我们第一步实现action并没有那么复杂。

第二步,我们需要在web.xml中配置过滤器,将struts组件插入进来。 
配置文件大概是这样:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>testStruts2</display-name><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list><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>
</web-app>

然后我们在根目录下创建一个jsp文件:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><base href="<%=basePath%>"><title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--></head><body>hello<br></body>
</html>

里面不需要太多东西,我们只是做一个简单的测试。

然后我们将项目部署到tomcat中,启动。

然后用浏览器访问: 
http://localhost:8080/testStruts2/hello 
浏览器就会跳转到我们写好的Hello.jsp页面。

我们接着讲原理

首先,浏览器发出一个url,这个url首先发送到服务器,也就是我们的tomcat,发到tomcat过后,将交给web.xml,然后进入过滤器,通过过滤器将这个请求发送给StrutsPrepareAndExecuteFilter来处理,

StrutsPrepareAndExecuteFilter调用主配置文件struts.xml中的namespace看是否与namespace吻合,找到与之吻合的package,然后找对应的action的name,然后转到对应的页面。

其实上面过程还省略了一些过程: 

就是一个请求到了action的name的时候并不会直接转到我们的页面,而是会转到action对应的类,

上面的struts省略了这一步,但是struts2帮我们默认执行了这一个过程,如果我们补充这个过程的话应该这样:

<action name="hello" class="testStruts2.HelloAction">
package testStruts2;import com.opensymphony.xwork2.ActionSupport;public class HelloAction extends ActionSupport{public String  execute() {return SUCCESS;}
}

在struts2的主配置文件action中添加一个class=“”,并在项目的testStruts2中添加一个action类,这个action类可以有三种方法来写,但是都要包含execute方法。 
我们给出剩下的两种action类书写方式:

package testStruts2;import com.opensymphony.xwork2.ActionSupport;public class HelloAction{public String  execute() {return "success";}
}
package testStruts2;import com.opensymphony.xwork2.ActionSupport;public class HelloAction implements Action{public String  execute() {return SUCCESS;}
}

以上的两种方法,一个是不继承和实现任何方法,但是包含一个execute方法,返回一个success字符串,另一个实现Action方法,返回SUCCESS。
Action里面已经封装了一些变量,所以实现这个接口的类可以直接返回SUCCESS,同时我们还要知道ActionSupport也实现了Action,并且里面还封装了大量的方法,这个以后我们将慢慢用到。
以上三种action书写方式,建议使用第一种,因为我们以后将要经常使用到ActionSupport里面封装的方法。

经过上面这个的Action返回一个success,然后StrutsPrepareAndExecuteFilter,将action里面的result里的页面返回给浏览器。

 

如果留意的同学,还会发现我们从官网下载下来的blank范例里面action里面还有些其他的属性,对就是method。

动态方法调用:

定义一个action并不一定实现Action接口,同时也可以不执行execute方法,我们只要将action里面的method属性改为要执行的方法就行,就像这样:

<action name="hello" class="testStruts2.HelloAction" method="ADD">

同时我们action里面的方法也要改为ADD,但是返回值类型一定要为String

package testStruts2;
public class HelloAction {public String ADD() {return "success";}
}

这样对于不同的请求,我们可以根据需要在同一个Action类中用不同的方法处理。 
这样可以减少创建Action类,并且安全,但是也会造成一个Action类太过庞杂。 
动态方法调用有三种方式,上面的算式一种。

 

继续我们来说第二种: 
用“!”叹号方式(不推荐使用) 
这种方法怎么使用呢?

<action name="helloadd" class="testStruts2.HelloAction" ><result>/Hello.jsp</result>
</action>

就是这样,理论上我们再Action类中含有execute方法不会产生什么影响,但是如果我们将Action类中的方法改为String Add()呢?
就会报错,所以就用到可!了,我们的url地址应该为:
http://localhost:8080/testStruts2/hello/helloadd!ADD
这样就会找到ADD方法了。
但是还要注意一点的是我们要将动态方法调用打开:

<constant name="struts.enable.DynamicMethodInvocation" value="true" />

这里默认是关闭的,我们将它改为true就行了。

第三种就是通配符配置了: 

首先我们需要将上面的DMI改为false(不改也可以运行,但是建议改)。

<action name="hello_*" class="testStruts2.HelloAction" method="{1}"><result>/Hello_{1}.jsp</result></action>

然后就是这样:用*代替未知的url
这里的{1}表示第一个 * 代表的内容 使用通配符可能有好几个 * ,我们可以根据*的顺序用{2}{3}…依次表示
http://localhost:8080/testStruts2/hello/hello_ADD.action用这个url来访问我们的ADD方法,

当我们需要其他DELETE(删除的时候) 
只需要输入http://localhost:8080/testStruts2/hello/hello_DELETE.action 
并在Action类里面添加DELETE方法和添加响应的Hello_DELETE.jsp页面。

使用通配符简化了我们好多的配置,原来需要在配置文件中配置好多个action,现在只需要用通配符就可以解决这些,只需要添加响应的Action类(方法)和jsp页面就行了。

 

<action name="*_*" class="testStruts2.{1}HelloAction" ><result> /{1}_{2}_hello.jsp</result>
</action>

 

上面的是两个通配符的范例,如果请求是这样:
http://localhost:8080/testStruts2/hello/hello_DELETE.action
它就能够根据{1}找到对应的Action类,根据{2}找到对应的方法。
是不是很简便?(这样的做法叫做约定优于配置

 

action接收参数:

   我们怎么样用struts接受客户端发过来的参数呢?下面列举四种方法: 

  ①属性参数输入

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts><constant name="struts.enable.DynamicMethodInvocation" value="false" /><constant name="struts.devMode" value="true" /><package name="default" namespace="/" extends="struts-default"><action name="user" class="testStruts1.userAction"><result>/user.jsp</result></action></package>
</struts>    

上面是配置文件,没什么好说的,和之前大同小异。 

我们接下来看看Action类:

package testStruts1;import com.opensymphony.xwork2.ActionSupport;public class userAction extends ActionSupport{String username;public userAction() {}public userAction(String username) {super();this.username = username;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String execute() {System.out.println(username);return SUCCESS;} 
}

首先这个类要符合javabean的命名规则,我们再Action类中添加了一个username属性,并含有它的set get方法,并在execute里面将接收到的username输出到控制台来证实实验。

当我们将项目部署到服务器上后,在浏览器中输入一下URl: 
http://localhost:8080/testStruts1/user.action?username=aa 
控制台便会将接受到的username参数输出。

我们可以看到上面使用Action类的属性来接收参数的,struts通过我们给出的set get 方法帮助我们完成赋值。

②同样我们也可以定义一个实体类来来接收这些信息(官方叫DomainModel): 

例如 
这个是我们提交的信息:

<form action="login" method="post">用户名:<input type="text" name="user.username"><br>密码<input type="password" name="user.password"><br><input type="submit" value="登录"></form>
/*input里面一定要使用user.username和user.password和实体类对应,或者使用struts2提供的标签,否则会出错(不要问我是怎么知道的 哭脸.jpg)*/

这个是实体类:

package entity;public class User {String username;String password;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
package testStruts1;import com.opensymphony.xwork2.ActionSupport;import entity.User;public class userAction extends ActionSupport{User user;//不需要new对象,struts2帮我们完成了public User getUser() {return user;}public void setUser(User user) {this.user = user;}public String execute() {if(user.getUsername().equals("username")&&user.getPassword().equals("password")) {return SUCCESS;}return ERROR;} 
}
/*struts.xml*/<action name="login" class="testStruts1.userAction"><result name="success">/user.jsp</result><result name="error">/error.jsp</result></action>

 ③还有一种使用DTO(date transfer object)数据传输对象来进行传输。 
这种方式主要是应对提交的参数和我们的实体对象不匹配的状况:

比如用户注册的时候会输入第二次密码来进行确认,我们将接受两个密码,所以在这个类中我们接收三个参数:username ,password,confirmPassword。 

然后在Action类的execute方法中使用DTO对象来对User对象进行赋值:

User user = new User();//这里就需要我们实例化了,因为struts实例化的机会被下面的玩意抢了。
  DTO dto ;public String execute(){user.setUserName(dto.getUserName());  user.setUserPassword(dto.getUserPassword());  //后面再利用user实例来进行一系列的操作。
}

当然现在我们有更为先进的技术就是我们完全可以用js来在客户端确认是否相同,然后将数据传输过来。

 

④还有一种叫方法:ModelDriven

public class userAction extends ActionSupport implements ModelDriven<User>{User user = new User();//这里需要自己new对象
    @Overridepublic User getModel() {return user;}public void setUser(User user) {this.user = user;}public User getModel() {return user;}public String execute() {if(user.getUsername().equals("username")&&user.getPassword().equals("password")) {return SUCCESS;}return ERROR;} 
}

就是这样,实现ModelDriven接口,并实现getModel方法,直接获得这个模型对象user。怎么实现这样的原理的呢?
是通过一个缺省的拦截器ModelDrivenInterceptor这里面判断一个Action对象是否实现ModelDriven,如果实现就返回这个User对象,并将User对象push到valueStack中(valueStack后边介绍)。

 

 

版权声明:本文为博主原创文章,如需转载请表明出处。 https://blog.csdn.net/qq_39266910/article/details/78485739

 

转载于:https://www.cnblogs.com/chengshun/p/9772835.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396531.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实现对数组找最大最小数

实现对数组找最大最小数 在用js的过程中我们往往会需要找到一个数组里最大或最小的数&#xff0c; 但是我们不能直接用Math.max(Arr)或Math.min(Arr)&#xff0c;因为max&#xff08;&#xff09;里面不能填数组&#xff0c;只能填连续的数。 那我们该怎么办呢&#xff1f; 一定…

开源免费 低代码平台开源_行动透明:免费代码营现已开源

开源免费 低代码平台开源by freeCodeCamp通过freeCodeCamp 行动透明&#xff1a;免费代码营现已开源 (Transparency in Action: Free Code Camp is Now Open Source) We’re thrilled to announce that Free Code Camp is now fully open-source. Now you can fork our code b…

vc mysql init 崩溃_故障分析 | 崩溃恢复巨慢原因分析

作者&#xff1a;xuty本文来源&#xff1a;原创投稿*爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。一、现象有个 MySQL 5.7 开发库异常挂掉后&#xff0c;奔溃恢复一直处于如下位置&#xff0c;且持续了 2 小时左右才起来…

surfaceview结束后怎么处理_污泥压滤机处理后的污泥怎么处置

在污泥处理处置中&#xff0c;污泥压滤机处理污泥只是对污泥进行脱水&#xff0c;并没有实现污泥资源化处置。再进行污泥“减量化、无害化、资源化”处理时&#xff0c;许多企业用污泥压滤机对污泥脱水处理后就不知道怎么继续处置了&#xff0c;从而使污泥饼无处可去&#xff0…

js数组详解

1&#xff0c;什么是数组数组是值得有序集合&#xff0c;每个值叫做一个元素&#xff0c;而每个元素在数组中有一个位置&#xff0c;以数字表示&#xff0c;称为索引。js的数组是无类型的&#xff0c;数组元素可以是任意类型&#xff0c;同一个数组中的不同元素可能是对象或数组…

[转载]linux内存映射mmap原理分析

转自&#xff1a;http://blog.csdn.net/yusiguyuan/article/details/23388771 内存映射&#xff0c;简而言之就是将用户空间的一段内存区域映射到内核空间&#xff0c;映射成功后&#xff0c;用户对这段内存区域的修改可以直接反映到内核空间&#xff0c;同样&#xff0c;内核空…

判断一个指针有没有free_Free Code Camp的每个人现在都有一个档案袋

判断一个指针有没有freeby freeCodeCamp通过freeCodeCamp Free Code Camp的每个人现在都有一个档案袋 (Everyone at Free Code Camp now has a Portfolio) Note: we originally published this on our now-defunct blog in January of 2015.注意&#xff1a;我们最初是在2015年…

冒泡、快速排序小结

1.冒泡排序 (1) 比较领近的两个数 (2) 如果左边的比右边的数字大&#xff0c;则交换位置 (3) 向右移动一位&#xff0c;继续比较相邻的两个数 排序示例&#xff1a; 一轮排序结束后&#xff0c;最大值的位置已经移动最右端&#xff0c;再次如此循环&#xff0c;最终经过n-1次则…

python中until函数_等待应用程序窗口:python中的pywinauto.timings.WaitUntilPasses

我试图在pywinauto中使用waituntilpasses来给应用程序时间打开一个新窗口.我已使用SWAPY识别窗口详细信息.为了进行测试,我手动打开了子窗口,因此WaitUntilPasses应该立即看到该窗口,但是没有看到.语法显示为OK,因为我可以找到并打印find_windows的输出,如下所示&#xff1a;xx…

synchronized 异常_由浅入深,Java 并发编程中的 Synchronized

synchronized 作用synchronized 关键字是 Java 并发编程中线程同步的常用手段之一。1.1 作用&#xff1a;确保线程互斥的访问同步代&#xff0c;锁自动释放&#xff0c;多个线程操作同个代码块或函数必须排队获得锁&#xff0c;保证共享变量的修改能够及时可见&#xff0c;获得…

mysql正则通配符全解_mysql正则表达式与通配符

扩展正则表达式的一些字符是&#xff1a; “.”匹配任何单个的字符。 一个字符类“[...]”匹配在方括号内的任何字符。例如&#xff0c;“[abc]”匹配“a”、“b”或“c”。为了命名字符的一个范围&#xff0c;使用一个“-”。“[a-z]”匹配任何小写字母&#xff0c;而“[0-9…

dos常用文件操作命令

1、DIR 含义&#xff1a; 显示指定目录下的文件和子目录列表 类型&#xff1a; 内部命令 格式&#xff1a; DIR[drive:][path][filename][/p][/w][/A[[:]attributes]][/O[[:]sortorder]][/S][/B][/L] 举例&#xff1a; DIR DIR D:\px2 DIR D:\px2\*.txt DIR /A:D /O:D 2、COPY…

使您的Java代码闻起来很新鲜

by Marco Massenzio由Marco Massenzio 使您的Java代码闻起来很新鲜 (Make your Java code smell nice and fresh) A few years ago I joined a startup working on a cloud enterprise service that was originally built by an offshore team.几年前&#xff0c;我加入了一家…

MySQL时间戳与日期格式的相互转换

MySQL时间戳与日期格式的相互转换&#xff0c;PHP时间戳与日期格式的相互转换 MySQL: 获取当前时间SELECT NOW(); // 2018/10/11 14:22:51 时间日期格式转换成时间戳格式&#xff0c;UNIX_TIMESTAMP()SELECT UNIX_TIMESTAMP(NOW()); // 1539238930 时间戳格式转换成时间日期格式…

Linux内存分配机制之伙伴系统和SLAB

转载请注明原文地址&#xff1a;http://www.cnblogs.com/ygj0930/p/6539590.html 内核内存管理的一项重要工作就是如何在频繁申请释放内存的情况下&#xff0c;避免碎片的产生。这就要求内核采取灵活而恰当的内存分配策略。通常&#xff0c;内存分配一般有两种情况&#xff1a…

this.$modal.confirm 自定义按钮关闭_自定义函数,让你玩转Excel得心应手

让“自动更正”输入统一的文本&#xff0c;你是不是经常为输入某些固定的文本,如《电脑报》而烦恼呢?那就往下看吧。1.执行“工具→自动更正”命令,打开“自动更正”对话框。2.在“替换”下面的方框中输入“pcw”(也可以是其他字符,“pcw”用小写),在“替换为”下面的方框中输…

php mysql 排名算法_MySQL PHP:优化排名查询和计数子查询

这是原始数据,并希望根据得分(count(tbl_1.id))对它们进行排名.[tbl_1]id | name1 | peter2 | jane1 | peter2 | jane3 | harry3 | harry3 | harry3 | harry4 | ron因此,制作临时表(tbl_2)来计算每个id的分数.SELECT id, name, COUNT( id ) AS scoreFROM tbl_1GROUP BY idORDER…

CCF-CSP 最大的矩形

问题描述在横轴上放了n个相邻的矩形&#xff0c;每个矩形的宽度是1&#xff0c;而第i&#xff08;1 ≤ i ≤ n&#xff09;个矩形的高度是hi。这n个矩形构成了一个直方图。例如&#xff0c;下图中六个矩形的高度就分别是3, 1, 6, 5, 2, 3。请找出能放在给定直方图里面积最大的矩…

Stack Overflow 2016年对50,000名开发人员进行的调查得出的见解

Today, Stack Overflow released the results of their 2016 survey of more than 50,000 developers.今天&#xff0c;Stack Overflow发布了他们2016年对50,000多名开发人员进行的调查的结果。 I’ve combed through this big document to bring you the most surprising ins…

web管理

1.站点根目录下查找是否被放置webshell***根据语句判断是不是PHP***脚本# find /storage/www/ -name "*.php" | xargs grep-in --color "eval("# grep -i --include*.php -r system\s*\( /storage/www/2.统计访问日志中来自同ip出现的次数分析盗链、***、机…