struts2是什么

概念

struts2使用优势

自动封装参数

参数校验

结果的处理(转发|重定向)

国际化

显示等待页面

表单的防止重复提交

struts2具有更加先进的架构以及思想

struts2的历史

struts2与struts1区别就是技术上没有什么关系.

struts2的前身时webwork框架.


搭建struts2框架

1.导包

org.apache.struts

struts2-core

2.5.13

2.书写Action类

package com.stevezong.struts2;


public class HelloAction {


public String hello() {

System.out.println("hi stevezong");

return "success" ;

}

}


3.书写src/struts.xml

"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

"http://struts.apache.org/dtds/struts-2.5.dtd">

/hello.jsp

4.将struts2核心过滤器配置到web.xml

struts2

org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter

struts2

/*

5.写 jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

Insert title here

Hello,Stevezong

6.测试

http://127.0.0.1:8080/struts2/hello/HelloAction


struts2访问流程&struts2架构


http://127.0.0.1:8080/struts2/hello/HelloAction

hello/HelloAction->

过滤器 ->

核心配置文件-> 

hello-> 

package namespace="hello" ->

HelloAction -> 

action name="HelloAction" ->

class="com.stevezong.struts2.HelloAction"->

反射 创建 action 对象->

调用method="hello" hello这个方法->

return "success"->

找 result name="success"的结果->



配置详解

struts.xml配置

<--

name 属性 标识结果处理的名称 与action方法的返回值对应

type 属性  指定调用那个哪一个result类来处理结果  默认使用转发

标签提 填写页面的相对路径

-->

/hello.jsp

struts2常量配置

struts2默认常量配置位置

/org/apache/struts2/default.properties

修改struts2常量配置(方式先后也是加载顺序)

方式1:src/struts.xml ***一般都是在这里配置

...

...

...

方式2:在src下创建struts.properties

...

struts.i18n.encoding=UTF-8

...

方式3:在项目的web.xml中

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"

version="2.5">

struts2

struts2

org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter

struts2

/*

struts.i18n.encoding

UTF-8

顺序

常量配置

struts.i18n.encoding=UTF-8

struts.action.extension=action,,

struts.devMode = false

struts2配置的进阶

动态方法调用

方式1

"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

"http://struts.apache.org/dtds/struts-2.5.dtd">

regex:.*

/hello.jsp

package com.stevezong.struts2;

public class UserAction {

public String add() {

System.out.println("addUser");

return "success";

}

public String deleteDemo() {

System.out.println("deleteUser");

return "success";

}

public String updateDemo() {

System.out.println("updateUser");

return "success";

}

public String findDemo() {

System.out.println("findUser");

return "success";

}

}

http://127.0.0.1:8080/struts2/user/UserAction

http://127.0.0.1:8080/struts2/user/UserAction!

http://127.0.0.1:8080/struts2/user/UserAction!updateDemo

http://127.0.0.1:8080/struts2/user/UserAction!add

!方法名

方式2

regex:.*

/hello.jsp

http://127.0.0.1:8080/struts2/user/UserAction

http://127.0.0.1:8080/struts2/user/UserAction_

http://127.0.0.1:8080/struts2/user/UserAction_updateDemo

http://127.0.0.1:8080/struts2/user/UserAction_add

struts2中的默认配置

action method 的默认是 execute  

没有写 就去找这个方法

action class 的默认是com.opensymphony.xwork2.ActionSupport

没有写 就用这个class

result name 的默认是 success

没有写 就去找这个

result type 的默认是 dispatcher

没有写,就是用转发

default-action-ref name="defaultAction"

如果找不到包下的action, 会使用一个defaultAction 作为默认action



action类详解

Action类的书写方式

方式1 少用

创建一个类 可以是POJO 不用继承任何父类 也不需要实现任何接口

public class Demo{

public String add(){

}

}

方式2

实现一个接口 Action 接口预制了一写字符串

package com.stevezong.struts2;


import com.opensymphony.xwork2.Action;


public class DemoAction  implements Action{


//没什么作用,放着就可以就是提供一个规范

public String execute() throws Exception {

return null;

}


}


方式3 常用

继承一个类 ActionSupport

package com.stevezong.struts2;


import com.opensymphony.xwork2.ActionSupport;


public class DemoAction  extends ActionSupport{


/**

*/

private static final long serialVersionUID = 1L;



}

结果跳转方式

转发

"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

"http://struts.apache.org/dtds/struts-2.5.dtd">

regex:.*

/hello.jsp

重定向

"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

"http://struts.apache.org/dtds/struts-2.5.dtd">

regex:.*

/hello.jsp

转发到Action

"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

"http://struts.apache.org/dtds/struts-2.5.dtd">

regex:.*

/hello.jsp

/hello.jsp

