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

第一步: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. 【转】Java中用单例模式有什么好处

    Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收( ...

  2. javascript面向对象编程(OOP)——汇总

    目录 一.JS的解析与执行过程 预处理阶段 执行阶段 二.作用域 块作用域 函数作用域 动态作用域 词法作用域 三.闭包 什么是闭包 闭包的好处 四.类与对象 对象 类 原型(prototype) t ...

  3. ViewPager无限轮播与自定义切换动画

    一直在寻求一个能用得长久的ViewPager,寻寻觅觅终于发现,ViewPager有这一个就够了. 注:并非完全原创 先看一下效果: 淡入淡出: 旋转: 无限轮播的ViewPager 主要设计思路(以 ...

  4. python并发编程之多线程二

    一,开启线程的两种方式 方法一: from threading import Thread import random,time def eat(name): print('%s is eating. ...

  5. 第十一章 泛型算法 C++ PRIMER

    vector<int>::const_iterator result = find(vector.begin(). vector.end(),search_value); 如果查找失败,分 ...

  6. ASE加密

    密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.

  7. Awk,Cat,Head分析Nginx日志常用命令

    Nginx 日志分析   1.根据访问IP统计UV   awk '{print $1}'  access.log|sort | uniq -c |wc -l   2.统计访问URL统计PV   awk ...

  8. 了解web及网络基础

    了解web及网络基础 以下内容简单的说明了一下TCP/IP协议族中HTTP协议.DNS服务.IP协议的一些概念和关系.笔者只是对知识点进行了总结,仅供参考: ) 转载请注明出处:了解web及网络基础 ...

  9. suds库使用说明官方文档

    OVERVIEW The Suds web services client is a lightweight soap-based client for python the is licensed ...

  10. Expected MultipartHttpServletRequest: is a MultipartResolver configured解决方案

    异常信息: java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolv ...