一.Struts2是什么
一.Struts2简介
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。
在用户请求和模块化处理、页面的展现方面。
Struts2原理图:
应用流程注解:
1.当Web容器收到请求(HttpServletReques
t)它将请求传递给一个标准的的过滤链包括(ActionContextCleanUp)过滤器。
2.经过Other filters(SiteMesh ,etc),需要调用FilterDispatcher核心控制器,然后它调用ActionMapper确定请求哪个Action,ActionMapper返回一个收集Action详细信息的ActionMaping对象。
3.FilterDispatcher将控制权委派给ActionProxy,ActionProxy调用配置管理器(ConfigurationManager) 从配置文件中读取配置信息(struts.xml),然后创建ActionInvocation对象。
4.ActionInvocation在调用Action之前会依次的调用所用配置拦截器(Interceptor N)一旦执行结果返回结果字符串ActionInvocation负责查找结果字符串对应的(Result)然后执行这个Result Result会调用一些模版(JSP)来呈现页面。
5.拦截器(Interceptor N)会再被执行(顺序和Action执行之前相反)最后响应(HttpServletResponse)被返回在web.xml中配置的那些过滤器和核心控制器(FilterDispatcher)。
Struts2包的下载:
https://struts.apache.org/
Apache Struts is a free, open-source, MVC framework for creating elegant, modern Java web applications. It favors convention over configuration, is extensible using a plugin architecture, and ships with plugins to support REST, AJAX and JSON.
包struts-2.5.17:
apps:示例项
docs:文档
lib:开发包,有插件包和核心包
src:源码,可以添加到项目里面去
.txt:协议、规范
核心包有8个:
commons-fileupload-1.3.1.jar
commons-io-2.2.jar
commons-lang3-3.1.jar
freemarker-2.3.19.jar
javassist-3.11.0.GA.jar
ognl-3.0.6.jar
struts2-core-2.3.16.3.jar
xwork-core-2.3.16.2.jar
二.Struts2的HelloWorld!程序
New Dynamic Web Project(HeadFirstStruts2Chap01)
->Dynamic web module version 2.5(3.0没有web.xml)
->将核心包添加到lib
->web.xml中写过滤器代码
要交给struts2处理filter、查看org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter添加了源码在src包中
<?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_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>HeadFirstStruts2Chap01</display-name>
<welcome-file-list>
<welcome-file>index.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>
->struts.xml中
用户请求一个地址,通过struts2返回一个页面
写一个包package 起个名helloworld 继承一个默认包
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="helloWorld" extends="struts-default">
</package>
</struts>
->New Class(com.tech.action.HelloWorldAction)
struts2的action处理类 实现Action接口 重写execute方法system.out.println(“执行了Action的默认方法”);return SUCCESS;
package com.java1234.action;
import com.opensymphony.xwork2.Action;
public class HelloWorldAction implements Action{
@Override
public String execute() throws Exception {
System.out.println("执行了Action的默认方法");
return SUCCESS;
}
}
->struts.xml 中
<action name="hello" class="com.java1234.action.HelloWorldAction">
<result name="success">helloWorld.jsp</result>
</action>
->New JSP File(helloWorld.jsp)
Struts2你好!
->启动程序http://localhost:8080/HeadFirstStruts2Chap01/hello
执行结果:
请求hello后,控制台打印出"执行了Action的默认方法",页面跳转到helloWorld.jsp,但浏览器地址没有变。
执行过程:
首先定义了一个filter,url-pattern为/*相当于拦截了所有的请求,把所有的请求交给了分发器(Struts2的核心控制器)org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,它的主要功能是将交给它的请求进行解析,判断是要给交哪个action处理,去相应的action类里执行代码,因为此类最后是返回了SUCCESS,匹配action里面的result里的"success",转发到.jsp页面。
二.Struts2核心知识
一.Struts2 get/set 自动获取/设置数据
这是拦截器很常用的一个功能。
新建项目HeadFirstStruts2Chap02
->HelloWorldAction.java中
private String name;以及相应的get set方法
package com.java1234.action;
import com.opensymphony.xwork2.Action;
public class HelloWorldAction implements Action{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
System.out.println("执行了Action的默认方法");
return SUCCESS;
}
}
->页面helloWorld.jsp
n
a
m
e
你
好
!
−
>
s
t
r
u
t
s
.
x
m
l
不
变
−
>
启
动
程
序
:
h
t
t
p
:
/
/
l
o
c
a
l
h
o
s
t
:
8080
/
H
e
a
d
F
i
r
s
t
S
t
r
u
t
s
2
C
h
a
p
01
/
h
e
l
l
o
?
n
a
m
e
=
S
t
r
u
t
s
2
执
行
结
果
:
控
制
台
上
打
印
出
"
执
行
了
A
c
t
i
o
n
的
默
认
方
法
"
,
页
面
跳
转
到
页
面
跳
转
到
h
e
l
l
o
W
o
r
l
d
.
j
s
p
,
显
示
出
“
S
t
r
u
t
s
2
你
好
!
”
浏
览
器
地
址
没
有
变
。
执
行
过
程
:
在
发
出
请
求
时
就
传
递
给
属
性
n
a
m
e
一
个
值
?
n
a
m
e
=
S
t
r
u
t
s
2
,
首
先
拦
截
器
调
用
s
e
t
方
法
,
设
置
给
了
当
前
的
n
a
m
e
属
性
。
页
面
跳
转
到
h
e
l
l
o
W
o
r
l
d
.
j
s
p
,
用
{name}你好! ->struts.xml不变 ->启动程序:http://localhost:8080/HeadFirstStruts2Chap01/hello?name=Struts2 执行结果: 控制台上打印出"执行了Action的默认方法",页面跳转到页面跳转到helloWorld.jsp,显示出“Struts2你好!”浏览器地址没有变。 执行过程: 在发出请求时就传递给属性name一个值?name=Struts2,首先拦截器调用set方法,设置给了当前的name属性。页面跳转到helloWorld.jsp,用
name你好!−>struts.xml不变−>启动程序:http://localhost:8080/HeadFirstStruts2Chap01/hello?name=Struts2执行结果:控制台上打印出"执行了Action的默认方法",页面跳转到页面跳转到helloWorld.jsp,显示出“Struts2你好!”浏览器地址没有变。执行过程:在发出请求时就传递给属性name一个值?name=Struts2,首先拦截器调用set方法,设置给了当前的name属性。页面跳转到helloWorld.jsp,用{name}取得这个属性,然后用get方法取到这个属性,显示在页面上。
以上是使用URL的方式进行提交,以下我们使用form方式。
新建一个index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="hello" method="post">
name:<input type="text" name="name"/>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
执行过程:起始页面是index.jsp,我们在文本框中输入"Struts2",点击提交后,会自动调用set方法将这个值传递给属性name。控制台打印出"执行了HelloWorldAction的默认方法",跳转到helloWorld.jsp页面,要读取属性name的值,就使用get方法,显示“Struts2你好!”
二.ActionSupport类引入
->新建一个ActionHelloWorldAction2,继承ActionSupport
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorldAction2 extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
System.out.println("执行了HelloWorldAction2 Action的默认方法");
return SUCCESS;
}
}
->在struts.xml中添加
<action name="hello" class="com.java1234.action.HelloWorldAction2">
<result name="success">helloWorld.jsp</result>
</action>
->helloWorld.jsp页面不变
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02
执行结果:与上面的一样。
ActionSupport功能更强大,我们以后都用它。
三.Action设置数据
一.属性驱动(FieldDriven)
A基本数据类型属性
新建User类
package com.java1234.model;
public class User {
private String userName;
private 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;
}
}
->新建UserAction类,用来判断登陆验证
package com.java1234.action;
import com.java1234.model.User;
import com.java1234.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private UserService userService=new UserService();
private String userName;
private 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;
}
@Override
public String execute() throws Exception {
System.out.println("执行了UserAction的默认方法");
User user=new User();
user.setUserName(userName);
user.setPassword(password);
if(userService.login(user)){
return SUCCESS;
}else{
return ERROR;
}
}
}
->新建login.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="user" method="post">
用户名:<input type="text" name="userName"/>
密码:<input type="text" name="password"/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
->Service是专门用来处理业务的
新建UserService.java
package com.java1234.service;
import com.java1234.model.User;
public class UserService {
public boolean login(User user){
if("java1234".equals(user.getUserName())&&"123456".equals(user.getPassword())){
return true;
}else{
return false;
}
}
}
->新建success.jsp
登陆成功
->新建error.jsp
登录失败
->在struts.xml中
<action name="user" class="com.java1234.action.UserAction">
<result name="success">success.jsp</result>
<result name="error">error.jsp</result>
</action>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02/login.jsp
执行结果:
进入login.jsp,在名字和密码的文本框中填入内容,点提交。控制台上打印出"执行了UserAction的默认方法",用service去判断是否正确,跳转到相应的正确错误页面。
执行过程:
注意:.jsp页面中的属性与action.java中的属性是一一对应的。
BJavaBean类型属性
如果有50个属性,那么action中也需要写50个,很麻烦,所以直接用JavaBean。
新建UserAction2
package com.java1234.action;
import com.java1234.model.User;
import com.java1234.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction2 extends ActionSupport{
private static final long serialVersionUID = 1L;
private UserService userService=new UserService();
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute() throws Exception {
System.out.println("执行了UserAction的默认方法");
if(userService.login(user)){
return SUCCESS;
}else{
return ERROR;
}
}
}
->新建login2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="user2" method="post">
用户名:<input type="text" name="user.userName"/>
密码:<input type="text" name="user.password"/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
->struts.xml中添加
<action name="user2" class="com.java1234.action.UserAction2">
<result name="success">success.jsp</result>
<result name="error">error.jsp</result>
</action>
->Model层、Service层、success.jsp、error.jsp的代码不用变
->执行程序http://localhost:8080/HeadFirstStruts2Chap02/login2.jsp
二.模型驱动(ModelDriven)
只能接收一种类型,开发时,一个action中有好几个javabean,所以一般不用这个方法。
实现这个方法有一个泛型。
新建UserAction3
package com.java1234.action;
import com.java1234.model.User;
import com.java1234.service.UserService;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class UserAction3 extends ActionSupport implements ModelDriven<User>{
private static final long serialVersionUID = 1L;
private UserService userService=new UserService();
private User user=new User();
@Override
public String execute() throws Exception {
System.out.println("执行了UserAction3的默认方法");
if(userService.login(user)){
return SUCCESS;
}else{
return ERROR;
}
}
@Override
public User getModel() {
// TODO Auto-generated method stub
return user;
}
}
->新建login3.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="user3" method="post">
用户名:<input type="text" name="userName"/>
密码:<input type="text" name="password"/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
->struts.xml中添加
<action name="user3" class="com.java1234.action.UserAction3">
<result name="success">success.jsp</result>
<result name="error">error.jsp</result>
</action>
->Model层、Service层、success.jsp、error.jsp的代码不用变
->执行程序:http://localhost:8080/HeadFirstStruts2Chap02/login3.jsp
四.Struts2处理传入多个值
一.处理数目不定的字符串
New Project(HeadFirstStruts2Chap02_02)
->新建hobby.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="hobby" method="post">
爱好:
<input type="checkbox" name="hobby" value="唱歌"/>唱歌
<input type="checkbox" name="hobby" value="跳舞"/>跳舞
<input type="checkbox" name="hobby" value="睡觉"/>睡觉
<input type="checkbox" name="hobby" value="玩CF"/>玩CF
<input type="submit" value="提交"/>
</form>
</body>
</html>
->新建HobbyAction
package com.java1234.action;
import com.opensymphony.xwork2.Action;
public class HobbyAction implements Action{
private String[] hobby;
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
@Override
public String execute() throws Exception {
System.out.println("执行了Action的默认方法");
if(hobby!=null){
for(String h:hobby){
System.out.println(h);
}
}
return SUCCESS;
}
}
->struts.xml
<action name="hobby" class="com.java1234.action.HobbyAction">
<result name="success">success.jsp</result>
</action>
->新建success.jsp
->不需要用model层
->执行程序:http://localhost:8080/HeadFirstStruts2Chap02_02/hobby.jsp
执行结果:在复选框中选多个选项后,提交。在控制台上打印出"执行了Action的默认方法"和相应的选项名称。
二.处理数目不定的JavaBean对象
新建addstudents.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="student" method="post">
<table>
<tr>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
<tr>
<td><input type="text" name="students[0].name"/></td>
<td><input type="text" name="students[0].sex"/></td>
<td><input type="text" name="students[0].age"/></td>
</tr>
<tr>
<td><input type="text" name="students[1].name"/></td>
<td><input type="text" name="students[1].sex"/></td>
<td><input type="text" name="students[1].age"/></td>
</tr>
<tr>
<td colspan="3">
<input type="submit" value="提交"/>
</td>
</tr>
</table>
</form>
</body>
</html>
->新建model层,Student.java
package com.java1234.model;
public class Student {
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
->新建StudentAction.java
package com.java1234.action;
import java.util.List;
import com.java1234.model.Student;
import com.opensymphony.xwork2.Action;
public class StudentAction implements Action{
private List<Student> students;
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String execute() throws Exception {
System.out.println("执行了Action的默认方法");
for(Student s:students){
System.out.println(s);
}
return SUCCESS;
}
}
->struts.xml
<action name="student" class="com.java1234.action.StudentAction">
<result name="success">success.jsp</result>
</action>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_02/addstudents.jsp
执行结果:
批量添加,添上两个人的姓名、性别、年龄,点击提交。控制台输出"执行了Action的默认方法"和打印出两个对象。
五.struts.xml配置
一.pageckage配置
name包名
extends继承
namespace包命名空间,要在浏览器中请求中加一个这个前缀
abstract抽象包
以下讲解namespace的作用:
新建项目HeadFirstStruts2Chap02_03
->struts.xml中添加两个包
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="foreground" namespace="/fore" extends="struts-default">
<action name="studentList" class="com.java1234.action.ForeStudent">
<result name="success">${pageContext.request.contextPath}/success.jsp</result>
</action>
</package>
<action name="studentList" class="com.java1234.action.BackStudent">
<result name="success">${pageContext.request.contextPath}/success.jsp</result>
</action>
<package name="background" namespace="/back" extends="struts-default">
</package>
<package name="infoFilter" abstract="true"></package>
</struts>
->新建BackStudent
package com.java1234.action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class BackStudent extends ActionSupport{
@Override
public String execute() throws Exception {
System.out.println("执行了BackStudent Action的默认方法");
return SUCCESS;
}
}
->新建ForeStudent
package com.java1234.action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class ForeStudent extends ActionSupport{
@Override
public String execute() throws Exception {
System.out.println("执行了ForeStudent Action的默认方法");
return SUCCESS;
}
}
->新建一个success.jsp
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_03/studentList
这样是请求不到的
http://localhost:8080/HeadFirstStruts2Chap02_03/fore/studentList
${pageContext.request.contextPath}/才能支持绝对路径,要不然会报错,说找不到fore/success.jsp。
执行结果:
在控制台上输出"执行了ForeStudent Action的默认方法",跳转到了success.jsp页面。
http://localhost:8080/HeadFirstStruts2Chap02_03/back/studentList
执行结果:
在控制台上输出"执行了BackStudent Action的默认方法",跳转到了success.jsp页面。
以下讲解abstract的作用:
struts.xml
<package name="infoFilter" abstract="true"></package>
一般情况下是abstract=“false”。这个包用来让别的包继承,这个包下面不可以写action。
二.action配置
name action的名字,写上这个就可以在浏览器路径中直接请求这个action了
class处理类,具体的请求处理类
method方法
->BackStudent.java中添加一个方法
public String show()throws Exception{
System.out.println("执行了 BackStudent show方法");
return SUCCESS;
}
然后,action中默认请求的是execute方法,若我们写上method=“show”
->struts.xml
<action name="studentList" class="com.java1234.action.BackStudent" method="show">
<result name="success">${pageContext.request.contextPath}/success.jsp</result>
</action>
那么就会去默认执行show方法
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_03/back/studentList
执行结果:
控制台输出了"执行了 BackStudent show方法"
三.分模块配置方法
新建项目HeadFirstStruts2Chap02_04
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="cheliang.xml"></include>
<include file="zichan.xml"></include>
</struts>
->新建cheliang.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="cheliang" namespace="/cheliang" extends="struts-default">
<action name="cheliang" class="com.java1234.action.CheLiangAction">
<result name="success">${pageContext.request.contextPath}/success.jsp</result>
</action>
</package>
</struts>
->新建zichan.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="zichan" namespace="/zichan" extends="struts-default">
<action name="zichan" class="com.java1234.action.ZiChanAction">
<result name="success">${pageContext.request.contextPath}/success.jsp</result>
</action>
</package>
</struts>
->新建CheLiangAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class CheLiangAction extends ActionSupport{
private static final long serialVersionUID = 1L;
@Override
public String execute() throws Exception {
System.out.println("执行了CheLiangAction Action的默认方法");
return SUCCESS;
}
}
->新建ZiChanAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class ZiChanAction extends ActionSupport{
private static final long serialVersionUID = 1L;
@Override
public String execute() throws Exception {
System.out.println("执行了ZiChanAction Action的默认方法");
return SUCCESS;
}
}
->success.jsp
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_04/cheliang/cheliang
执行结果:
控制台上打印出"执行了CheLiangAction Action的默认方法",页面跳转到success.jsp。
http://localhost:8080/HeadFirstStruts2Chap02_04/zichan/zichan
控制台上打印出"执行了ZiChanAction Action的默认方法",页面跳转到success.jsp。
这是一种分模块的方法,当你的项目中模块很多时,就需要使用这种方式来写struts.xml
四. 使用通配符
新建项目HeadFirstStruts2Chap02_05
->新建GradeAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class GradeAction extends ActionSupport{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String list()throws Exception{
System.out.println("班级查找");
name="班级查找";
return SUCCESS;
}
public String add()throws Exception{
System.out.println("班级添加");
name="班级添加";
return SUCCESS;
}
public String update()throws Exception{
System.out.println("班级修改");
name="班级修改";
return SUCCESS;
}
public String delete()throws Exception{
System.out.println("班级删除");
name="班级删除";
return SUCCESS;
}
}
->新建StudentAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class StudentAction extends ActionSupport{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String list()throws Exception{
System.out.println("学生查找");
name="学生查找";
return SUCCESS;
}
public String add()throws Exception{
System.out.println("学生添加");
name="学生添加";
return SUCCESS;
}
public String update()throws Exception{
System.out.println("学生修改");
name="学生修改";
return SUCCESS;
}
public String delete()throws Exception{
System.out.println("学生删除");
name="学生删除";
return SUCCESS;
}
}
方式一使用一个通配符
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manage" namespace="/" extends="struts-default">
<action name="student_*" class="com.java1234.action.StudentAction" method="{1}">
<result name="success">success.jsp</result>
</action>
<action name="grade_*" class="com.java1234.action.GradeAction" method="{1}">
<result name="success">success.jsp</result>
</action>
</package>
</struts>
->success.jsp
OK!${name}
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>通配符</h1>
<a href="student_list" target="_blank">学生信息查询</a>
<a href="student_add" target="_blank">学生信息添加</a>
<a href="student_update" target="_blank">学生信息修改</a>
<a href="student_delete" target="_blank">学生信息删除</a>
<br/><br/>
<a href="grade_list" target="_blank">班级信息查询</a>
<a href="grade_add" target="_blank">班级信息添加</a>
<a href="grade_update" target="_blank">班级信息修改</a>
<a href="grade_delete" target="_blank">班级信息删除</a> <br/>
</body>
</html>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_05
运行结果:
进入起始页面index.jsp。点击相应的学生/班级 查找/添加/修改/删除的链接,就会跳转到success.jsp页面,显示出相应的字,OK!学生/班级 查找/添加/修改/删除。且控制台上也打印出相应的字
学生/班级 查找/添加/修改/删除。
方式二 使用二个通配符
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manage" namespace="/" extends="struts-default">
<action name="*_*" class="com.java1234.action.{1}Action" method="{2}">
<result name="success">success.jsp</result>
</action>
</package>
</struts>
->success.jsp
OK!${name}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>通配符</h1>
<a href="Student_list" target="_blank">学生信息查询</a>
<a href="Student_add" target="_blank">学生信息添加</a>
<a href="Student_update" target="_blank">学生信息修改</a>
<a href="Student_delete" target="_blank">学生信息删除</a>
<br/><br/>
<a href="Grade_list" target="_blank">班级信息查询</a>
<a href="Grade_add" target="_blank">班级信息添加</a>
<a href="Grade_update" target="_blank">班级信息修改</a>
<a href="Grade_delete" target="_blank">班级信息删除</a> <br/>
</body>
</html>
结果还是一样的
方式三 使用动态调用,如下
六.动态方法调用
开启动态方法调用:
<constant name="struts.enable.DynamicMethodInvovation" value="true">
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
**<constant name="struts.enable.DynamicMethodInvocation" value="true" />**
<package name="manage" namespace="/" extends="struts-default">
<action name="student" class="com.java1234.action.StudentAction">
<result name="success">success.jsp</result>
</action>
<action name="grade" class="com.java1234.action.GradeAction">
<result name="success">success.jsp</result>
</action>
</package>
</struts>
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>动态方法调用</h1>
<a href="student!list" target="_blank">学生信息查询</a>
<a href="student!add" target="_blank">学生信息添加</a>
<a href="student!update" target="_blank">学生信息修改</a>
<a href="student!delete" target="_blank">学生信息删除</a>
<br/><br/>
<a href="grade!list" target="_blank">班级信息查询</a>
<a href="grade!add" target="_blank">班级信息添加</a>
<a href="grade!update" target="_blank">班级信息修改</a>
<a href="grade!delete" target="_blank">班级信息删除</a> <br/>
</body>
</html>
->success.jsp
OK!${name}
执行结果和上面是一样的。
最好不要使用这种方式,而是使用通配符。
七.Action生命周期
新建项目HeadFirstStruts2Chap02_06
->新建HelloAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
public HelloAction() {
System.out.println(this);
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return SUCCESS;
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manage" namespace="/" extends="struts-default">
<action name="hello" class="com.java1234.action.HelloAction">
<result name="success">success.jsp</result>
</action>
</package>
</struts>
->启动程序 :http://localhost:8080/HeadFirstStruts2Chap02_06/hello
执行结果:每次启动程序都会创建一个新的hellowaorldaction的实例。
后面学到spring时,是单例。
八.result配置
1,type 默认是 dispatcher 内部转发;
2,type 为 redirect 重定向;
3,type 为 chain 链条;
4,type 为 redirectAction 重定向到 action;
上面 4 个常用,一定要掌握;
其他 freemarkerfreemarker 模版 httpheader 返回一个已配置好的 HTTP 头信息响应 stream 将原始数据作为流传递回浏览器端, velocity 呈现 Velocity 模板 xslt 该 XML 可以通过 XSL 模板进行转换 plaintext 返回普通文本类容
result 全局配置
新建项目HeadFirstStruts2Chap02_07
第一种:(type 默认是 dispatcher 内部转发)
->新建HelloAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="manage" namespace="/" extends="struts-default">
<action name="hello" class="com.java1234.action.HelloAction">
<result name="success" >success.jsp</result>
</action>
</package>
</struts>
->success.jsp
Name:${name}
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hello?name=Struts2" target="_blank">默认转发_dispatcher</a><br/>
</body>
</html>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_07
执行结果:点击"默认转发_dispatcher",跳转到success.jsp页面,显示出Name:Struts2。
如果是转发的话,能取到name的值,重定向的话是取不到的。
第二种:type 是 dispatcher
->新建HelloAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="manage" namespace="/" extends="struts-default">
<action name="hello" class="com.java1234.action.HelloAction">
<result name="success" type="dispatcher" >success.jsp</result>
</action>
</package>
</struts>
->success.jsp
Name:${name}
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hello?name=Struts2" target="_blank">默认转发_dispatcher</a><br/>
</body>
</html>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_07
执行结果:点击"默认转发_dispatcher",跳转到success.jsp,取到了name值。
第三种:type 为 redirect 重定向
->新建HelloAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
public String r()throws Exception{
return "r";
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="manage" namespace="/" extends="struts-default">
<action name="hello" class="com.java1234.action.HelloAction">
<result name="success" >success.jsp</result>
<result name="r" type="redirect">success.jsp</result>
</action>
</package>
</struts>
->success.jsp
Name:${name}
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hello?name=Struts2" target="_blank">默认转发_dispatcher</a><br/>
<a href="hello!r?name=Struts2" target="_blank">重定向_redirect</a><br/>
</body>
</html>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_07
执行结果:点击"重定向_redirect",跳转到success.jsp页面,显示Name:。获取不到name值。
hello!r?name=Struts2,这表明是动态调用,要开启动态方法调用。
第四种:type 为 chain 链条
在Action中 请求了一个东西,返回到了另一个请求继续执行。且数据可以共享。
->新建HelloAction2.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction2 extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name2;
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
@Override
public String execute() throws Exception {
this.name2="你好啊";
return SUCCESS;
}
}
->新建HelloAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
public String r()throws Exception{
return "r";
}
public String c()throws Exception{
return "c";
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="manage" namespace="/" extends="struts-default">
<action name="hello" class="com.java1234.action.HelloAction">
<result name="success" >success.jsp</result>
<result name="r" type="redirect">success.jsp</result>
<result name="c" type="chain">hello2</result>
</action>
<action name="hello2" class="com.java1234.action.HelloAction2">
<result name="success" >success.jsp</result>
</action>
</package>
</struts>
->success.jsp
Name:
n
a
m
e
N
a
m
e
2
:
{name} Name2:
nameName2:{name2}
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hello?name=Struts2" target="_blank">默认转发_dispatcher</a><br/>
<a href="hello!r?name=Struts2" target="_blank">重定向_redirect</a><br/>
<a href="hello!c?name=Struts2" target="_blank">链条_chain</a><br/>
</body>
</html>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_07
执行结果:点击"链条_chain",跳转到success.jsp页面,显示Name:Struts2 Name2:你好啊。
hello!c?name=Struts2,这表明是动态调用,要开启动态方法调用。
转发到了一个新的action。
第五种:type 为 redirectAction 重定向到 action
这种与链式的区别在于,重定向到下一个Action,值是带不过去的。但是它能节省一下资源。
->新建HelloAction2.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction2 extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name2;
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
@Override
public String execute() throws Exception {
this.name2="你好啊";
return SUCCESS;
}
}
->新建HelloAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
public String r()throws Exception{
return "r";
}
public String c()throws Exception{
return "c";
}
public String ra()throws Exception{
return "ra";
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="manage" namespace="/" extends="struts-default">
<action name="hello" class="com.java1234.action.HelloAction">
<result name="success" >success.jsp</result>
<result name="r" type="redirect">success.jsp</result>
<result name="c" type="chain">hello2</result>
<result name="ra" type="redirectAction">hello2</result>
</action>
<action name="hello2" class="com.java1234.action.HelloAction2">
<result name="success" >success.jsp</result>
</action>
</package>
</struts>
->success.jsp
Name:
n
a
m
e
N
a
m
e
2
:
{name} Name2:
nameName2:{name2}
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hello?name=Struts2" target="_blank">默认转发_dispatcher</a><br/>
<a href="hello!r?name=Struts2" target="_blank">重定向_redirect</a><br/>
<a href="hello!c?name=Struts2" target="_blank">链条_chain</a><br/>
<a href="hello!ra?name=Struts2" target="_blank">重定向到Action_redirectAction</a><br/>
</body>
</html>
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_07
执行结果:点击"重定向到Action_redirectAction",跳转到success.jsp页面,显示Name: Name2:你好啊。
name取不到。
hello!ra?name=Struts2,这表明是动态调用,要开启动态方法调用。
转发到了一个新的action。
二.result全局配置
有一种result,全局action都要用到,比如说一种错误页面
->新建HelloAction2.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction2 extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name2;
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
@Override
public String execute() throws Exception {
this.name2="你好啊";
return SUCCESS;
}
}
->新建HelloAction.java
package com.java1234.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String name;
private String error;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
@Override
public String execute() throws Exception {
if(name==null || "".equals(name)){
this.error="name是空";
return ERROR;
}
return SUCCESS;
}
public String r()throws Exception{
return "r";
}
public String c()throws Exception{
return "c";
}
public String ra()throws Exception{
return "ra";
}
}
->struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="manage" namespace="/" extends="struts-default">
<global-results>
<result name="error">error.jsp</result>
</global-results>
<action name="hello" class="com.java1234.action.HelloAction">
<result name="success" >success.jsp</result>
<result name="r" type="redirect">success.jsp</result>
<result name="c" type="chain">hello2</result>
<result name="ra" type="redirectAction">hello2</result>
</action>
<action name="hello2" class="com.java1234.action.HelloAction2">
<result name="success" >success.jsp</result>
</action>
</package>
</struts>
->success.jsp
Name:
n
a
m
e
N
a
m
e
2
:
{name} Name2:
nameName2:{name2}
->index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hello?name=Struts2" target="_blank">默认转发_dispatcher</a><br/>
<a href="hello!r?name=Struts2" target="_blank">重定向_redirect</a><br/>
<a href="hello!c?name=Struts2" target="_blank">链条_chain</a><br/>
<a href="hello!ra?name=Struts2" target="_blank">重定向到Action_redirectAction</a><br/>
<a href="hello" target="_blank">全局result配置</a><br/>
</body>
</html>
->error.jsp
错误信息:${error }
->启动程序:http://localhost:8080/HeadFirstStruts2Chap02_07
执行结果:点击"全局result配置",跳转到success.jsp页面,显示错误信息:name是空。
执行过程 :在hello这个Action里面,先在此action中找相应的result,如果没有找到那个errorresult,就去全局变量中寻找。