首先我们先来直接配置,然后再来讲原理:

第一步: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对象
@Override
public 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后边介绍)。

未完待续。。

Struts2学习---基本配置,action,动态方法调用,action接收参数的更多相关文章

  1. struts2视频学习笔记 11-12(动态方法调用,接收请求参数)

    课时11 动态方法调用 如果Action中存在多个方法时,可以使用!+方法名调用指定方法.(不推荐使用) public String execute(){ setMsg("execute&q ...

  2. Struts2学习第七课 动态方法调用

    动态方法调用:通过url动态调用Action中的方法. action声明: <package name="struts-app2" namespace="/&quo ...

  3. Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解

    1.修改struts2常量配置(3种) 第一种 在str/struts.xml中添加constant标签 <struts> <!-- 如果使用使用动态方法调用和include冲突 - ...

  4. JavaWeb_(Struts2框架)struts.xml核心配置、动态方法调用、结果集的处理

    此系列博文基于同一个项目已上传至github 传送门 JavaWeb_(Struts2框架)Struts创建Action的三种方式 传送门 JavaWeb_(Struts2框架)struts.xml核 ...

  5. struts2.3.15.3中动态方法调用默认是关闭的

    初学ssh,用的struts2.3.15.3,使用了如下表单: <form action="/spring3/index/login.action" method=" ...

  6. Struts2学习第二天——动态方法调用

    method属性 在前面的例子里,Action默认使用execute()方法来处理请求.但是,如果有多个不同的请求需要同一个Action进行不同处理,怎么办?在Struts.xml文件中,需要指定Ac ...

  7. struts2的通配符与动态方法调用

    1.Action标签中的method属性 我们知道action默认的执行的方法是execute方法,但是一个action只执行一个方法我们觉得有点浪费,我们希望在一个action中实现同一模块的不同功 ...

  8. 01_5_Struts_ActionMethod_DMI_动态方法调用

    01_5_Struts_ActionMethod_DMI_动态方法调用 1. ActionMethod_DMI_动态方法调用 Action执行的时候并不一定要执行execute()方法 可以在配置文件 ...

  9. Struts2学习笔记 - Action篇<动态方法调用>

    有三种方法可以使一个Action处理多个请求 动态方法调用DMI 定义逻辑Acton 在配置文件中使用通配符 这里就说一下Dynamic Method nvocation ,动态方法调用,什么是动态方 ...

随机推荐

  1. Celery 源码解析六:Events 的实现

    在 Celery 中,除了远程控制之外,还有一个元素可以让我们对分布式中的任务的状态有所掌控,而且从实际意义上来说,这个元素对 Celery 更为重要,这就是在本文中将要说到的 Event. 在 Ce ...

  2. Eclipse中代码整体左移,右移快捷键

    1.向右:将要移动的代码选中,然后按TAB键2.向左:将要移动的代码选中,然后按SHIFT+TAB键

  3. 【Java】单词倒序输出

    如何将一段单词倒序输出?把"Hello Java Hello China"变成"China Hello Java Hello"? 看起来好像很简单,只需要把字符 ...

  4. Python基础-数据类型和变量

    数据类型 python中包含6种标准数据类型:1.Number 数值类型2.String 字符串类型3.List 列表类型4.Tuple 元祖类型5.Dict 字典类型6.Set 集合类型 注意:除了 ...

  5. TFboy养成记 tf.cast,tf.argmax,tf.reduce_sum

    referrence: 莫烦视频 先介绍几个函数 1.tf.cast() 英文解释: 也就是说cast的直译,类似于映射,映射到一个你制定的类型. 2.tf.argmax 原型: 含义:返回最大值所在 ...

  6. Python函数中如何定义参数

    一.位置参数:根据函数定义时的参数位置传递参数#形参和实参的个数必须一致def fun1(): print("运行结果") print("this is fun1(),n ...

  7. ##5.1 Nova控制节点-- openstack pike

    ##5.1 Nova控制节点 openstack pike 安装 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ##5.1 Nova控制节点 # co ...

  8. Google 视频编码格式 VP9 究竟厉害在哪里

    近期 Google 已经开始研究 VP10 了,VP10 是一个由 WebM 和 Motroska 包含的开放.免费视频编解码器.Google 也已利用 VP10 来处理 YouTube 4K 视频. ...

  9. java学习笔记之字符流文件复制

    字符文件复制 FileReader fr =new FileReader("b.txt");//绑定源文件 FileWriter fw= new FileWriter(" ...

  10. Cesium几个案例介绍

    前言 本文为大家介绍几个Cesium的Demo,通过这几个Demo能够对如何使用Cesium有进一步的了解,并能充分理解Cesium的强大之处和新功能.其他的无需多言,如果还不太了解什么是Cesium ...