Demo3Action

/da

重定向到Action

"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

"http://struts.apache.org/dtds/struts-2.5.dtd">

regex:.*

/hello.jsp

/hello.jsp

Demo3Action

/da

Demo4Action

/da

访问servletAPI方式

原理

通过ActionContext *****

Java:

package com.stevezong.struts2;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class Demo6Action  extends ActionSupport{

@Override

public String execute() throws Exception {

//session 域

Map session = ActionContext.getContext().getSession();

session.put("name", "session");

Map application = ActionContext.getContext().getApplication();

application.put("name", "application");

//=====================================================================================

//不推荐使用原生的request域

String key = "request";

Map requestScoper = (Map) ActionContext.getContext().get(key);

// 推荐

ActionContext.getContext().put("name", "request");

//=====================================================================================

System.out.println("execute5");

return super.execute();

}

}

JSP:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

Insert title here

request:${ requestScope.name }

session:${sessionScope.name }

application: ${applicationScope.name }


XML:

/api.jsp

通过ServletActionContext

package com.stevezong.struts2;

import javax.servlet.ServletContext;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class Demo7Action extends ActionSupport {


@Override

public String execute() throws Exception {

// 不推荐

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

ServletContext servletContext = ServletActionContext.getServletContext();

HttpSession session = request.getSession();

System.out.println("execute7");

return super.execute();

}

}


通过实现接口方式

package com.stevezong.struts2;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import org.apache.struts2.interceptor.ServletRequestAware;

import org.apache.struts2.interceptor.ServletResponseAware;


import com.opensymphony.xwork2.ActionSupport;


public class Demo8Action extends ActionSupport implements ServletRequestAware, ServletResponseAware {

// 实现不同的XXXXAware接口 重写 setxxx方法

private HttpServletRequest request;

private HttpServletResponse response;


@Override

public String execute() throws Exception {

System.out.println("execute8");

return super.execute();

}


public void setServletRequest(HttpServletRequest request) {

this.request = request;

}


public void setServletResponse(HttpServletResponse response) {

this.response = response;

}


}


如何获得参数

1、第一种

1、jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

Insert title here

2、java

package com.stevezong.struts2;


import com.opensymphony.xwork2.ActionSupport;


public class Demo9Action extends ActionSupport {

private String name;


@Override

public String execute() throws Exception {

// 如何获得参数

System.out.println("name参数的值" + name);


System.out.println("execute9");

return "success";

}


public String getName() {

return name;

}


public void setName(String name) {

this.name = name;

}


}

3、xml

/api.jsp

/form.jsp







扩展

strutsMVC

Action生命周期

1.每次请求到来时,都会创建一个新的Action实例

2.Action是线程安全的.可以使用成员变量接收参数

属性驱动获得参数

1、给action 添加一个属性

1、java

package com.stevezong.struts2;


import java.util.Date;


import com.opensymphony.xwork2.ActionSupport;


public class Demo9Action extends ActionSupport {

private String name;

//自动类型装换,8大基本类型和包装类

private Integer age;

//支持特定的类型字符串转换为Date yyyy-MM-dd

private Date br;

@Override

public String execute() throws Exception {

// 如何获得参数

System.out.println("name参数的值" + name);

System.out.println("age参数"+age);

System.out.println("br的参数"+br);

return "success";

}


public String getName() {

return name;

}


public void setName(String name) {

this.name = name;

}


public Integer getAge() {

return age;

}


public void setAge(Integer age) {

this.age = age;

}


public Date getBr() {

return br;

}


public void setBr(Date br) {

this.br = br;

}


}

2、jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

Insert title here


对象驱动(jsp中注意)

1创建一个User 类

2、Action中 private User user;

3、修改jsp中 name 的值为 user.xxx

1、java

package com.stevezong.struts2;


import com.opensymphony.xwork2.ActionSupport;

import com.stevezong.struts2.domain.User;


public class Demo9Action extends ActionSupport {

private User user;


@Override

public String execute() throws Exception {

// 如何获得参数

System.out.println(user);

return "success";

}


public User getUser() {

return user;

}


public void setUser(User user) {

this.user = user;

}

}

2、java

package com.stevezong.struts2.domain;


import java.util.Date;


public class User {

private String name;

private Integer age;

private Date br;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public Date getBr() {

return br;

}

public void setBr(Date br) {

this.br = br;

}

@Override

public String toString() {

return "User [name=" + name + ", age=" + age + ", br=" + br + "]";

}

}


3、jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

Insert title here

模型驱动

1实现一个ModelDriven 接口 有一个泛型就是你要接受的类

2、private User user = new User();

3、实现 接口的方法 格式固定

public User getModel() {

return user;

}

1、

package com.stevezong.struts2;

import com.opensymphony.xwork2.ActionSupport;

import com.opensymphony.xwork2.ModelDriven;

import com.stevezong.struts2.domain.User;

public class Demo9Action extends ActionSupport implements ModelDriven {

private User user = new User();

@Override

public String execute() throws Exception {

// 如何获得参数

System.out.println(user);

return "success";

}

public User getModel() {

return user;

}

}


2、

package com.stevezong.struts2.domain;

import java.util.Date;

public class User {

private String name;

private Integer age;

private Date br;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public Date getBr() {

return br;

}

public void setBr(Date br) {

this.br = br;

}

@Override

public String toString() {

return "User [name=" + name + ", age=" + age + ", br=" + br + "]";

}

}

3、jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

Insert title here

集合类型参数封装

list

1、java

package com.stevezong.struts2;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class Demo9Action extends ActionSupport {

private List list;

@Override

public String execute() throws Exception {

// 如何获得参数

System.out.println(list);

return "success";

}

public List getList() {

return list;

}

public void setList(List list) {

this.list = list;

}

}

2、jsp list 可以指定下标

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

Insert title here

map

1、java

package com.stevezong.struts2;

import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

public class Demo9Action extends ActionSupport {

private Map map;

@Override

public String execute() throws Exception {

// 如何获得参数

System.out.println(map);

return "success";

}

public Map getMap() {

return map;

}

public void setMap(Map map) {

this.map = map;

}

}

2、jsp 结果:{br=3, name=1, age=2}

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

Insert title here

OGNL表达式

OGNL:对象视图导航语言.  ${user.addr.name} 这种写法就叫对象视图导航.

OGNL不仅仅可以视图导航.支持比EL表达式更加丰富的功能.

使用OGNL准备工作

导包

struts2 的包中已经包含了.所以不需要导入额外的jar包

代码准备

OGNL 表达式

OGNLContext Ognl上下文对象

ROOT Context

放任何对象那个未做root 都可以

Map

语法

基本取值

赋值

调用方法

调用静态方法

创建对象(List,Map)

package com.stevezong.struts2;

import java.util.HashMap;

import java.util.Map;

import org.junit.Test;

import com.stevezong.struts2.domain.User2;

import ognl.Ognl;

import ognl.OgnlContext;

import ognl.OgnlException;

public class Demo1 {

@Test

public void fun1() throws Exception {

// 准备 ROOT

User2 user = new User2("stevezong", 18);

// 准备Context

Map context = new HashMap();

context.put("user1", new User2("steve", 17));

context.put("user2", new User2("zong", 18));

// 准备OGNLContext

OgnlContext oc = new OgnlContext();

oc.setRoot(user);

oc.setValues(context);

// 书写OGNL

//取出root中的user对象的name属性和age属性

String name = (String) Ognl.getValue("name", oc,oc.getRoot());

Integer age = (Integer) Ognl.getValue("age", oc,oc.getRoot());

System.out.println(name+":"+age);

// 书写OGNL

//取出Context中的  #从context中取 user1 获取那个 .name 获取那个属性

String name1 = (String) Ognl.getValue("#user1.name", oc,oc.getRoot());

Integer age1 = (Integer) Ognl.getValue("#user1.age", oc,oc.getRoot());

System.out.println(name1+":"+age1);

// 书写OGNL

//root 赋值

Ognl.getValue("name='zongsteve'", oc,oc.getRoot());

String name2 = (String) Ognl.getValue("name", oc,oc.getRoot());

System.out.println("name2:"+name2);

// 书写OGNL

//Context 赋值

Ognl.getValue("#user1.name='zong'", oc,oc.getRoot());

String name3 = (String) Ognl.getValue("#user1.name", oc,oc.getRoot());

System.out.println("name3:"+name3);

// 书写OGNL

//调用Root的get set方法

Ognl.getValue("setName('steve')", oc,oc.getRoot());

String name4 = (String) Ognl.getValue("getName()", oc,oc.getRoot());

System.out.println("name4:"+name4);

// 书写OGNL

//调用Context的get set方法

Ognl.getValue("#user1.setName('steve')", oc,oc.getRoot());

String name5 = (String) Ognl.getValue("#user1.getName()", oc,oc.getRoot());

System.out.println("name5:"+name5);

// 书写OGNL

//调用静态方法@加类的全限定名@方法名(参数)

String str = (String) Ognl.getValue("@com.stevezong.struts2.TestUtil@echo('hi stevezong')", oc,oc.getRoot());

System.out.println("str:"+str);

// 书写OGNL

//创建list对象

Integer  size = (Integer) Ognl.getValue("{'stevezong','steve','zong'}.size()", oc,oc.getRoot());

//获取list中的对象

String name6 = (String) Ognl.getValue("{'stevezong','steve','zong'}[0]", oc,oc.getRoot());

//获取list中的对象

String name7 = (String) Ognl.getValue("{'stevezong','steve','zong'}.get(1)", oc,oc.getRoot());

System.out.println("size:"+size);

System.out.println("name6:"+name6);

System.out.println("name7:"+name7);

// 书写OGNL

//创建map对象

Integer  size2 = (Integer) Ognl.getValue("#{'name':'stevezong','age':'18'}.size()", oc,oc.getRoot());

String name8 = (String)Ognl.getValue("#{'name':'stevezong','age':'18'}['name']", oc,oc.getRoot());

Integer age2 = (Integer)Ognl.getValue("#{'name':'stevezong','age':18}.get('age')", oc,oc.getRoot());

System.out.println("size2:"+size2);

System.out.println("name8:"+name8);

System.out.println("age2:"+age2);

}

}

package com.stevezong.struts2.domain;

public class User2 {

private String name;

private Integer age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

@Override

public String toString() {

return "User2 [name=" + name + ", age=" + age + "]";

}

public User2() {

super();

}

public User2(String name, Integer age) {

super();

this.name = name;

this.age = age;

}

}

OGNL与Struts2的结合

结合原理

Ognl 表达式要想运行 要有 OGNLContext Struts2 就提供了一个OGNLContext 不过名字换成了 ValueStack

ValueStack中的两部分

Root   放了一个栈

Context 放的是ActionContext(数据中心)

栈原理

栈是由ArrayList模拟的

栈中的两个方法的实现

访问栈中属性的特点.由上到下

查看值栈中两部分内容(使用DEBUG标签)

Root

默认情况下,栈中放置当前访问的Action对象

Context

Context部分就是ActionContext数据中心

struts2与ognl结合体现

参数接收

如何获得值栈对象,值栈对象与ActionContext对象是互相引用的

配置文件中

语法:${ognl表达式}

${name}

就会从 当前的Action对象的中查找 name这个属性

struts2标签

扩展:request对象的getAttribute方法

查找顺序

自定义拦截器

架构

拦截器创建

创建方式1 实现一个 接口 Interceptor

package com.stevezong.struts2;


import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.Interceptor;


public class MyInterceptor implements Interceptor{

//拦截器的生命周期  随项目的启动而创建 随项目的关闭而销毁

//销毁方法

public void destroy() {

}

//初始化方法

public void init() {

}

//拦截方法

public String intercept(ActionInvocation invocation) throws Exception {

return null;

}


}


创建方式2 继承一个 类AbstractInterceptor 帮助我们写好了 init方法 和 destroy方法

package com.stevezong.struts2;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;


public class MyInterceptor2  extends AbstractInterceptor{


@Override

public String intercept(ActionInvocation invocation) throws Exception {

return null;

}

}


创建方式3

package com.stevezong.struts2;


import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;


public class MyInterceptor3  extends MethodFilterInterceptor{

//功能 定制拦截器拦截的方法

//定制哪些方法需要拦截

//定制哪些方法不需要拦截

@Override

protected String doIntercept(ActionInvocation invocation) throws Exception {

return null;

}

}


拦截器api

放行

前后处理

不放行,直接跳转到一个结果页面

不执行后续的拦截器以及Action,直接交给Result处理结果.进行页面跳转

拦截器配置

步骤1:注册拦截器

步骤2:配置拦截器栈

步骤3:指定包中默认拦截器栈

如何定制拦截方法

全局结果集


"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

"http://struts.apache.org/dtds/struts-2.5.dtd">

add,del

regex:.*

/vs.jsp


package com.stevezong.struts2;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

public class MyInterceptor3  extends MethodFilterInterceptor{

//功能 定制拦截器拦截的方法

//定制哪些方法需要拦截

//定制哪些方法不需要拦截

@Override

protected String doIntercept(ActionInvocation invocation) throws Exception {

//前处理

System.out.println("1");

//放行

invocation.invoke();

System.out.println("2");

//后处理

return "success";

}

}



package com.stevezong.struts2;


import com.opensymphony.xwork2.ActionSupport;


public class Demo3  extends ActionSupport{

@Override

public String execute() throws Exception {

System.out.println("execute");

return "success";

}

public String add() throws Exception {

System.out.println("Demo3add");

return "success";

}

public String del() throws Exception {

System.out.println("Demo3del");

return "success";

}

public String update() throws Exception {

System.out.println("Demo3update");

return "success";

}

public String find() throws Exception {

System.out.println("Demo3find");

return "success";

}

}





















struts2标签(了解)

标签体系'

struts2标签结构

控制标签

数据标签

表单标签

非表单标签

在action中添加错误信息

取出错误信息

异常 配置

regex:.*

/index.htm

/jsp/error.jsp